Author: tomekr
Date: Fri Dec 16 11:12:53 2016
New Revision: 1774571
URL: http://svn.apache.org/viewvc?rev=1774571&view=rev
Log:
OAK-5290 Backported the oak-upgrade from trunk.
Added:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/core/
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/core/IndexAccessor.java
- copied, changed from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/LoggingEqualsDiff.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ConstantBlobStoreFactory.java
- copied, changed from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStore.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStoreFactory.java
- copied, changed from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java
- copied, changed from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/DatastoreArguments.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/security/AuthorizableFolderEditor.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/AuthorizableFolderEditorTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/UpgradeOldSegmentTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFdsTest.java
- copied, changed from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFds.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentWithMissingDestinationDirectoryTest.java
- copied, changed from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyReferencesTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/parser/
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/parser/StoreArgumentsTest.java
- copied, changed from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/resources/test-repo-1.0.zip
Removed:
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFds.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyReferencesTest.java
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStore.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationCliArguments.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/StoreArguments.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/StoreType.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeState.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeState.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionCopier.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionCopyConfiguration.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionHistoryUtil.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionableEditor.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionablePropertiesEditor.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/resources/upgrade_usage.txt
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/AbstractRepositoryUpgradeTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/BrokenVersionableTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistoryTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositorySidegradeTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/SameNodeSiblingsTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStoreTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/Jcr2ToSegmentTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToJdbcTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFbsTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFdsTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToS3Test.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FdsToFbsTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3ToFbsTest.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileBlobStoreContainer.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileDataStoreContainer.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/JdbcNodeStoreContainer.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/MongoNodeStoreContainer.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/S3DataStoreContainer.java
jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java
Copied:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/core/IndexAccessor.java
(from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java)
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/core/IndexAccessor.java?p2=jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/core/IndexAccessor.java&p1=jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java&r1=1774499&r2=1774571&rev=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/core/IndexAccessor.java
Fri Dec 16 11:12:53 2016
@@ -14,16 +14,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.jackrabbit.oak.upgrade.cli.node;
+package org.apache.jackrabbit.core;
+import org.apache.jackrabbit.core.query.QueryHandler;
+import org.apache.jackrabbit.core.query.lucene.SearchIndex;
+import org.apache.lucene.index.IndexReader;
+
+import javax.jcr.RepositoryException;
import java.io.IOException;
-import org.apache.jackrabbit.oak.spi.blob.BlobStore;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
+public final class IndexAccessor {
-import com.google.common.io.Closer;
+ private IndexAccessor() {
+ }
-public interface NodeStoreFactory {
+ public static IndexReader getReader(RepositoryContext ctx) throws
RepositoryException, IOException {
+ RepositoryImpl repo = ctx.getRepository();
+ SearchManager searchMgr =
repo.getSearchManager(ctx.getRepositoryConfig().getDefaultWorkspaceName());
+ if (searchMgr == null) {
+ return null;
+ }
+ QueryHandler handler = searchMgr.getQueryHandler();
+ SearchIndex index = (SearchIndex) handler;
+ return index.getIndexReader();
+ }
- NodeStore create(BlobStore blobStore, Closer closer) throws IOException;
}
Added:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/LoggingEqualsDiff.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/LoggingEqualsDiff.java?rev=1774571&view=auto
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/LoggingEqualsDiff.java
(added)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/LoggingEqualsDiff.java
Fri Dec 16 11:12:53 2016
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.upgrade;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
+import org.slf4j.Logger;
+
+public class LoggingEqualsDiff implements NodeStateDiff {
+
+ private final Logger log;
+
+ private final String path;
+
+ private boolean pathDisplayed;
+
+ public LoggingEqualsDiff(Logger log, String path) {
+ this.log = log;
+ this.path = path;
+ }
+
+ @Override
+ public boolean propertyAdded(PropertyState after) {
+ displayPath();
+ log.info(" + {}<{}>", after.getName(), after.getType());
+ return false;
+ }
+
+ @Override
+ public boolean propertyChanged(PropertyState before, PropertyState after) {
+ displayPath();
+ log.info(" ^ {}<{}>", before.getName(), before.getType());
+ return false;
+ }
+
+ @Override
+ public boolean propertyDeleted(PropertyState before) {
+ displayPath();
+ log.info(" - {}<{}>", before.getName(), before.getType());
+ return false;
+ }
+
+ @Override
+ public boolean childNodeAdded(String name, NodeState after) {
+ String childPath = PathUtils.concat(path, name);
+ log.info("+ {}", childPath);
+ return false;
+ }
+
+ @Override
+ public boolean childNodeChanged(String name, NodeState before, NodeState
after) {
+ String childPath = PathUtils.concat(path, name);
+ return after.compareAgainstBaseState(before, new
LoggingEqualsDiff(log, childPath));
+ }
+
+ @Override
+ public boolean childNodeDeleted(String name, NodeState before) {
+ String childPath = PathUtils.concat(path, name);
+ log.info("- {}", childPath);
+ return false;
+ }
+
+ private void displayPath() {
+ if (!pathDisplayed) {
+ log.info("^ {}", path);
+ pathDisplayed = true;
+ }
+ }
+}
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
Fri Dec 16 11:12:53 2016
@@ -18,29 +18,35 @@ package org.apache.jackrabbit.oak.upgrad
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Comparator;
import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.jcr.RepositoryException;
-import org.apache.jackrabbit.oak.Oak;
+import com.google.common.base.Function;
+import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.commit.CompositeEditorProvider;
import org.apache.jackrabbit.oak.spi.commit.EditorHook;
import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
+import org.apache.jackrabbit.oak.spi.state.ApplyDiff;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.LoggingCompositeHook;
+import org.apache.jackrabbit.oak.upgrade.cli.node.TarNodeStore;
import org.apache.jackrabbit.oak.upgrade.nodestate.NameFilteringNodeState;
import org.apache.jackrabbit.oak.upgrade.nodestate.report.LoggingReporter;
import org.apache.jackrabbit.oak.upgrade.nodestate.report.ReportingNodeState;
import org.apache.jackrabbit.oak.upgrade.nodestate.NodeStateCopier;
import org.apache.jackrabbit.oak.upgrade.version.VersionCopyConfiguration;
+import org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil;
import org.apache.jackrabbit.oak.upgrade.version.VersionableEditor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,7 +54,14 @@ import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.ImmutableSet.copyOf;
import static com.google.common.collect.ImmutableSet.of;
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Lists.transform;
import static com.google.common.collect.Sets.union;
+import static java.util.Collections.sort;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
+import static
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants.NT_REP_PERMISSION_STORE;
+import static
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants.REP_PERMISSION_STORE;
import static
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.DEFAULT_EXCLUDE_PATHS;
import static
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.DEFAULT_INCLUDE_PATHS;
import static
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.DEFAULT_MERGE_PATHS;
@@ -58,11 +71,16 @@ import static org.apache.jackrabbit.oak.
import static
org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade.markIndexesToBeRebuilt;
import static
org.apache.jackrabbit.oak.upgrade.nodestate.NodeStateCopier.copyProperties;
import static
org.apache.jackrabbit.oak.upgrade.version.VersionCopier.copyVersionStorage;
+import static
org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil.getVersionStorage;
public class RepositorySidegrade {
private static final Logger LOG =
LoggerFactory.getLogger(RepositorySidegrade.class);
+ private static final int LOG_NODE_COPY =
Integer.getInteger("oak.upgrade.logNodeCopy", 10000);
+
+ private static final String WORKSPACE_NAME_PROP =
"oak.upgrade.workspaceName";
+
/**
* Target node store.
*/
@@ -85,9 +103,11 @@ public class RepositorySidegrade {
*/
private Set<String> mergePaths = DEFAULT_MERGE_PATHS;
- private boolean skipLongNames = true;
+ private boolean filterLongNames = true;
+
+ private boolean verify = false;
- private boolean skipInitialization = false;
+ private boolean onlyVerify = false;
private List<CommitHook> customCommitHooks = null;
@@ -112,8 +132,8 @@ public class RepositorySidegrade {
* not referenced by the existing nodes). By default all orphaned version
* histories are copied. One may disable it completely by setting
* {@code null} here or limit it to a selected date range:
- * {@code <minDate, now()>}. <br/>
- * <br/>
+ * {@code <minDate, now()>}. <br>
+ * <br>
* Please notice, that this option is overriden by the
* {@link #setCopyVersions(Calendar)}. You can't copy orphaned versions
* older than set in {@link #setCopyVersions(Calendar)} and if you set
@@ -181,7 +201,6 @@ public class RepositorySidegrade {
this.excludePaths = copyOf(checkNotNull(excludes));
}
-
/**
* Sets the paths that should be merged when the source repository
* is copied to the target repository.
@@ -192,22 +211,20 @@ public class RepositorySidegrade {
this.mergePaths = copyOf(checkNotNull(merges));
}
- public boolean isSkipLongNames() {
- return skipLongNames;
+ public boolean isFilterLongNames() {
+ return filterLongNames;
}
- public void setSkipLongNames(boolean skipLongNames) {
- this.skipLongNames = skipLongNames;
+ public void setFilterLongNames(boolean filterLongNames) {
+ this.filterLongNames = filterLongNames;
}
- /**
- * Skip the new repository initialization. Only copy content passed in the
- * {@link #includePaths}.
- *
- * @param skipInitialization
- */
- public void setSkipInitialization(boolean skipInitialization) {
- this.skipInitialization = skipInitialization;
+ public void setVerify(boolean verify) {
+ this.verify = verify;
+ }
+
+ public void setOnlyVerify(boolean onlyVerify) {
+ this.onlyVerify = onlyVerify;
}
/**
@@ -227,31 +244,35 @@ public class RepositorySidegrade {
* during the copy operation as this method requires exclusive access
* to the repositories.
*
- * @param initializer optional extra repository initializer to use
+ * @param initializer optional repository initializer to use
*
* @throws RepositoryException if the copy operation fails
*/
public void copy(RepositoryInitializer initializer) throws
RepositoryException {
try {
- NodeBuilder targetRoot = target.getRoot().builder();
+ if (!onlyVerify) {
+ NodeBuilder targetRoot = target.getRoot().builder();
+ if (VersionHistoryUtil.getVersionStorage(targetRoot).exists()
&& !versionCopyConfiguration.skipOrphanedVersionsCopy()) {
+ LOG.warn("The version storage on destination already
exists. Orphaned version histories will be skipped.");
+ versionCopyConfiguration.setCopyOrphanedVersions(null);
+ }
- if (skipInitialization) {
- LOG.info("Skipping the repository initialization");
- } else {
- new InitialContent().initialize(targetRoot);
if (initializer != null) {
initializer.initialize(targetRoot);
}
- }
- final NodeState reportingSourceRoot =
ReportingNodeState.wrap(source.getRoot(), new LoggingReporter(LOG, "Copying",
10000, -1));
- final NodeState sourceRoot;
- if (skipLongNames) {
- sourceRoot = NameFilteringNodeState.wrap(reportingSourceRoot);
- } else {
- sourceRoot = reportingSourceRoot;
+ final NodeState reportingSourceRoot =
ReportingNodeState.wrap(source.getRoot(), new LoggingReporter(LOG, "Copying",
LOG_NODE_COPY, -1));
+ final NodeState sourceRoot;
+ if (filterLongNames) {
+ sourceRoot =
NameFilteringNodeState.wrap(reportingSourceRoot);
+ } else {
+ sourceRoot = reportingSourceRoot;
+ }
+ copyState(sourceRoot, targetRoot);
+ }
+ if (verify || onlyVerify) {
+ verify();
}
- copyState(sourceRoot, targetRoot);
} catch (Exception e) {
throw new RepositoryException("Failed to copy content", e);
@@ -259,29 +280,48 @@ public class RepositorySidegrade {
}
private void removeCheckpointReferences(NodeBuilder builder) throws
CommitFailedException {
- // removing references to the checkpoints,
+ // removing references to the checkpoints,
// which don't exist in the new repository
builder.setChildNode(":async");
}
- private void copyState(NodeState sourceRoot, NodeBuilder targetRoot)
throws CommitFailedException {
+ private void copyState(NodeState sourceRoot, NodeBuilder targetRoot)
throws CommitFailedException, RepositoryException {
copyWorkspace(sourceRoot, targetRoot);
- removeCheckpointReferences(targetRoot);
- if (!versionCopyConfiguration.skipOrphanedVersionsCopy()) {
- copyVersionStorage(sourceRoot, targetRoot,
versionCopyConfiguration);
+
+ boolean isRemoveCheckpointReferences = false;
+ if (!isCompleteMigration()) {
+ LOG.info("Custom paths have been specified, checkpoints won't be
migrated");
+ isRemoveCheckpointReferences = true;
+ } else {
+ boolean checkpointsCopied = copyCheckpoints(targetRoot);
+ if (!checkpointsCopied) {
+ LOG.info("Copying checkpoints is not supported for this
combination of node stores");
+ isRemoveCheckpointReferences = true;
+ }
+ }
+ if (isRemoveCheckpointReferences) {
+ removeCheckpointReferences(targetRoot);
}
final List<CommitHook> hooks = new ArrayList<CommitHook>();
- hooks.add(new EditorHook(
- new VersionableEditor.Provider(sourceRoot,
Oak.DEFAULT_WORKSPACE_NAME, versionCopyConfiguration)));
+ if (!versionCopyConfiguration.isCopyAll()) {
+ NodeBuilder versionStorage =
VersionHistoryUtil.getVersionStorage(targetRoot);
+ if (!versionStorage.exists()) { // it's possible that this is a
new repository and the version storage
+ // hasn't been created/copied yet
+ versionStorage =
VersionHistoryUtil.createVersionStorage(targetRoot);
+ }
+ if (!versionCopyConfiguration.skipOrphanedVersionsCopy()) {
+ copyVersionStorage(targetRoot, getVersionStorage(sourceRoot),
versionStorage, versionCopyConfiguration);
+ }
+ hooks.add(new EditorHook(new
VersionableEditor.Provider(sourceRoot, getWorkspaceName(),
versionCopyConfiguration)));
+ }
if (customCommitHooks != null) {
hooks.addAll(customCommitHooks);
}
- markIndexesToBeRebuilt(targetRoot);
-
if (!isCompleteMigration()) {
+ markIndexesToBeRebuilt(targetRoot);
// type validation, reference and indexing hooks
hooks.add(new EditorHook(new CompositeEditorProvider(
createTypeEditorProvider(),
@@ -298,7 +338,12 @@ public class RepositorySidegrade {
private void copyWorkspace(NodeState sourceRoot, NodeBuilder targetRoot) {
final Set<String> includes =
calculateEffectiveIncludePaths(includePaths, sourceRoot);
- final Set<String> excludes = union(copyOf(this.excludePaths),
of("/jcr:system/jcr:versionStorage"));
+ final Set<String> excludes;
+ if (versionCopyConfiguration.isCopyAll()) {
+ excludes = copyOf(this.excludePaths);
+ } else {
+ excludes = union(copyOf(this.excludePaths),
of("/jcr:system/jcr:versionStorage"));
+ }
final Set<String> merges = union(copyOf(this.mergePaths),
of("/jcr:system"));
NodeStateCopier.builder()
@@ -311,4 +356,138 @@ public class RepositorySidegrade {
copyProperties(sourceRoot, targetRoot);
}
}
-}
\ No newline at end of file
+
+ private boolean copyCheckpoints(NodeBuilder targetRoot) {
+ if (!(source instanceof TarNodeStore && target instanceof
TarNodeStore)) {
+ return false;
+ }
+
+ TarNodeStore sourceTarNS = (TarNodeStore) source;
+ TarNodeStore targetTarNS = (TarNodeStore) target;
+
+ NodeState sourceSuperRoot = sourceTarNS.getSuperRoot();
+ NodeBuilder targetSuperRoot = targetTarNS.getSuperRoot().builder();
+
+ String previousCheckpoint = null;
+ for (String checkpoint : getCheckpointNames(sourceSuperRoot)) {
+ NodeState targetPreviousRoot, sourcePreviousRoot;
+ if (previousCheckpoint == null) {
+ sourcePreviousRoot = source.getRoot();
+ targetPreviousRoot = targetRoot.getNodeState();
+ } else {
+ sourcePreviousRoot = getCheckpointRoot(sourceSuperRoot,
previousCheckpoint);
+ targetPreviousRoot =
getCheckpointRoot(targetSuperRoot.getNodeState(), previousCheckpoint);
+ }
+ NodeState sourceCheckpoint = getCheckpoint(sourceSuperRoot,
checkpoint);
+ NodeBuilder targetCheckpoint = getCheckpoint(targetSuperRoot,
checkpoint);
+
+ // copy checkpoint metadata
+ NodeStateCopier.copyProperties(sourceCheckpoint, targetCheckpoint);
+ targetCheckpoint.setChildNode("properties",
sourceCheckpoint.getChildNode("properties"));
+
+ // create the checkpoint root
+ NodeState sourceCheckpointRoot =
sourceCheckpoint.getChildNode("root");
+ NodeBuilder targetCheckpointRoot =
targetCheckpoint.setChildNode("root", targetPreviousRoot);
+ sourceCheckpointRoot.compareAgainstBaseState(sourcePreviousRoot,
new ApplyDiff(targetCheckpointRoot));
+
+ previousCheckpoint = checkpoint;
+ }
+
+ targetTarNS.setSuperRoot(targetSuperRoot);
+ return true;
+ }
+
+ /**
+ * Return all checkpoint paths, sorted by their "created" property,
descending.
+ *
+ * @param superRoot
+ * @return
+ */
+ private static List<String> getCheckpointNames(NodeState superRoot) {
+ List<ChildNodeEntry> checkpoints =
newArrayList(superRoot.getChildNode("checkpoints").getChildNodeEntries().iterator());
+ sort(checkpoints, new Comparator<ChildNodeEntry>() {
+ @Override
+ public int compare(ChildNodeEntry o1, ChildNodeEntry o2) {
+ long c1 = o1.getNodeState().getLong("created");
+ long c2 = o1.getNodeState().getLong("created");
+ return -Long.compare(c1, c2);
+ }
+ });
+ return transform(checkpoints, new Function<ChildNodeEntry, String>() {
+ @Nullable
+ @Override
+ public String apply(@Nullable ChildNodeEntry input) {
+ return input.getName();
+ }
+ });
+ }
+
+ private static NodeState getCheckpointRoot(NodeState superRoot, String
name) {
+ return getCheckpoint(superRoot, name).getChildNode("root");
+ }
+
+ private static NodeState getCheckpoint(NodeState superRoot, String name) {
+ return superRoot.getChildNode("checkpoints").getChildNode(name);
+ }
+
+ private static NodeBuilder getCheckpoint(NodeBuilder superRoot, String
name) {
+ return superRoot.child("checkpoints").child(name);
+ }
+
+ private String getWorkspaceName() throws RepositoryException {
+ String definedName = System.getProperty(WORKSPACE_NAME_PROP);
+ String detectedName = deriveWorkspaceName();
+ if (StringUtils.isNotBlank(definedName)) {
+ return definedName;
+ } else if (StringUtils.isNotBlank(detectedName)) {
+ return detectedName;
+ } else {
+ throw new RepositoryException("Can't detect the workspace name.
Please use the system property " + WORKSPACE_NAME_PROP + " to set it
manually.");
+ }
+ }
+
+ /**
+ * This method tries to derive the workspace name from the source
repository. It uses the
+ * fact that the /jcr:system/rep:permissionStore usually contains just one
child
+ * named after the workspace.
+ *
+ * @return the workspace name or null if it can't be derived
+ */
+ private String deriveWorkspaceName() {
+ NodeState permissionStore =
source.getRoot().getChildNode(JCR_SYSTEM).getChildNode(REP_PERMISSION_STORE);
+ List<String> nameCandidates = new ArrayList<String>();
+ for (ChildNodeEntry e : permissionStore.getChildNodeEntries()) {
+ String primaryType = e.getNodeState().getName(JCR_PRIMARYTYPE);
+ if (NT_REP_PERMISSION_STORE.equals(primaryType)) {
+ nameCandidates.add(e.getName());
+ }
+ }
+ if (nameCandidates.size() == 1) {
+ return nameCandidates.get(0);
+ } else {
+ return null;
+ }
+ }
+
+ private void verify() {
+ final NodeState sourceRoot;
+ final NodeState targetRoot;
+
+ if (source instanceof TarNodeStore && target instanceof TarNodeStore) {
+ sourceRoot = ((TarNodeStore) source).getSuperRoot();
+ targetRoot = ((TarNodeStore) target).getSuperRoot();
+ } else {
+ sourceRoot = source.getRoot();
+ targetRoot = target.getRoot();
+ }
+
+ final NodeState reportingSource = ReportingNodeState.wrap(sourceRoot,
new LoggingReporter(LOG, "Verifying", LOG_NODE_COPY, -1));
+
+ LOG.info("Verifying whether repositories are identical");
+ if (targetRoot.compareAgainstBaseState(reportingSource, new
LoggingEqualsDiff(LOG, "/"))) {
+ LOG.info("Verification result: both repositories are identical");
+ } else {
+ LOG.warn("Verification result: repositories are not identical");
+ }
+ }
+}
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java
Fri Dec 16 11:12:53 2016
@@ -31,6 +31,7 @@ import static org.apache.jackrabbit.oak.
import static
org.apache.jackrabbit.oak.plugins.name.Namespaces.addCustomMapping;
import static
org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.NODE_TYPES_PATH;
import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_ALL;
+import static
org.apache.jackrabbit.oak.upgrade.cli.parser.OptionParserFactory.SKIP_NAME_CHECK;
import static
org.apache.jackrabbit.oak.upgrade.nodestate.FilteringNodeState.ALL;
import static
org.apache.jackrabbit.oak.upgrade.nodestate.FilteringNodeState.NONE;
import static
org.apache.jackrabbit.oak.upgrade.nodestate.NodeStateCopier.copyProperties;
@@ -51,7 +52,9 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.jcr.NamespaceException;
+import javax.jcr.Node;
import javax.jcr.RepositoryException;
+import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.nodetype.NodeDefinitionTemplate;
@@ -68,6 +71,7 @@ import com.google.common.collect.Immutab
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+import org.apache.jackrabbit.core.IndexAccessor;
import org.apache.jackrabbit.core.RepositoryContext;
import org.apache.jackrabbit.core.config.BeanConfig;
import org.apache.jackrabbit.core.config.LoginModuleConfig;
@@ -76,6 +80,7 @@ import org.apache.jackrabbit.core.config
import org.apache.jackrabbit.core.fs.FileSystem;
import org.apache.jackrabbit.core.fs.FileSystemException;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.core.query.lucene.FieldNames;
import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
import org.apache.jackrabbit.core.security.user.UserManagerImpl;
import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -89,7 +94,6 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.index.IndexUpdate;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateCallback;
import org.apache.jackrabbit.oak.plugins.index.IndexUtils;
-import
org.apache.jackrabbit.oak.plugins.index.counter.NodeCounterEditorProvider;
import
org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
import
org.apache.jackrabbit.oak.plugins.index.reference.ReferenceEditorProvider;
import org.apache.jackrabbit.oak.plugins.name.NamespaceConstants;
@@ -121,9 +125,11 @@ import org.apache.jackrabbit.oak.upgrade
import org.apache.jackrabbit.oak.upgrade.nodestate.report.LoggingReporter;
import org.apache.jackrabbit.oak.upgrade.nodestate.report.ReportingNodeState;
import org.apache.jackrabbit.oak.upgrade.nodestate.NodeStateCopier;
+import org.apache.jackrabbit.oak.upgrade.security.AuthorizableFolderEditor;
import org.apache.jackrabbit.oak.upgrade.security.GroupEditorProvider;
import org.apache.jackrabbit.oak.upgrade.security.RestrictionEditorProvider;
import org.apache.jackrabbit.oak.upgrade.version.VersionCopyConfiguration;
+import org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil;
import org.apache.jackrabbit.oak.upgrade.version.VersionableEditor;
import org.apache.jackrabbit.oak.upgrade.version.VersionablePropertiesEditor;
import org.apache.jackrabbit.spi.Name;
@@ -135,16 +141,23 @@ import org.apache.jackrabbit.spi.QValueC
import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.jackrabbit.spi.commons.value.ValueFormat;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermDocs;
+import org.apache.lucene.index.TermEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static
org.apache.jackrabbit.oak.upgrade.version.VersionCopier.copyVersionStorage;
+import static
org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil.getVersionStorage;
public class RepositoryUpgrade {
private static final Logger logger =
LoggerFactory.getLogger(RepositoryUpgrade.class);
- private static final Set<String> INDEXES_TO_REBUILD =
ImmutableSet.of("counter");
+ private static final int LOG_NODE_COPY =
Integer.getInteger("oak.upgrade.logNodeCopy", 10000);
+
+ private static final Set<String> INDEXES_TO_REBUILD =
ImmutableSet.of("counter", "uuid");
public static final Set<String> DEFAULT_INCLUDE_PATHS = ALL;
@@ -188,7 +201,9 @@ public class RepositoryUpgrade {
private List<CommitHook> customCommitHooks = null;
- private boolean skipLongNames = true;
+ private boolean checkLongNames = false;
+
+ private boolean filterLongNames = true;
private boolean skipInitialization = false;
@@ -262,12 +277,20 @@ public class RepositoryUpgrade {
this.earlyShutdown = earlyShutdown;
}
- public boolean isSkipLongNames() {
- return skipLongNames;
+ public boolean isCheckLongNames() {
+ return checkLongNames;
+ }
+
+ public void setCheckLongNames(boolean checkLongNames) {
+ this.checkLongNames = checkLongNames;
+ }
+
+ public boolean isFilterLongNames() {
+ return filterLongNames;
}
- public void setSkipLongNames(boolean skipLongNames) {
- this.skipLongNames = skipLongNames;
+ public void setFilterLongNames(boolean filterLongNames) {
+ this.filterLongNames = filterLongNames;
}
public boolean isSkipInitialization() {
@@ -318,7 +341,6 @@ public class RepositoryUpgrade {
this.excludePaths = copyOf(checkNotNull(excludes));
}
-
/**
* Sets the paths that should be merged when the source repository
* is copied to the target repository.
@@ -348,8 +370,8 @@ public class RepositoryUpgrade {
* not referenced by the existing nodes). By default all orphaned version
* histories are copied. One may disable it completely by setting
* {@code null} here or limit it to a selected date range:
- * {@code <minDate, now()>}. <br/>
- * <br/>
+ * {@code <minDate, now()>}. <br>
+ * <br>
* Please notice, that this option is overriden by the
* {@link #setCopyVersions(Calendar)}. You can't copy orphaned versions
* older than set in {@link #setCopyVersions(Calendar)} and if you set
@@ -378,10 +400,18 @@ public class RepositoryUpgrade {
* @throws RepositoryException if the copy operation fails
*/
public void copy(RepositoryInitializer initializer) throws
RepositoryException {
+ if (checkLongNames) {
+ assertNoLongNames();
+ }
+
RepositoryConfig config = source.getRepositoryConfig();
logger.info("Copying repository content from {} to Oak",
config.getHomeDir());
try {
NodeBuilder targetBuilder = target.getRoot().builder();
+ if (VersionHistoryUtil.getVersionStorage(targetBuilder).exists()
&& !versionCopyConfiguration.skipOrphanedVersionsCopy()) {
+ logger.warn("The version storage on destination already
exists. Orphaned version histories will be skipped.");
+ versionCopyConfiguration.setCopyOrphanedVersions(null);
+ }
final Root upgradeRoot = new UpgradeRoot(targetBuilder);
String workspaceName =
@@ -453,10 +483,10 @@ public class RepositoryUpgrade {
source, workspaceName,
targetBuilder.getNodeState(),
uriToPrefix, copyBinariesByReference, skipOnError
),
- new LoggingReporter(logger, "Migrating", 10000, -1)
+ new LoggingReporter(logger, "Migrating", LOG_NODE_COPY, -1)
);
final NodeState sourceRoot;
- if (skipLongNames) {
+ if (filterLongNames) {
sourceRoot = NameFilteringNodeState.wrap(reportingSourceRoot);
} else {
sourceRoot = reportingSourceRoot;
@@ -472,7 +502,7 @@ public class RepositoryUpgrade {
if (!versionCopyConfiguration.skipOrphanedVersionsCopy()) {
logger.info("Copying version storage");
watch.reset().start();
- copyVersionStorage(sourceRoot, targetBuilder,
versionCopyConfiguration);
+ copyVersionStorage(targetBuilder,
getVersionStorage(sourceRoot), getVersionStorage(targetBuilder),
versionCopyConfiguration);
targetBuilder.getNodeState(); // on TarMK this does call
triggers the actual copy
logger.info("Version storage copied in {}s ({})",
watch.elapsed(TimeUnit.SECONDS), watch);
} else {
@@ -489,6 +519,9 @@ public class RepositoryUpgrade {
String groupsPath = userConf.getParameters().getConfigValue(
UserConstants.PARAM_GROUP_PATH,
UserConstants.DEFAULT_GROUP_PATH);
+ String usersPath = userConf.getParameters().getConfigValue(
+ UserConstants.PARAM_USER_PATH,
+ UserConstants.DEFAULT_USER_PATH);
// hooks specific to the upgrade, need to run first
hooks.add(new EditorHook(new CompositeEditorProvider(
@@ -496,7 +529,8 @@ public class RepositoryUpgrade {
new GroupEditorProvider(groupsPath),
// copy referenced version histories
new VersionableEditor.Provider(sourceRoot, workspaceName,
versionCopyConfiguration),
- new SameNameSiblingsEditor.Provider()
+ new SameNameSiblingsEditor.Provider(),
+ AuthorizableFolderEditor.provider(groupsPath, usersPath)
)));
// this editor works on the VersionableEditor output, so it can't
be
@@ -946,6 +980,43 @@ public class RepositoryUpgrade {
return includes;
}
+ void assertNoLongNames() throws RepositoryException {
+ Session session = source.getRepository().login(null, null);
+ boolean longNameFound = false;
+ try {
+ IndexReader reader = IndexAccessor.getReader(source);
+ if (reader == null) {
+ return;
+ }
+ TermEnum terms = reader.terms(new Term(FieldNames.LOCAL_NAME));
+ while (terms.next()) {
+ Term t = terms.term();
+ if (!FieldNames.LOCAL_NAME.equals(t.field())) {
+ continue;
+ }
+ String name = t.text();
+ if (NameFilteringNodeState.isNameTooLong(name)) {
+ TermDocs docs = reader.termDocs(t);
+ if (docs.next()) {
+ int docId = docs.doc();
+ String uuid =
reader.document(docId).get(FieldNames.UUID);
+ Node n = session.getNodeByIdentifier(uuid);
+ logger.warn("Name too long: {}", n.getPath());
+ longNameFound = true;
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new RepositoryException(e);
+ } finally {
+ session.logout();
+ }
+ if (longNameFound) {
+ logger.error("Node with a long name has been found. Please fix the
content or rerun the migration with {} option.", SKIP_NAME_CHECK);
+ throw new RepositoryException("Node with a long name has been
found.");
+ }
+ }
+
static class LoggingCompositeHook implements CommitHook {
private final Collection<CommitHook> hooks;
private boolean started = false;
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStore.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStore.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStore.java
Fri Dec 16 11:12:53 2016
@@ -57,27 +57,27 @@ import static com.google.common.base.Pre
/**
* A DelegatingDataStore can avoid performing expensive file system access by
making
* use of pre computed data related to files in DataStore.
- * <p/>
- * <p>During repository migration actual blob content is not accessed and
instead
+ * <p>
+ * During repository migration actual blob content is not accessed and instead
* only the blob length and blob references are accessed. DelegatingDataStore
can be
* configured with a mapping file which would be used to determine the length
of given
- * blob reference.</p>
- * <p/>
+ * blob reference.
+ * <p>
* Mapping file format
- * <pre><![CDATA[
+ * <pre>{@code
* #< length >| < identifier >
* 4432|dd10bca036f3134352c63e534d4568a3d2ac2fdc
* 32167|dd10bca036f3134567c63e534d4568a3d2ac2fdc
- * ]]></pre>
- * <p/>
+ * }</pre>
+ * <p>
* The Configuration:
- * <p/>
- * <pre><![CDATA[
+ * <p>
+ * <pre>{@code
* <DataStore
class="org.apache.jackrabbit.oak.upgrade.blob.LengthCachingDataStore">
* <param name="mappingFilePath" value="/path/to/mapping/file" />
* <param name="delegateClass"
value="org.apache.jackrabbit.core.data.FileDataStore" />
* </DataStore>
- * ]]></pre>
+ * }</pre>
*/
public class LengthCachingDataStore extends AbstractDataStore {
private static final Logger log =
LoggerFactory.getLogger(LengthCachingDataStore.class);
@@ -292,7 +292,7 @@ public class LengthCachingDataStore exte
InputStream is = null;
try {
Properties props = new Properties();
- is = Files.newInputStreamSupplier(configFile).getInput();
+ is = Files.asByteSource(configFile).openStream();
props.load(is);
PropertiesUtil.populate(delegate, propsToMap(props), false);
log.info("Configured the delegating DataStore via {}",
configFile.getAbsolutePath());
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java
Fri Dec 16 11:12:53 2016
@@ -20,35 +20,15 @@ import java.io.IOException;
import java.io.InputStream;
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;
-
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"));
}
@@ -62,18 +42,6 @@ public class CliUtils {
}
}
- 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) {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
Fri Dec 16 11:12:53 2016
@@ -29,6 +29,8 @@ import org.apache.jackrabbit.oak.spi.com
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;
@@ -41,44 +43,40 @@ public class MigrationFactory {
protected final StoreArguments stores;
+ protected final DatastoreArguments datastores;
+
protected final Closer closer;
- public MigrationFactory(MigrationOptions options, StoreArguments stores,
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 {
+ 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 {
- BlobStore srcBlobStore = stores.getSrcBlobStore().create(closer);
+ 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;
- if (options.isCopyBinariesByReference()) {
- dstBlobStore = srcBlobStore;
- } else {
- dstBlobStore = stores.getDstBlobStore().create(closer);
- }
+ 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);
- if (source.getDataStore() != null &&
options.isCopyBinariesByReference()) {
- upgrade.setCopyBinariesByReference(true);
- }
+ upgrade.setCopyBinariesByReference(datastores.getBlobMigrationCase()
== DatastoreArguments.BlobMigrationCase.COPY_REFERENCES);
upgrade.setCopyVersions(options.getCopyVersions());
upgrade.setCopyOrphanedVersions(options.getCopyOrphanedVersions());
if (options.getIncludePaths() != null) {
@@ -90,7 +88,8 @@ public class MigrationFactory {
if (options.getMergePaths() != null) {
upgrade.setMerges(options.getMergePaths());
}
- upgrade.setSkipLongNames(stores.isSkipLongNames());
+ upgrade.setFilterLongNames(!stores.getDstType().isSupportLongNames());
+ upgrade.setCheckLongNames(!options.isSkipNameCheck() &&
!stores.getDstType().isSupportLongNames());
upgrade.setSkipOnError(!options.isFailOnError());
upgrade.setEarlyShutdown(options.isEarlyShutdown());
upgrade.setSkipInitialization(options.isSkipInitialization());
@@ -114,8 +113,9 @@ public class MigrationFactory {
if (options.getMergePaths() != null) {
sidegrade.setMerges(options.getMergePaths());
}
- sidegrade.setSkipLongNames(stores.isSkipLongNames());
- sidegrade.setSkipInitialization(options.isSkipInitialization());
+ sidegrade.setFilterLongNames(stores.getSrcType().isSupportLongNames()
&& !stores.getDstType().isSupportLongNames());
+ sidegrade.setVerify(options.isVerify());
+ sidegrade.setOnlyVerify(options.isOnlyVerify());
return sidegrade;
}
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java
Fri Dec 16 11:12:53 2016
@@ -25,8 +25,11 @@ 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;
@@ -35,19 +38,39 @@ import org.apache.jackrabbit.oak.upgrade
public class OakUpgrade {
public static void main(String... args) throws IOException {
- MigrationCliArguments cliArguments =
CliUtils.parseOrExit(OptionParserFactory.create(), args);
- if (cliArguments == null) {
- return;
+ 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());
}
- migrate(cliArguments);
}
- public static void migrate(MigrationCliArguments argumentParser) throws
IOException {
- MigrationOptions options = argumentParser.getOptions();
- StoreArguments stores = argumentParser.getStoreArguments();
+ 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,
closer);
+ MigrationFactory factory = new MigrationFactory(options, stores,
datastores, closer);
try {
if (stores.getSrcStore().isJcr2()) {
upgrade(factory);
@@ -61,11 +84,11 @@ public class OakUpgrade {
}
}
- private static void upgrade(MigrationFactory migrationFactory) throws
IOException, RepositoryException {
+ private static void upgrade(MigrationFactory migrationFactory) throws
IOException, RepositoryException, CliArgumentException {
migrationFactory.createUpgrade().copy(createCompositeInitializer());
}
- private static void sidegrade(MigrationFactory migrationFactory) throws
IOException, RepositoryException {
+ private static void sidegrade(MigrationFactory migrationFactory) throws
IOException, RepositoryException, CliArgumentException {
migrationFactory.createSidegrade().copy();
}
Copied:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ConstantBlobStoreFactory.java
(from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java)
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ConstantBlobStoreFactory.java?p2=jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ConstantBlobStoreFactory.java&p1=jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java&r1=1774499&r2=1774571&rev=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ConstantBlobStoreFactory.java
Fri Dec 16 11:12:53 2016
@@ -14,16 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.jackrabbit.oak.upgrade.cli.node;
+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;
-import org.apache.jackrabbit.oak.spi.blob.BlobStore;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
+public class ConstantBlobStoreFactory implements BlobStoreFactory {
-import com.google.common.io.Closer;
+ private final BlobStore blobStore;
-public interface NodeStoreFactory {
+ public ConstantBlobStoreFactory(BlobStore blobStore) {
+ this.blobStore = blobStore;
+ }
- NodeStore create(BlobStore blobStore, Closer closer) throws IOException;
+ @Override
+ public BlobStore create(Closer closer) throws IOException {
+ return blobStore;
+ }
}
Added:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStore.java?rev=1774571&view=auto
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStore.java
(added)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStore.java
Fri Dec 16 11:12:53 2016
@@ -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;
+ }
+}
Copied:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStoreFactory.java
(from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java)
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStoreFactory.java?p2=jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStoreFactory.java&p1=jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java&r1=1774499&r2=1774571&rev=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/MissingBlobStoreFactory.java
Fri Dec 16 11:12:53 2016
@@ -14,16 +14,21 @@
* 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;
+package org.apache.jackrabbit.oak.upgrade.cli.blob;
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 {
+public class MissingBlobStoreFactory implements BlobStoreFactory {
+
+ @Override
+ public BlobStore create(Closer closer) {
+ return new MissingBlobStore();
+ }
- NodeStore create(BlobStore blobStore, Closer closer) throws IOException;
+ @Override
+ public String toString() {
+ return "MissingBlobStore";
+ }
}
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java
Fri Dec 16 11:12:53 2016
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.upgrad
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;
@@ -27,6 +28,8 @@ 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 {
@@ -40,7 +43,9 @@ public class JdbcFactory implements Node
private final String password;
- public JdbcFactory(String jdbcUri, int cacheSize, String user, 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) {
@@ -48,16 +53,19 @@ public class JdbcFactory implements Node
}
this.user = user;
this.password = password;
+ this.readOnly = readOnly;
}
@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);
+ 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();
@@ -65,6 +73,28 @@ public class JdbcFactory implements Node
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);
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java
Fri Dec 16 11:12:53 2016
@@ -16,14 +16,18 @@
*/
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;
@@ -31,35 +35,60 @@ 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;
- public MongoFactory(String repoDesc, 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();
}
- 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);
+ 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();
}
- DocumentNodeStore documentNodeStore = builder.getNodeStore();
- closer.register(asCloseable(documentNodeStore));
- return documentNodeStore;
}
static Closeable asCloseable(final DocumentNodeStore documentNodeStore) {
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
Fri Dec 16 11:12:53 2016
@@ -26,4 +26,6 @@ import com.google.common.io.Closer;
public interface NodeStoreFactory {
NodeStore create(BlobStore blobStore, Closer closer) throws IOException;
+
+ boolean hasExternalBlobReferences() throws IOException;
}
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java
Fri Dec 16 11:12:53 2016
@@ -20,38 +20,112 @@ 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.SegmentNodeBuilder;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
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.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import com.google.common.io.Closer;
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
public class SegmentFactory implements NodeStoreFactory {
private final File dir;
- private final boolean mmap;
+ private final boolean disableMmap;
+
+ private final boolean readOnly;
- public SegmentFactory(String directory, boolean mmap) {
+ public SegmentFactory(String directory, boolean disableMmap, boolean
readOnly) {
this.dir = new File(directory);
- this.mmap = mmap;
+ this.disableMmap = disableMmap;
+ this.readOnly = readOnly;
+ createDirectoryIfMissing(dir);
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 {
- Builder builder = FileStore.newFileStore(new File(dir,
"segmentstore"));
- if (blobStore != null) {
- builder.withBlobStore(blobStore);
+ File directory = new File(dir, "segmentstore");
+
+ final FileStore fs;
+ if (readOnly) {
+ if (disableMmap) {
+ fs = new FileStore.ReadOnlyStore(directory, 0, false,
blobStore);
+ } else {
+ fs = new FileStore.ReadOnlyStore(directory, blobStore);
+ }
+ } else {
+ Builder builder = FileStore.newFileStore(directory);
+ if (blobStore != null) {
+ builder.withBlobStore(blobStore);
+ }
+ builder.withMaxFileSize(256);
+ if (disableMmap) {
+ builder.withMemoryMapping(false);
+ } else {
+ builder.withDefaultMemoryMapping();
+ }
+ fs = builder.create();
}
- builder.withMaxFileSize(256).withMemoryMapping(mmap);
- FileStore fs = builder.create();
closer.register(asCloseable(fs));
- return SegmentNodeStore.newSegmentNodeStore(fs).create();
+
+ return new
TarNodeStore(SegmentNodeStore.newSegmentNodeStore(fs).create(), new
TarNodeStore.SuperRootProvider() {
+ @Override
+ public void setSuperRoot(NodeBuilder builder) {
+ checkArgument(builder instanceof SegmentNodeBuilder);
+ SegmentNodeBuilder segmentBuilder = (SegmentNodeBuilder)
builder;
+ SegmentNodeState lastRoot = (SegmentNodeState) getSuperRoot();
+
+ if (!lastRoot.getRecordId().equals(((SegmentNodeState)
segmentBuilder.getBaseState()).getRecordId())) {
+ throw new IllegalArgumentException("The new head is out of
date");
+ }
+
+ fs.setHead(lastRoot, ((SegmentNodeBuilder)
builder).getNodeState());
+ }
+
+ @Override
+ public NodeState getSuperRoot() {
+ return fs.getHead();
+ }
+ });
+ }
+
+ @Override
+ public boolean hasExternalBlobReferences() throws IOException {
+ FileStore fs = new FileStore.ReadOnlyStore(new File(dir,
"segmentstore"), 0, false);
+ try {
+ fs.getTracker().collectBlobReferences(new ReferenceCollector() {
+ @Override
+ public void addReference(String reference, @Nullable String
nodeId) {
+ // 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() {
@@ -71,4 +145,7 @@ public class SegmentFactory implements N
public String toString() {
return String.format("SegmentNodeStore[%s]", dir);
}
+
+ private static class ExternalBlobFound extends RuntimeException {
+ }
}
Modified:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java
Fri Dec 16 11:12:53 2016
@@ -59,4 +59,12 @@ public class StoreFactory {
public boolean isJcr2() {
return jcr2Factory != null;
}
+
+ public boolean hasExternalBlobReferences() throws IOException {
+ if (isJcr2()) {
+ return true;
+ } else {
+ return nodeStoreFactory.hasExternalBlobReferences();
+ }
+ }
}
Copied:
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java
(from r1774499,
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java)
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java?p2=jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java&p1=jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java&r1=1774499&r2=1774571&rev=1774571&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/TarNodeStore.java
Fri Dec 16 11:12:53 2016
@@ -16,14 +16,40 @@
*/
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.NodeBuilder;
+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 void setSuperRoot(NodeBuilder builder) {
+ superRootProvider.setSuperRoot(builder);
+ }
+
+ public NodeState getSuperRoot() {
+ return superRootProvider.getSuperRoot();
+ }
+
+ @Override
+ protected NodeStore getNodeStore() {
+ return ns;
+ }
+
+ interface SuperRootProvider {
-import com.google.common.io.Closer;
+ void setSuperRoot(NodeBuilder builder);
-public interface NodeStoreFactory {
+ NodeState getSuperRoot();
- NodeStore create(BlobStore blobStore, Closer closer) throws IOException;
+ }
}