You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by to...@apache.org on 2017/04/28 07:16:15 UTC
svn commit: r1792993 [3/9] - in /jackrabbit/oak/branches/1.0/oak-upgrade: ./
src/main/java/org/apache/jackrabbit/core/
src/main/java/org/apache/jackrabbit/oak/plugins/
src/main/java/org/apache/jackrabbit/oak/plugins/document/
src/main/java/org/apache/j...
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,57 @@
+/*
+ * 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.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.Closer;
+
+public class CliUtils {
+
+ private static final Logger log = LoggerFactory.getLogger(OakUpgrade.class);
+
+ 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 void handleSigInt(final Closer closer) {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ try {
+ closer.close();
+ } catch (IOException e) {
+ log.error("Can't close", e);
+ }
+ }
+ });
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,123 @@
+/*
+ * 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.CliArgumentException;
+import org.apache.jackrabbit.oak.upgrade.cli.parser.DatastoreArguments;
+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 DatastoreArguments datastores;
+
+ protected final Closer closer;
+
+ public MigrationFactory(MigrationOptions options, StoreArguments stores, DatastoreArguments datastores, Closer closer) {
+ this.options = options;
+ this.stores = stores;
+ this.datastores = datastores;
+ this.closer = closer;
+ }
+
+ public RepositoryUpgrade createUpgrade() throws IOException, RepositoryException, CliArgumentException {
+ 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, CliArgumentException {
+ BlobStore srcBlobStore = datastores.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 = datastores.getDstBlobStore(srcBlobStore).create(closer);
+ NodeStore dstStore = stores.getDstStore().create(dstBlobStore, closer);
+ return dstStore;
+ }
+
+ protected RepositoryUpgrade createUpgrade(RepositoryContext source, NodeStore dstStore) {
+ RepositoryUpgrade upgrade = new RepositoryUpgrade(source, dstStore);
+ upgrade.setCopyBinariesByReference(datastores.getBlobMigrationCase() == DatastoreArguments.BlobMigrationCase.COPY_REFERENCES);
+ upgrade.setCopyVersions(options.getCopyVersions());
+ upgrade.setCopyOrphanedVersions(options.getCopyOrphanedVersions());
+ if (options.getIncludePaths() != null) {
+ upgrade.setIncludes(options.getIncludePaths());
+ }
+ if (options.getExcludePaths() != null) {
+ upgrade.setExcludes(options.getExcludePaths());
+ }
+ if (options.getMergePaths() != null) {
+ upgrade.setMerges(options.getMergePaths());
+ }
+ upgrade.setFilterLongNames(!stores.getDstType().isSupportLongNames());
+ upgrade.setCheckLongNames(!options.isSkipNameCheck() && !stores.getDstType().isSupportLongNames());
+ upgrade.setSkipOnError(!options.isFailOnError());
+ upgrade.setEarlyShutdown(options.isEarlyShutdown());
+ upgrade.setSkipInitialization(options.isSkipInitialization());
+ 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());
+ }
+ sidegrade.setFilterLongNames(stores.getSrcType().isSupportLongNames() && !stores.getDstType().isSupportLongNames());
+ sidegrade.setVerify(options.isVerify());
+ sidegrade.setOnlyVerify(options.isOnlyVerify());
+ sidegrade.setSkipCheckpoints(options.isSkipCheckpoints());
+ return sidegrade;
+ }
+
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,101 @@
+/*
+ * 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 joptsimple.OptionSet;
+import org.apache.jackrabbit.oak.spi.lifecycle.CompositeInitializer;
+import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
+import org.apache.jackrabbit.oak.upgrade.cli.parser.CliArgumentException;
+import org.apache.jackrabbit.oak.upgrade.cli.parser.DatastoreArguments;
+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 {
+ OptionSet options = OptionParserFactory.create().parse(args);
+ try {
+ MigrationCliArguments cliArguments = new MigrationCliArguments(options);
+ if (cliArguments.hasOption(OptionParserFactory.HELP) || cliArguments.getArguments().isEmpty()) {
+ CliUtils.displayUsage();
+ return;
+ }
+ migrate(cliArguments);
+ } catch(CliArgumentException e) {
+ if (e.getMessage() != null) {
+ System.err.println(e.getMessage());
+ }
+ System.exit(e.getExitCode());
+ }
+ }
+
+ public static void migrate(MigrationCliArguments argumentParser) throws IOException, CliArgumentException {
+ MigrationOptions options = new MigrationOptions(argumentParser);
+ options.logOptions();
+
+ StoreArguments stores = new StoreArguments(options, argumentParser.getArguments());
+ stores.logOptions();
+
+ boolean srcEmbedded = stores.srcUsesEmbeddedDatastore();
+ DatastoreArguments datastores = new DatastoreArguments(options, stores, srcEmbedded);
+
+ migrate(options, stores, datastores);
+ }
+
+ public static void migrate(MigrationOptions options, StoreArguments stores, DatastoreArguments datastores) throws IOException, CliArgumentException {
+ Closer closer = Closer.create();
+ CliUtils.handleSigInt(closer);
+ MigrationFactory factory = new MigrationFactory(options, stores, datastores, closer);
+ try {
+ if (stores.getSrcStore().isJcr2()) {
+ upgrade(factory);
+ } else {
+ sidegrade(factory);
+ }
+ } catch (Throwable t) {
+ throw closer.rethrow(t);
+ } finally {
+ closer.close();
+ }
+ }
+
+ private static void upgrade(MigrationFactory migrationFactory) throws IOException, RepositoryException, CliArgumentException {
+ migrationFactory.createUpgrade().copy(createCompositeInitializer());
+ }
+
+ private static void sidegrade(MigrationFactory migrationFactory) throws IOException, RepositoryException, CliArgumentException {
+ 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/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/BlobStoreFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/BlobStoreFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/BlobStoreFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/BlobStoreFactory.java Fri Apr 28 07:16:13 2017
@@ -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/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ConstantBlobStoreFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ConstantBlobStoreFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ConstantBlobStoreFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ConstantBlobStoreFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,36 @@
+/*
+ * 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 com.google.common.io.Closer;
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+
+import java.io.IOException;
+
+public class ConstantBlobStoreFactory implements BlobStoreFactory {
+
+ private final BlobStore blobStore;
+
+ public ConstantBlobStoreFactory(BlobStore blobStore) {
+ this.blobStore = blobStore;
+ }
+
+ @Override
+ public BlobStore create(Closer closer) throws IOException {
+ return blobStore;
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/DummyBlobStoreFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/DummyBlobStoreFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/DummyBlobStoreFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/DummyBlobStoreFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,34 @@
+/*
+ * 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;
+ }
+
+ @Override
+ public String toString() {
+ return "DummyBlobStore";
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileBlobStoreFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileBlobStoreFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileBlobStoreFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileBlobStoreFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,41 @@
+/*
+ * 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);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("FileBlobStore[%s]", directory);
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileDataStoreFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileDataStoreFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileDataStoreFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileDataStoreFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+ private final boolean ignoreMissingBlobs;
+
+ public FileDataStoreFactory(String directory, boolean ignoreMissingBlobs) {
+ this.directory = directory;
+ this.ignoreMissingBlobs = ignoreMissingBlobs;
+ }
+
+ @Override
+ public BlobStore create(Closer closer) {
+ OakFileDataStore delegate = new OakFileDataStore();
+ delegate.setPath(directory);
+ delegate.init(null);
+ closer.register(asCloseable(delegate));
+
+ if (ignoreMissingBlobs) {
+ return new SafeDataStoreBlobStore(delegate);
+ } else {
+ return new DataStoreBlobStore(delegate);
+ }
+ }
+
+ private static Closeable asCloseable(final FileDataStore store) {
+ return new Closeable() {
+ @Override
+ public void close() throws IOException {
+ store.close();
+ }
+ };
+ }
+
+ @Override
+ public String toString() {
+ return String.format("FileDataStore[%s]", directory);
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStore.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStore.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStore.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,68 @@
+/*
+ * 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 java.io.InputStream;
+
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+
+/**
+ * Utility BlobStore implementation to be used in tooling that can work with a
+ * FileStore without the need of the DataStore being present locally
+ */
+public class MissingBlobStore implements BlobStore {
+
+ @Override
+ public String writeBlob(InputStream in) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int readBlob(String blobId, long pos, byte[] buff, int off,
+ int length) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public long getBlobLength(String blobId) throws IOException {
+ // best effort length extraction
+ int indexOfSep = blobId.lastIndexOf("#");
+ if (indexOfSep != -1) {
+ return Long.valueOf(blobId.substring(indexOfSep + 1));
+ }
+ return -1;
+ }
+
+ @Override
+ public InputStream getInputStream(String blobId) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getBlobId(String reference) {
+ return reference;
+ }
+
+ @Override
+ public String getReference(String blobId) {
+ return blobId;
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStoreFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStoreFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStoreFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStoreFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,34 @@
+/*
+ * 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 MissingBlobStoreFactory implements BlobStoreFactory {
+
+ @Override
+ public BlobStore create(Closer closer) {
+ return new MissingBlobStore();
+ }
+
+ @Override
+ public String toString() {
+ return "MissingBlobStore";
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,127 @@
+/*
+ * 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.HashSet;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.aws.ext.ds.S3DataStore;
+import org.apache.jackrabbit.core.data.CachingDataStore;
+import org.apache.jackrabbit.core.data.DataStoreException;
+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;
+import com.google.common.io.Files;
+
+public class S3DataStoreFactory implements BlobStoreFactory {
+
+ private static final Logger log = LoggerFactory.getLogger(S3DataStoreFactory.class);
+
+ private static final Pattern STRIP_VALUE_PATTERN = Pattern.compile("^[TILFDXSCB]?\"(.*)\"\\W*$");
+
+ private final Properties props;
+
+ private final String directory;
+
+ private final File tempHomeDir;
+
+ private final boolean ignoreMissingBlobs;
+
+ public S3DataStoreFactory(String configuration, String directory, boolean ignoreMissingBlobs) throws IOException {
+ this.props = new Properties();
+ FileReader reader = new FileReader(new File(configuration));
+ try {
+ props.load(reader);
+ } finally {
+ IOUtils.closeQuietly(reader);
+ }
+
+ for (Object key : new HashSet<Object>(props.keySet())) {
+ String value = props.getProperty((String) key);
+ props.put(key, stripValue(value));
+ }
+
+ this.directory = directory;
+ this.tempHomeDir = Files.createTempDir();
+ this.ignoreMissingBlobs = ignoreMissingBlobs;
+ }
+
+ @Override
+ public BlobStore create(Closer closer) throws IOException {
+ S3DataStore delegate = new S3DataStore();
+ delegate.setProperties(props);
+ delegate.setPath(directory);
+ try {
+ delegate.init(tempHomeDir.getPath());
+ } catch (RepositoryException e) {
+ throw new IOException(e);
+ }
+ closer.register(asCloseable(delegate, tempHomeDir));
+ if (ignoreMissingBlobs) {
+ return new SafeDataStoreBlobStore(delegate);
+ } else {
+ return new DataStoreBlobStore(delegate);
+ }
+ }
+
+ private static Closeable asCloseable(final CachingDataStore store, final File tempHomeDir) {
+ 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();
+ FileUtils.deleteDirectory(tempHomeDir);
+ } catch (DataStoreException e) {
+ throw new IOException(e);
+ } catch (InterruptedException e) {
+ throw new IOException(e);
+ }
+ }
+ };
+ }
+
+ static String stripValue(String value) {
+ Matcher matcher = STRIP_VALUE_PATTERN.matcher(value);
+ if (matcher.matches()) {
+ return matcher.group(1);
+ } else {
+ return value;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("S3DataStore[%s]", directory);
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/SafeDataStoreBlobStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/SafeDataStoreBlobStore.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/SafeDataStoreBlobStore.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/SafeDataStoreBlobStore.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,101 @@
+/*
+ * 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.core.data.DataIdentifier;
+import org.apache.jackrabbit.core.data.DataRecord;
+import org.apache.jackrabbit.core.data.DataStore;
+import org.apache.jackrabbit.core.data.DataStoreException;
+import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreBlobStore;
+import org.apache.jackrabbit.oak.plugins.blob.datastore.InMemoryDataRecord;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * This implementation of the DataStoreBlobStore won't throw an exception if
+ * it can't find blob with given id. The WARN message will be emitted instead
+ * and the empty InputStream will be returned.
+ */
+public class SafeDataStoreBlobStore extends DataStoreBlobStore {
+
+ private static final Logger log = LoggerFactory.getLogger(SafeDataStoreBlobStore.class);
+
+ public SafeDataStoreBlobStore(DataStore delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public String getReference(@Nonnull String encodedBlobId) {
+ checkNotNull(encodedBlobId);
+ String blobId = extractBlobId(encodedBlobId);
+ //Reference are not created for in memory record
+ if (InMemoryDataRecord.isInstance(blobId)) {
+ return null;
+ }
+
+ DataRecord record;
+ try {
+ record = delegate.getRecordIfStored(new DataIdentifier(blobId));
+ if (record != null) {
+ return record.getReference();
+ } else {
+ log.debug("No blob found for id [{}]", blobId);
+ }
+ } catch (DataStoreException e) {
+ log.warn("Unable to access the blobId for [{}]", blobId, e);
+ }
+ return null;
+ }
+
+
+ @Override
+ protected InputStream getStream(String blobId) throws IOException {
+ try {
+ DataRecord record = getDataRecord(blobId);
+ if (record == null) {
+ log.warn("No blob found for id [{}]", blobId);
+ return new ByteArrayInputStream(new byte[0]);
+ }
+ InputStream in = getDataRecord(blobId).getStream();
+ if (!(in instanceof BufferedInputStream)){
+ in = new BufferedInputStream(in);
+ }
+ return in;
+ } catch (DataStoreException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ protected DataRecord getDataRecord(String blobId) throws DataStoreException {
+ DataRecord id;
+ if (InMemoryDataRecord.isInstance(blobId)) {
+ id = InMemoryDataRecord.getInstance(blobId);
+ } else {
+ id = delegate.getRecordIfStored(new DataIdentifier(blobId));
+ }
+ return id;
+ }
+}
\ No newline at end of file
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/Jackrabbit2Factory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/Jackrabbit2Factory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/Jackrabbit2Factory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/Jackrabbit2Factory.java Fri Apr 28 07:16:13 2017
@@ -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/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.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.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.RDBBlobStore;
+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;
+import java.io.Closeable;
+import java.io.IOException;
+
+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;
+
+ private final boolean readOnly;
+
+ public JdbcFactory(String jdbcUri, int cacheSize, String user, String password, boolean readOnly) {
+ 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;
+ this.readOnly = readOnly;
+ }
+
+ @Override
+ public NodeStore create(BlobStore blobStore, Closer closer) {
+ DocumentMK.Builder builder = MongoFactory.getBuilder(cacheSize);
+ if (blobStore != null) {
+ builder.setBlobStore(blobStore);
+ }
+ builder.setRDBConnection(getDataSource(closer));
+ if (readOnly) {
+ log.warn("Read-only mode for the DocumentMK is not available in 1.4");
+ }
+ 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;
+ }
+
+ private DataSource getDataSource(Closer closer) {
+ DataSource ds = RDBDataSourceFactory.forJdbcUrl(jdbcUri, user, password);
+ if (ds instanceof Closeable) {
+ closer.register((Closeable)ds);
+ }
+ return ds;
+ }
+
+ @Override
+ public boolean hasExternalBlobReferences() throws IOException {
+ Closer closer = Closer.create();
+ try {
+ DataSource ds = getDataSource(closer);
+ RDBBlobStore blobStore = new RDBBlobStore(ds);
+ return !blobStore.getAllChunkIds(0).hasNext();
+ } catch(Throwable e) {
+ throw closer.rethrow(e);
+ } finally {
+ closer.close();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("DocumentNodeStore[%s]", jdbcUri);
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,126 @@
+/*
+ * 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 com.mongodb.DB;
+import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
+import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
+import org.apache.jackrabbit.oak.plugins.document.mongo.MongoBlobStore;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.UnknownHostException;
+
+public class MongoFactory implements NodeStoreFactory {
+
+ private static final Logger log = LoggerFactory.getLogger(MongoFactory.class);
+
+ private static final long MB = 1024 * 1024;
+
+ private final MongoClientURI uri;
+
+ private final int cacheSize;
+
+ private final boolean readOnly;
+
+ public MongoFactory(String repoDesc, int cacheSize, boolean readOnly) {
+ this.uri = new MongoClientURI(repoDesc);
+ this.cacheSize = cacheSize;
+ this.readOnly = readOnly;
+ }
+
+ @Override
+ public NodeStore create(BlobStore blobStore, Closer closer) throws UnknownHostException {
+ DocumentMK.Builder builder = getBuilder(cacheSize);
+ builder.setMongoDB(getDB(closer));
+ if (blobStore != null) {
+ builder.setBlobStore(blobStore);
+ }
+ if (readOnly) {
+ log.warn("Read-only mode for the DocumentMK is not available in 1.4");
+ }
+ DocumentNodeStore documentNodeStore = builder.getNodeStore();
+ closer.register(asCloseable(documentNodeStore));
+ return documentNodeStore;
+ }
+
+ private DB getDB(Closer closer) throws UnknownHostException {
+ String db;
+ if (uri.getDatabase() == null) {
+ db = "aem-author"; // assume an author instance
+ } else {
+ db = uri.getDatabase();
+ }
+ MongoClient client = new MongoClient(uri);
+ closer.register(asCloseable(client));
+ return client.getDB(db);
+ }
+
+ @Override
+ public boolean hasExternalBlobReferences() throws IOException {
+ Closer closer = Closer.create();
+ try {
+ MongoBlobStore mongoBlobStore = new MongoBlobStore(getDB(closer));
+ return !mongoBlobStore.getAllChunkIds(0).hasNext();
+ } catch(Throwable e) {
+ throw closer.rethrow(e);
+ } finally {
+ closer.close();
+ }
+ }
+
+ 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/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+ boolean hasExternalBlobReferences() throws IOException;
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,129 @@
+/*
+ * 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.blob.ReferenceCollector;
+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.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+
+import com.google.common.io.Closer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nullable;
+
+public class SegmentFactory implements NodeStoreFactory {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SegmentFactory.class);
+
+ private final File dir;
+
+ private final boolean disableMmap;
+
+ public SegmentFactory(String directory, boolean disableMmap, boolean readOnly) {
+ this.dir = new File(directory);
+ this.disableMmap = disableMmap;
+ createDirectoryIfMissing(dir);
+ if (readOnly) {
+ LOG.info("Read-only segment node store is not supported in 1.0");
+ }
+ if (!dir.isDirectory()) {
+ throw new IllegalArgumentException("Not a directory: " + dir.getPath());
+ }
+ }
+
+ private void createDirectoryIfMissing(File directory) {
+ if (!directory.exists()) {
+ directory.mkdirs();
+ }
+ }
+
+ @Override
+ public NodeStore create(BlobStore blobStore, Closer closer) throws IOException {
+ File directory = new File(dir, "segmentstore");
+ boolean mmapEnabled = !disableMmap && "64".equals(System.getProperty("sun.arch.data.model", "32"));
+
+ final FileStore fs;
+ Builder builder;
+ builder = FileStore.newFileStore(directory);
+
+ if (blobStore != null) {
+ builder.withBlobStore(blobStore);
+ }
+ builder.withMaxFileSize(256);
+ builder.withMemoryMapping(mmapEnabled);
+ fs = builder.create();
+
+ closer.register(asCloseable(fs));
+
+ return new TarNodeStore(new SegmentNodeStore(fs), new TarNodeStore.SuperRootProvider() {
+ @Override
+ public NodeState getSuperRoot() {
+ return fs.getHead();
+ }
+ });
+ }
+
+ @Override
+ public boolean hasExternalBlobReferences() throws IOException {
+ FileStore fs = FileStore.newFileStore(new File(dir, "segmentstore")).create();
+ try {
+ fs.getTracker().collectBlobReferences(new ReferenceCollector() {
+ @Override
+ public void addReference(String reference) {
+ // FIXME the collector should allow to stop processing
+ // see java.nio.file.FileVisitor
+ throw new ExternalBlobFound();
+ }
+ });
+ return false;
+ } catch (ExternalBlobFound e) {
+ return true;
+ } finally {
+ fs.close();
+ }
+ }
+
+ 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);
+ }
+
+ private static class ExternalBlobFound extends RuntimeException {
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,70 @@
+/*
+ * 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;
+ }
+
+ public boolean hasExternalBlobReferences() throws IOException {
+ if (isJcr2()) {
+ return true;
+ } else {
+ return nodeStoreFactory.hasExternalBlobReferences();
+ }
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,48 @@
+/*
+ * 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.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.spi.state.ProxyNodeStore;
+
+public class TarNodeStore extends ProxyNodeStore {
+
+ private final NodeStore ns;
+
+ private final SuperRootProvider superRootProvider;
+
+ public TarNodeStore(NodeStore ns, SuperRootProvider superRootProvider) {
+ this.ns = ns;
+ this.superRootProvider = superRootProvider;
+ }
+
+ public NodeState getSuperRoot() {
+ return superRootProvider.getSuperRoot();
+ }
+
+ @Override
+ protected NodeStore getNodeStore() {
+ return ns;
+ }
+
+ public interface SuperRootProvider {
+
+ NodeState getSuperRoot();
+
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/CliArgumentException.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/CliArgumentException.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/CliArgumentException.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/CliArgumentException.java Fri Apr 28 07:16:13 2017
@@ -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/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/DatastoreArguments.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/DatastoreArguments.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/DatastoreArguments.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/DatastoreArguments.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,238 @@
+/*
+ * 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 org.apache.commons.lang.text.StrSubstitutor;
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+import org.apache.jackrabbit.oak.upgrade.cli.blob.BlobStoreFactory;
+import org.apache.jackrabbit.oak.upgrade.cli.blob.ConstantBlobStoreFactory;
+import org.apache.jackrabbit.oak.upgrade.cli.blob.DummyBlobStoreFactory;
+import org.apache.jackrabbit.oak.upgrade.cli.blob.FileBlobStoreFactory;
+import org.apache.jackrabbit.oak.upgrade.cli.blob.FileDataStoreFactory;
+import org.apache.jackrabbit.oak.upgrade.cli.blob.MissingBlobStoreFactory;
+import org.apache.jackrabbit.oak.upgrade.cli.blob.S3DataStoreFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Map;
+
+import static com.google.common.collect.Maps.newHashMap;
+import static org.apache.jackrabbit.oak.upgrade.cli.parser.StoreType.JCR2_DIR_XML;
+
+/**
+ * This class parses the input provided by the user and analyses the given node stores
+ * in order to find out which datastore combination should be used for the migration.
+ *
+ * The desired outcome for the combinations of user input can be found in the table below.
+ * The table is a kind of heuristics that tries to match the user intentions.
+ * <pre>
+ * For sidegrade:
+ || src blobstore defined || src blobs embedded || dst blobstore defined || --copy-binaries || outcome src blobstore || outcome action
+ | - | - | - | - | missing | copy references¹
+ | - | - | - | + | missing | (x) not supported
+ | - | - | + | * | missing | (x) not supported
+ | - | + | - | * | embedded | copy to embedded
+ | - | + | + | * | embedded | copy to defined blobstore
+ | + | * | - | - | as in src | copy references
+ | + | * | - | + | as in src | copy to embedded
+ | + | * | + | * | as in src | copy to defined blobstore
+
+ ¹ - (x) not supported for SegmentMK -> MongoMK migration
+
+ For upgrade:
+
+ || dst blobstore defined || --copy-binaries || outcome src blobstore || outcome action
+ | - | - | defined by JCR2 | copy references
+ | - | + | defined by JCR2 | copy to embedded
+ | + | * | defined by JCR2 | copy to defined blobstore
+ * </pre>
+ */
+public class DatastoreArguments {
+
+ private static final Logger log = LoggerFactory.getLogger(DatastoreArguments.class);
+
+ private final BlobStoreFactory definedSrcBlob;
+
+ private final BlobStoreFactory definedDstBlob;
+
+ private final StoreArguments storeArguments;
+
+ private final BlobMigrationCase blobMigrationCase;
+
+ private final MigrationOptions options;
+
+ private final boolean srcEmbedded;
+
+ public DatastoreArguments(MigrationOptions options, StoreArguments storeArguments, boolean srcEmbedded) throws CliArgumentException {
+ this.storeArguments = storeArguments;
+ this.options = options;
+ this.srcEmbedded = srcEmbedded;
+
+ try {
+ blobMigrationCase = discoverBlobMigrationCase();
+ } catch (IOException e) {
+ log.error("Can't figure out the right blob migration path", e);
+ throw new CliArgumentException(1);
+ }
+
+ if (blobMigrationCase == BlobMigrationCase.UNSUPPORTED) {
+ throw new CliArgumentException("This combination of data- and node-stores is not supported", 1);
+ }
+
+ try {
+ definedSrcBlob = options.isSrcBlobStoreDefined() ? getDefinedSrcBlobStore() : null;
+ definedDstBlob = options.isDstBlobStoreDefined() ? getDefinedDstBlobStore() : null;
+ } catch(IOException e) {
+ log.error("Can't read the blob configuration", e);
+ throw new CliArgumentException(1);
+ }
+
+ log.info(blobMigrationCase.getDescription(this));
+ }
+
+ public BlobStoreFactory getSrcBlobStore() throws IOException {
+ BlobStoreFactory result;
+ if (options.isSrcBlobStoreDefined()) {
+ result = definedSrcBlob;
+ } else if (blobMigrationCase == BlobMigrationCase.COPY_REFERENCES) {
+ result = new MissingBlobStoreFactory();
+ } else {
+ result = new DummyBlobStoreFactory(); // embedded
+ }
+ log.info("Source blob store: {}", result);
+ return result;
+ }
+
+ public BlobStoreFactory getDstBlobStore(BlobStore srcBlobStore) throws IOException {
+ BlobStoreFactory result;
+ if (options.isDstBlobStoreDefined()) {
+ result = definedDstBlob;
+ } else if (blobMigrationCase == BlobMigrationCase.COPY_REFERENCES && (options.isSrcBlobStoreDefined() || storeArguments.getSrcType() == JCR2_DIR_XML)) {
+ result = new ConstantBlobStoreFactory(srcBlobStore);
+ } else if (blobMigrationCase == BlobMigrationCase.COPY_REFERENCES) {
+ result = new MissingBlobStoreFactory();
+ } else {
+ result = new DummyBlobStoreFactory(); // embedded
+ }
+
+ log.info("Destination blob store: {}", result);
+ return result;
+ }
+
+ private BlobStoreFactory getDefinedSrcBlobStore() throws IOException {
+ boolean ignoreMissingBinaries = options.isIgnoreMissingBinaries();
+ if (options.isSrcFbs()) {
+ return new FileBlobStoreFactory(options.getSrcFbs());
+ } else if (options.isSrcS3()) {
+ return new S3DataStoreFactory(options.getSrcS3Config(), options.getSrcS3(), ignoreMissingBinaries);
+ } else if (options.isSrcFds()) {
+ return new FileDataStoreFactory(options.getSrcFds(), ignoreMissingBinaries);
+ } else {
+ return null;
+ }
+ }
+
+ private BlobStoreFactory getDefinedDstBlobStore() throws IOException {
+ if (options.isDstFbs()) {
+ return new FileBlobStoreFactory(options.getDstFbs());
+ } else if (options.isDstS3()) {
+ return new S3DataStoreFactory(options.getDstS3Config(), options.getDstS3(), false);
+ } else if (options.isDstFds()) {
+ return new FileDataStoreFactory(options.getDstFds(), false);
+ } else {
+ return null;
+ }
+ }
+
+ public enum BlobMigrationCase {
+ COPY_REFERENCES("Only blob references will be copied"),
+ EMBEDDED_TO_EMBEDDED("Blobs embedded in ${srcnode} will be embedded in ${dstnode}"),
+ EMBEDDED_TO_EXTERNAL("Blobs embedded in ${srcnode} will be copied to ${dstblob}"),
+ EXTERNAL_TO_EMBEDDED("Blobs stored in ${srcblob} will be embedded in ${dstnode}"),
+ EXTERNAL_TO_EXTERNAL("Blobs stored in ${srcblob} will be copied to ${dstblob}"),
+ UNSUPPORTED("Unsupported case");
+
+ private final String description;
+
+ BlobMigrationCase(String description) {
+ this.description = description;
+ }
+
+ private String getDescription(DatastoreArguments datastoreArguments) {
+ Map<String, String> map = newHashMap();
+ map.put("srcnode", datastoreArguments.storeArguments.getSrcDescriptor());
+ map.put("dstnode", datastoreArguments.storeArguments.getDstDescriptor());
+
+ if (datastoreArguments.storeArguments.getSrcType() == JCR2_DIR_XML) {
+ map.put("srcblob", "CRX2 datastore");
+ } else {
+ map.put("srcblob", datastoreArguments.definedSrcBlob == null ? "?" : datastoreArguments.definedSrcBlob.toString());
+ }
+ map.put("dstblob", datastoreArguments.definedDstBlob == null ? "?" : datastoreArguments.definedDstBlob.toString());
+
+ StrSubstitutor subst = new StrSubstitutor(map);
+ return subst.replace(description);
+ }
+
+ }
+
+ public BlobMigrationCase getBlobMigrationCase() {
+ return blobMigrationCase;
+ }
+
+ private BlobMigrationCase discoverBlobMigrationCase() throws IOException {
+ boolean srcDefined = options.isSrcBlobStoreDefined() || storeArguments.getSrcType() == JCR2_DIR_XML;
+ boolean dstDefined = options.isDstBlobStoreDefined();
+ boolean copyBinaries = options.isCopyBinaries();
+
+ boolean srcSegment = storeArguments.getSrcType().isSegment();
+ boolean dstSegment = storeArguments.getDstType().isSegment();
+
+ // default case, no datastore-related arguments given, but blobs are stored externally
+ if (!srcDefined && !dstDefined && !srcEmbedded && !copyBinaries) {
+ if (srcSegment && !dstSegment) { // segment -> document is not supported for this case
+ return BlobMigrationCase.UNSUPPORTED;
+ } else { // we try to copy references using MissingBlobStore
+ return BlobMigrationCase.COPY_REFERENCES;
+ }
+ // can't copy binaries if they are stored externally and we don't know where
+ } else if (!srcDefined && !dstDefined && !srcEmbedded && copyBinaries) {
+ return BlobMigrationCase.UNSUPPORTED;
+ // can't copy binaries if they are stored externally and we don't know where
+ // (even if the destination datastore is defined)
+ } else if (!srcDefined && !srcEmbedded && dstDefined) {
+ return BlobMigrationCase.UNSUPPORTED;
+ // source is embedded and no destination given
+ } else if (!srcDefined && srcEmbedded && !dstDefined) {
+ return BlobMigrationCase.EMBEDDED_TO_EMBEDDED;
+ // source is embedded and the destination is given
+ } else if (!srcDefined && srcEmbedded && dstDefined) {
+ return BlobMigrationCase.EMBEDDED_TO_EXTERNAL;
+ // source is given, no destination, but also no --copy-binaries -> copy references
+ } else if (srcDefined && !dstDefined && !copyBinaries) {
+ return BlobMigrationCase.COPY_REFERENCES;
+ // source is given, no destination, but --copy-binaries -> copy to embedded
+ } else if (srcDefined && !dstDefined && copyBinaries) {
+ return BlobMigrationCase.EXTERNAL_TO_EMBEDDED;
+ // source and destination is given
+ } else if (srcDefined && dstDefined) {
+ return BlobMigrationCase.EXTERNAL_TO_EXTERNAL;
+ }
+ return BlobMigrationCase.UNSUPPORTED;
+ }
+}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationCliArguments.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationCliArguments.java?rev=1792993&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationCliArguments.java (added)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationCliArguments.java Fri Apr 28 07:16:13 2017
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+ public MigrationCliArguments(OptionSet options) throws CliArgumentException {
+ this.options = options;
+ this.arguments = getNonOptionArguments();
+ }
+
+ 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 List<String> getArguments() {
+ return arguments;
+ }
+}