in oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgrade.java [395:558]
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 =
source.getRepositoryConfig().getDefaultWorkspaceName();
SecurityProvider security = SecurityProviderBuilder.newBuilder()
.with(mapSecurityConfig(config.getSecurityConfig())).build();
if (skipInitialization) {
logger.info("Skipping the repository initialization");
} else {
// init target repository first
logger.info("Initializing initial repository content from {}", config.getHomeDir());
new InitialContent().initialize(targetBuilder);
if (initializer != null) {
initializer.initialize(targetBuilder);
}
logger.debug("InitialContent completed from {}", config.getHomeDir());
for (SecurityConfiguration sc : security.getConfigurations()) {
RepositoryInitializer ri = sc.getRepositoryInitializer();
ri.initialize(targetBuilder);
logger.debug("Repository initializer '" + ri.getClass().getName() + "' completed", config.getHomeDir());
}
for (SecurityConfiguration sc : security.getConfigurations()) {
WorkspaceInitializer wi = sc.getWorkspaceInitializer();
wi.initialize(targetBuilder, workspaceName);
logger.debug("Workspace initializer '" + wi.getClass().getName() + "' completed", config.getHomeDir());
}
}
Map<String, String> uriToPrefix = new DualHashBidiMap<>();
logger.info("Copying registered namespaces");
copyNamespaces(targetBuilder, uriToPrefix);
logger.debug("Namespace registration completed.");
if (skipInitialization) {
logger.info("Skipping registering node types and privileges");
} else {
logger.info("Copying registered node types");
NodeTypeManager ntMgr = new ReadWriteNodeTypeManager() {
@NotNull
@Override
protected Tree getTypes() {
return upgradeRoot.getTree(NODE_TYPES_PATH);
}
@NotNull
@Override
protected Root getWriteRoot() {
return upgradeRoot;
}
};
copyNodeTypes(ntMgr, new ValueFactoryImpl(upgradeRoot, NamePathMapper.DEFAULT));
logger.debug("Node type registration completed.");
// migrate privileges
logger.info("Copying registered privileges");
PrivilegeConfiguration privilegeConfiguration = security.getConfiguration(PrivilegeConfiguration.class);
copyCustomPrivileges(privilegeConfiguration.getPrivilegeManager(upgradeRoot, NamePathMapper.DEFAULT));
logger.debug("Privilege registration completed.");
// Triggers compilation of type information, which we need for
// the type predicates used by the bulk copy operations below.
new TypeEditorProvider(false).getRootEditor(
targetBuilder.getBaseState(), targetBuilder.getNodeState(), targetBuilder, null);
}
final NodeState reportingSourceRoot = ReportingNodeState.wrap(
JackrabbitNodeState.createRootNodeState(
source, workspaceName, targetBuilder.getNodeState(),
uriToPrefix, copyBinariesByReference, skipOnError
),
new LoggingReporter(logger, "Migrating", LOG_NODE_COPY, -1)
);
final NodeState sourceRoot;
if (filterLongNames) {
sourceRoot = NameFilteringNodeState.wrapRoot(reportingSourceRoot);
} else {
sourceRoot = reportingSourceRoot;
}
final Stopwatch watch = Stopwatch.createStarted();
logger.info("Copying workspace content");
copyWorkspace(sourceRoot, targetBuilder, workspaceName);
targetBuilder.getNodeState(); // on TarMK this does call triggers the actual copy
logger.info("Upgrading workspace content completed in {}s ({})", watch.elapsed(TimeUnit.SECONDS), watch);
if (!versionCopyConfiguration.skipOrphanedVersionsCopy()) {
logger.info("Copying version storage");
watch.reset().start();
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 {
logger.info("Skipping the version storage as the copyOrphanedVersions is set to false");
}
watch.reset().start();
logger.info("Applying default commit hooks");
// TODO: default hooks?
List<CommitHook> hooks = new ArrayList<>();
UserConfiguration userConf =
security.getConfiguration(UserConfiguration.class);
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(
new RestrictionEditorProvider(),
new GroupEditorProvider(groupsPath),
// copy referenced version histories
new VersionableEditor.Provider(sourceRoot, workspaceName, versionCopyConfiguration),
new SameNameSiblingsEditor.Provider(),
AuthorizableFolderEditor.provider(groupsPath, usersPath)
)));
// this editor works on the VersionableEditor output, so it can't be
// a part of the same EditorHook
hooks.add(new EditorHook(new VersionablePropertiesEditor.Provider()));
// security-related hooks
for (SecurityConfiguration sc : security.getConfigurations()) {
hooks.addAll(sc.getCommitHooks(workspaceName));
}
if (customCommitHooks != null) {
hooks.addAll(customCommitHooks);
}
// type validation, reference and indexing hooks
hooks.add(new EditorHook(new CompositeEditorProvider(
createTypeEditorProvider(),
createIndexEditorProvider()
)));
target.merge(targetBuilder, new LoggingCompositeHook(hooks, source, overrideEarlyShutdown()), CommitInfo.EMPTY);
logger.info("Processing commit hooks completed in {}s ({})", watch.elapsed(TimeUnit.SECONDS), watch);
removeVersions();
logger.debug("Repository upgrade completed.");
} catch (Exception e) {
throw new RepositoryException("Failed to copy content", e);
}
}