/*
* Copyright (C) 2003-2010 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.services.jcr.ext.backup.usecase;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.container.xml.PropertiesParam;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.SimpleParameterEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.core.WorkspaceContainerFacade;
import org.exoplatform.services.jcr.ext.backup.BackupChain;
import org.exoplatform.services.jcr.ext.backup.BackupChainLog;
import org.exoplatform.services.jcr.ext.backup.BackupConfig;
import org.exoplatform.services.jcr.ext.backup.BackupJob;
import org.exoplatform.services.jcr.ext.backup.BackupManager;
import org.exoplatform.services.jcr.ext.backup.ExtendedBackupManager;
import org.exoplatform.services.jcr.ext.backup.RepositoryBackupChain;
import org.exoplatform.services.jcr.ext.backup.RepositoryBackupChainLog;
import org.exoplatform.services.jcr.ext.backup.RepositoryBackupConfig;
import org.exoplatform.services.jcr.ext.backup.impl.BackupManagerImpl;
import org.exoplatform.services.jcr.ext.backup.impl.JobExistingRepositoryRestore;
import org.exoplatform.services.jcr.ext.backup.impl.JobExistingRepositorySameConfigRestore;
import org.exoplatform.services.jcr.ext.backup.impl.JobExistingWorkspaceRestore;
import org.exoplatform.services.jcr.ext.backup.impl.JobExistingWorkspaceSameConfigRestore;
import org.exoplatform.services.jcr.ext.backup.impl.JobRepositoryRestore;
import org.exoplatform.services.jcr.ext.backup.impl.JobWorkspaceRestore;
import org.exoplatform.services.jcr.impl.backup.Backupable;
import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanException;
import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanerTool;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
import org.exoplatform.services.jcr.impl.core.SessionRegistry;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCDataContainerConfig.DatabaseStructureType;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerHelper;
import org.exoplatform.services.jcr.util.IdGenerator;
import org.exoplatform.services.jcr.util.TesterConfigurationHelper;
import java.io.File;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.naming.InitialContext;
import javax.sql.DataSource;
/**
* Created by The eXo Platform SAS.
*
* <br>Date:
*
* @author <a href="karpenko.sergiy@gmail.com">Karpenko Sergiy</a>
* @version $Id: TestLoadBackup.java 111 2008-11-11 11:11:11Z serg $
*/
public class TestBackupRestore extends BaseStandaloneBackupRestoreTest
{
private static final String NODE_NAME = "My Node \"with a '\"";
private static final String PROPERTY_NAME = "My Property \"with a '\"";
public static int index = 0;
public void testBackupRestoreExistingRepositorySingleDB() throws Exception
{
repositoryBackupRestore("db3");
repositoryBackupRestore("db3");
}
public void testBackupRestoreExistingRepositoryMultiDB() throws Exception
{
repositoryBackupRestore("db4");
repositoryBackupRestore("db4");
repositoryBackupRestore("db8");
repositoryBackupRestore("db8");
}
public void testBackupRestoreExistingWorkspaceSingleDB() throws Exception
{
workspaceBackupRestore("db3");
workspaceBackupRestore("db3");
}
public void testBackupRestoreExistingWorkspaceMultiDB() throws Exception
{
workspaceBackupRestore("db4");
workspaceBackupRestore("db4");
workspaceBackupRestore("db8");
workspaceBackupRestore("db8");
}
public void testJobExistingRepositorySameConfigRestoreSingleDB() throws Exception
{
repositoryBackupRestoreDirectlyOverJobExistingRepositorySameConfigRestore("db3");
repositoryBackupRestoreDirectlyOverJobExistingRepositorySameConfigRestore("db3");
}
public void testJobExistingRepositorySameConfigRestoreMultiDB() throws Exception
{
repositoryBackupRestoreDirectlyOverJobExistingRepositorySameConfigRestore("db4");
repositoryBackupRestoreDirectlyOverJobExistingRepositorySameConfigRestore("db4");
repositoryBackupRestoreDirectlyOverJobExistingRepositorySameConfigRestore("db8");
repositoryBackupRestoreDirectlyOverJobExistingRepositorySameConfigRestore("db8");
}
public void testJobExistingRepositoryRestoreSingleDB() throws Exception
{
repositoryBackupRestoreDirectlyOverJobExistingRepositoryRestore("db3");
repositoryBackupRestoreDirectlyOverJobExistingRepositoryRestore("db3");
}
public void testJobExistingRepositoryRestoreMultiDB() throws Exception
{
repositoryBackupRestoreDirectlyOverJobExistingRepositoryRestore("db4");
repositoryBackupRestoreDirectlyOverJobExistingRepositoryRestore("db4");
repositoryBackupRestoreDirectlyOverJobExistingRepositoryRestore("db8");
repositoryBackupRestoreDirectlyOverJobExistingRepositoryRestore("db8");
}
public void testJobRepositoryRestoreSingleDB() throws Exception
{
repositoryBackupRestoreDirectlyOverJobRepositoryRestore("db3");
repositoryBackupRestoreDirectlyOverJobRepositoryRestore("db3");
}
public void testJobRepositoryRestoreMultiDB() throws Exception
{
repositoryBackupRestoreDirectlyOverJobRepositoryRestore("db4");
repositoryBackupRestoreDirectlyOverJobRepositoryRestore("db4");
repositoryBackupRestoreDirectlyOverJobRepositoryRestore("db8");
repositoryBackupRestoreDirectlyOverJobRepositoryRestore("db8");
}
public void testJobExistingWorkspaceSameConfigRestoreSingleDB() throws Exception
{
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceSameConfigRestore("db3");
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceSameConfigRestore("db3");
}
public void testJobExistingWorkspaceSameConfigRestoreMultiDB() throws Exception
{
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceSameConfigRestore("db4");
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceSameConfigRestore("db4");
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceSameConfigRestore("db8");
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceSameConfigRestore("db8");
}
public void testJobExistingWorkspaceRestoreSingleDB() throws Exception
{
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceRestore("db3");
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceRestore("db3");
}
public void testJobExistingWorkspaceRestoreMultiDB() throws Exception
{
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceRestore("db4");
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceRestore("db4");
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceRestore("db8");
workspaceBackupRestoreDirectlyOverJobExistingWorkspaceRestore("db8");
}
public void testJobWorkspaceRestoreSingleDB() throws Exception
{
workspaceBackupRestoreDirectlyOverJobWorkspaceRestore("db3");
workspaceBackupRestoreDirectlyOverJobWorkspaceRestore("db3");
}
public void testJobWorkspaceRestoreMultiDB() throws Exception
{
workspaceBackupRestoreDirectlyOverJobWorkspaceRestore("db4");
workspaceBackupRestoreDirectlyOverJobWorkspaceRestore("db4");
workspaceBackupRestoreDirectlyOverJobWorkspaceRestore("db8");
workspaceBackupRestoreDirectlyOverJobWorkspaceRestore("db8");
}
public void testRepositoryFullBackupRestoreBackupSingleDBToIsolatedOnIsolated() throws Exception
{
repositoryFullBackupRestoreBackupSingleToIsolatedOnIsolated("db3");
repositoryFullBackupRestoreBackupSingleToIsolatedOnIsolated("db3");
}
protected void repositoryFullBackupRestoreBackupSingleToIsolatedOnIsolated(String repositoryName) throws Exception
{
// prepare
addConent(repositoryName);
BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
backupManagerImpl.start();
// backup
File backDir = new File("target/backup/" + IdGenerator.generate());
backDir.mkdirs();
RepositoryBackupConfig config = new RepositoryBackupConfig();
config.setRepository(repositoryName);
config.setBackupType(BackupManager.FULL_BACKUP_ONLY);
config.setBackupDir(backDir);
RepositoryBackupChain bch = backupManagerImpl.startBackup(config);
// wait till full backup will stop
while (bch.getState() != BackupJob.FINISHED)
{
Thread.yield();
Thread.sleep(30);
}
if (bch != null)
{
backupManagerImpl.stopBackup(bch);
}
TesterConfigurationHelper helper = TesterConfigurationHelper.getInstance();
RepositoryEntry repositoryEntryIsolated = helper.copyRepositoryEntry(repositoryService.getRepository(repositoryName).getConfiguration());
for (WorkspaceEntry we : repositoryEntryIsolated.getWorkspaceEntries())
{
we.getContainer().addParameter(
new SimpleParameterEntry(JDBCWorkspaceDataContainer.DB_STRUCTURE_TYPE, DatabaseStructureType.ISOLATED
.toString()));
}
// restore single backup on structure single to isolated
{
RepositoryEntry newRE = helper.copyRepositoryEntry(repositoryEntryIsolated);
File backLog = new File(bch.getLogFilePath());
assertTrue(backLog.exists());
RepositoryBackupChainLog bchLog = new RepositoryBackupChainLog(backLog);
backupManagerImpl.restoreExistingRepository(bchLog, newRE, false);
checkConent(newRE.getName());
String dbStructureType = repositoryService.getRepository(repositoryName).getConfiguration().getWorkspaceEntries().get(0).getContainer().getParameterValue(JDBCWorkspaceDataContainer.DB_STRUCTURE_TYPE);
assertTrue(DatabaseStructureType.ISOLATED.toString().equalsIgnoreCase(dbStructureType));
}
// restore single backup on structure isolated to isolated
{
RepositoryEntry newRE = helper.copyRepositoryEntry(repositoryEntryIsolated);
File backLog = new File(bch.getLogFilePath());
assertTrue(backLog.exists());
RepositoryBackupChainLog bchLog = new RepositoryBackupChainLog(backLog);
backupManagerImpl.restoreExistingRepository(bchLog, newRE, false);
checkConent(newRE.getName());
String dbStructureType = repositoryService.getRepository(repositoryName).getConfiguration().getWorkspaceEntries().get(0).getContainer().getParameterValue(JDBCWorkspaceDataContainer.DB_STRUCTURE_TYPE);
assertTrue(DatabaseStructureType.ISOLATED.toString().equalsIgnoreCase(dbStructureType));
}
// revert the single structure in repository
{
File backLog = new File(bch.getLogFilePath());
assertTrue(backLog.exists());
RepositoryBackupChainLog bchLog = new RepositoryBackupChainLog(backLog);
backupManagerImpl.restoreExistingRepository(bchLog.getBackupId(), false);
checkConent(repositoryName);
String dbStructureType = repositoryService.getRepository(repositoryName).getConfiguration().getWorkspaceEntries().get(0).getContainer().getParameterValue(JDBCWorkspaceDataContainer.DB_STRUCTURE_TYPE);
assertTrue(DatabaseStructureType.SINGLE.toString().equalsIgnoreCase(dbStructureType));
}
}
protected void repositoryBackupRestoreDirectlyOverJobExistingRepositorySameConfigRestore(String repositoryName)
throws Exception
{
addConent(repositoryName);
BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
backupManagerImpl.start();
File backDir = new File("target/backup/" + repositoryName);
backDir.mkdirs();
RepositoryBackupConfig config = new RepositoryBackupConfig();
config.setRepository(repositoryName);
config.setBackupType(BackupManager.FULL_BACKUP_ONLY);
config.setBackupDir(backDir);
RepositoryBackupChain bch = backupManagerImpl.startBackup(config);
// wait till full backup will stop
while (bch.getState() != BackupJob.FINISHED)
{
Thread.yield();
Thread.sleep(30);
}
if (bch != null)
{
backupManagerImpl.stopBackup(bch);
}
// restore
RepositoryBackupChainLog rblog = new RepositoryBackupChainLog(new File(bch.getLogFilePath()));
Map<String, File> workspacesMapping = new HashMap<String, File>();
Map<String, BackupChainLog> backups = new HashMap<String, BackupChainLog>();
for (String path : rblog.getWorkspaceBackupsInfo())
{
BackupChainLog bLog = new BackupChainLog(new File(path));
backups.put(bLog.getBackupConfig().getWorkspace(), bLog);
}
for (WorkspaceEntry wsEntry : rblog.getOriginalRepositoryEntry().getWorkspaceEntries())
{
workspacesMapping.put(wsEntry.getName(), new File(backups.get(wsEntry.getName()).getLogFilePath()));
}
JobExistingRepositorySameConfigRestore job =
new JobExistingRepositorySameConfigRestore(repositoryService, backupManagerImpl, rblog
.getOriginalRepositoryEntry(), workspacesMapping, new File(rblog.getLogFilePath()));
job.run();
assertEquals(JobRepositoryRestore.REPOSITORY_RESTORE_SUCCESSFUL, job.getStateRestore());
checkConent(repositoryName);
}
protected void repositoryBackupRestoreDirectlyOverJobExistingRepositoryRestore(String repositoryName)
throws Exception
{
addConent(repositoryName);
BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
backupManagerImpl.start();
File backDir = new File("target/backup/" + repositoryName);
backDir.mkdirs();
RepositoryBackupConfig config = new RepositoryBackupConfig();
config.setRepository(repositoryName);
config.setBackupType(BackupManager.FULL_BACKUP_ONLY);
config.setBackupDir(backDir);
RepositoryBackupChain bch = backupManagerImpl.startBackup(config);
// wait till full backup will stop
while (bch.getState() != BackupJob.FINISHED)
{
Thread.yield();
Thread.sleep(30);
}
if (bch != null)
{
backupManagerImpl.stopBackup(bch);
}
// restore
RepositoryBackupChainLog rblog = new RepositoryBackupChainLog(new File(bch.getLogFilePath()));
Map<String, File> workspacesMapping = new HashMap<String, File>();
Map<String, BackupChainLog> backups = new HashMap<String, BackupChainLog>();
for (String path : rblog.getWorkspaceBackupsInfo())
{
BackupChainLog bLog = new BackupChainLog(new File(path));
backups.put(bLog.getBackupConfig().getWorkspace(), bLog);
}
for (WorkspaceEntry wsEntry : rblog.getOriginalRepositoryEntry().getWorkspaceEntries())
{
workspacesMapping.put(wsEntry.getName(), new File(backups.get(wsEntry.getName()).getLogFilePath()));
}
JobExistingRepositoryRestore job =
new JobExistingRepositoryRestore(repositoryService, backupManagerImpl, rblog.getOriginalRepositoryEntry(),
workspacesMapping, new File(rblog.getLogFilePath()));
job.run();
assertEquals(JobRepositoryRestore.REPOSITORY_RESTORE_SUCCESSFUL, job.getStateRestore());
checkConent(repositoryName);
}
private int forceCloseSession(String repositoryName, String workspaceName) throws RepositoryException,
RepositoryConfigurationException
{
ManageableRepository mr = repositoryService.getRepository(repositoryName);
WorkspaceContainerFacade wc = mr.getWorkspaceContainer(workspaceName);
SessionRegistry sessionRegistry = (SessionRegistry)wc.getComponent(SessionRegistry.class);
return sessionRegistry.closeSessions(workspaceName);
}
protected void repositoryBackupRestoreDirectlyOverJobRepositoryRestore(String repositoryName)
throws Exception
{
addConent(repositoryName);
BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
backupManagerImpl.start();
File backDir = new File("target/backup/" + repositoryName);
backDir.mkdirs();
RepositoryBackupConfig config = new RepositoryBackupConfig();
config.setRepository(repositoryName);
config.setBackupType(BackupManager.FULL_BACKUP_ONLY);
config.setBackupDir(backDir);
RepositoryBackupChain bch = backupManagerImpl.startBackup(config);
// wait till full backup will stop
while (bch.getState() != BackupJob.FINISHED)
{
Thread.yield();
Thread.sleep(30);
}
if (bch != null)
{
backupManagerImpl.stopBackup(bch);
}
// restore
RepositoryBackupChainLog rblog = new RepositoryBackupChainLog(new File(bch.getLogFilePath()));
// clean existing repository
// list of components to clean
List<Backupable> backupable = new ArrayList<Backupable>();
//Create local copy of WorkspaceEntry for all workspaces
ArrayList<WorkspaceEntry> workspaceList = new ArrayList<WorkspaceEntry>();
workspaceList.addAll(rblog.getOriginalRepositoryEntry().getWorkspaceEntries());
// get all backupable components
for (WorkspaceEntry wEntry : workspaceList)
{
backupable.addAll(repositoryService.getRepository(rblog.getOriginalRepositoryEntry().getName())
.getWorkspaceContainer(wEntry.getName()).getComponentInstancesOfType(Backupable.class));
}
//close all session
for (WorkspaceEntry wEntry : workspaceList)
{
forceCloseSession(rblog.getOriginalRepositoryEntry().getName(), wEntry.getName());
}
//remove repository
repositoryService.removeRepository(rblog.getOriginalRepositoryEntry().getName());
// clean
for (Backupable component : backupable)
{
component.clean();
}
Map<String, File> workspacesMapping = new HashMap<String, File>();
Map<String, BackupChainLog> backups = new HashMap<String, BackupChainLog>();
for (String path : rblog.getWorkspaceBackupsInfo())
{
BackupChainLog bLog = new BackupChainLog(new File(path));
backups.put(bLog.getBackupConfig().getWorkspace(), bLog);
}
for (WorkspaceEntry wsEntry : rblog.getOriginalRepositoryEntry().getWorkspaceEntries())
{
workspacesMapping.put(wsEntry.getName(), new File(backups.get(wsEntry.getName()).getLogFilePath()));
}
JobRepositoryRestore job =
new JobRepositoryRestore(repositoryService, backupManagerImpl, rblog.getOriginalRepositoryEntry(),
workspacesMapping, new File(rblog.getLogFilePath()), false);
job.run();
assertEquals(JobRepositoryRestore.REPOSITORY_RESTORE_SUCCESSFUL, job.getStateRestore());
checkConent(repositoryName);
}
protected void workspaceBackupRestore(String repositoryName) throws Exception
{
addConent(repositoryName);
String workspaceName =
repositoryService.getRepository(repositoryName).getConfiguration().getSystemWorkspaceName();
WorkspaceEntry wsEntry = null;
for (WorkspaceEntry entry : repositoryService.getRepository(repositoryName).getConfiguration()
.getWorkspaceEntries())
{
if (entry.getName().equals(workspaceName))
{
wsEntry = entry;
break;
}
}
BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
backupManagerImpl.start();
File backDir = new File("target/backup/" + repositoryName);
backDir.mkdirs();
BackupConfig config = new BackupConfig();
config.setRepository(repositoryName);
config.setWorkspace(workspaceName);
config.setBackupType(BackupManager.FULL_BACKUP_ONLY);
config.setBackupDir(backDir);
BackupChain bch = backupManagerImpl.startBackup(config);
// wait till full backup will stop
while (bch.getFullBackupState() != BackupChain.FINISHED)
{
Thread.yield();
Thread.sleep(30);
}
if (bch != null)
{
backupManagerImpl.stopBackup(bch);
}
// restore
File backLog = new File(bch.getLogFilePath());
if (backLog.exists())
{
BackupChainLog bchLog = new BackupChainLog(backLog);
assertNotNull(bchLog.getStartedTime());
assertNotNull(bchLog.getFinishedTime());
backupManagerImpl.restoreExistingWorkspace(bchLog, repositoryName, wsEntry, false);
JobWorkspaceRestore restore = backupManagerImpl.getLastRestore(repositoryName, workspaceName);
assertNotNull(restore);
}
else
{
fail("There are no backup files in " + backDir.getAbsolutePath());
}
checkConent(repositoryName);
}
protected void workspaceBackupRestoreDirectlyOverJobExistingWorkspaceSameConfigRestore(String repositoryName)
throws Exception
{
addConent(repositoryName);
String workspaceName =
repositoryService.getRepository(repositoryName).getConfiguration().getSystemWorkspaceName();
WorkspaceEntry wsEntry = null;
for (WorkspaceEntry entry : repositoryService.getRepository(repositoryName).getConfiguration()
.getWorkspaceEntries())
{
if (entry.getName().equals(workspaceName))
{
wsEntry = entry;
break;
}
}
BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
backupManagerImpl.start();
File backDir = new File("target/backup/" + repositoryName);
backDir.mkdirs();
BackupConfig config = new BackupConfig();
config.setRepository(repositoryName);
config.setWorkspace(workspaceName);
config.setBackupType(BackupManager.FULL_BACKUP_ONLY);
config.setBackupDir(backDir);
BackupChain bch = backupManagerImpl.startBackup(config);
// wait till full backup will stop
while (bch.getFullBackupState() != BackupChain.FINISHED)
{
Thread.yield();
Thread.sleep(30);
}
if (bch != null)
{
backupManagerImpl.stopBackup(bch);
}
// restore
BackupChainLog bclog = new BackupChainLog(new File(bch.getLogFilePath()));
JobExistingWorkspaceSameConfigRestore job =
new JobExistingWorkspaceSameConfigRestore(repositoryService, backupManagerImpl, repositoryName, new File(bclog.getLogFilePath()), bclog
.getOriginalWorkspaceEntry());
job.run();
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, job.getStateRestore());
checkConent(repositoryName);
}
/**
* JobExistingWorkspaseRrestore is not support restore system workspace,
* because repository is not allowed removing system workspace.
*/
protected void workspaceBackupRestoreDirectlyOverJobExistingWorkspaceRestore(String repositoryName) throws Exception
{
addConent(repositoryName);
WorkspaceEntry wsEntry = null;
for (WorkspaceEntry entry : repositoryService.getRepository(repositoryName).getConfiguration()
.getWorkspaceEntries())
{
if (!entry.getName().equals(
repositoryService.getRepository(repositoryName).getConfiguration().getSystemWorkspaceName()))
{
wsEntry = entry;
break;
}
}
BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
backupManagerImpl.start();
File backDir = new File("target/backup/" + repositoryName);
backDir.mkdirs();
BackupConfig config = new BackupConfig();
config.setRepository(repositoryName);
config.setWorkspace(wsEntry.getName());
config.setBackupType(BackupManager.FULL_BACKUP_ONLY);
config.setBackupDir(backDir);
BackupChain bch = backupManagerImpl.startBackup(config);
// wait till full backup will stop
while (bch.getFullBackupState() != BackupChain.FINISHED)
{
Thread.yield();
Thread.sleep(30);
}
if (bch != null)
{
backupManagerImpl.stopBackup(bch);
}
// restore
BackupChainLog bclog = new BackupChainLog(new File(bch.getLogFilePath()));
JobExistingWorkspaceRestore job =
new JobExistingWorkspaceRestore(repositoryService, backupManagerImpl, repositoryName, new File(bclog.getLogFilePath()), bclog
.getOriginalWorkspaceEntry());
job.run();
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, job.getStateRestore());
checkConent(repositoryName);
}
/**
* JobWorkspaseRrestore is not support restore system workspace,
* because repository is not allowed removing system workspace.
*/
protected void workspaceBackupRestoreDirectlyOverJobWorkspaceRestore(String repositoryName)
throws Exception
{
addConent(repositoryName);
WorkspaceEntry wsEntry = null;
for (WorkspaceEntry entry : repositoryService.getRepository(repositoryName).getConfiguration()
.getWorkspaceEntries())
{
if (!entry.getName().equals(
repositoryService.getRepository(repositoryName).getConfiguration().getSystemWorkspaceName()))
{
wsEntry = entry;
break;
}
}
String workspaceName = wsEntry.getName();
BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
backupManagerImpl.start();
File backDir = new File("target/backup/" + repositoryName);
backDir.mkdirs();
BackupConfig config = new BackupConfig();
config.setRepository(repositoryName);
config.setWorkspace(workspaceName);
config.setBackupType(BackupManager.FULL_BACKUP_ONLY);
config.setBackupDir(backDir);
BackupChain bch = backupManagerImpl.startBackup(config);
// wait till full backup will stop
while (bch.getFullBackupState() != BackupChain.FINISHED)
{
Thread.yield();
Thread.sleep(30);
}
if (bch != null)
{
backupManagerImpl.stopBackup(bch);
}
// clean existed workspace
// get all backupable components
List<Backupable> backupable =
repositoryService.getRepository(repositoryName).getWorkspaceContainer(wsEntry.getName())
.getComponentInstancesOfType(Backupable.class);
// close all session
forceCloseSession(repositoryName, wsEntry.getName());
repositoryService.getRepository(repositoryName).removeWorkspace(wsEntry.getName());
// clean
for (Backupable component : backupable)
{
component.clean();
}
// restore
BackupChainLog bclog = new BackupChainLog(new File(bch.getLogFilePath()));
JobWorkspaceRestore job =
new JobWorkspaceRestore(repositoryService, backupManagerImpl, repositoryName, new File(bclog.getLogFilePath()), bclog
.getOriginalWorkspaceEntry());
job.run();
assertEquals(JobWorkspaceRestore.RESTORE_SUCCESSFUL, job.getStateRestore());
checkConent(repositoryName);
}
protected void repositoryBackupRestore(String repositoryName) throws Exception
{
// prepare content
addConent(repositoryName);
// prepare backupManager
BackupManagerImpl backupManagerImpl = (BackupManagerImpl)getBackupManager();
backupManagerImpl.start();
// backup
File backDir = new File("target/backup/" + repositoryName);
backDir.mkdirs();
RepositoryBackupConfig config = new RepositoryBackupConfig();
config.setRepository(repositoryName);
config.setBackupType(BackupManager.FULL_BACKUP_ONLY);
config.setBackupDir(backDir);
RepositoryBackupChain bch = backupManagerImpl.startBackup(config);
// wait end of backup
while (bch.getState() != BackupJob.FINISHED)
{
Thread.yield();
Thread.sleep(30);
}
if (bch != null)
{
backupManagerImpl.stopBackup(bch);
}
// clean repository via DBCleanService
DBCleanService.cleanRepositoryData(repositoryService.getRepository(repositoryName).getConfiguration());
checkEmptyTables(repositoryName);
// restore
restore(repositoryName, bch, backupManagerImpl);
checkConent(repositoryName);
// clean every workspace via DBCleanService
ManageableRepository repository = repositoryService.getRepository(repositoryName);
for (WorkspaceEntry wsEntry : repository.getConfiguration().getWorkspaceEntries())
{
DBCleanService.cleanWorkspaceData(wsEntry);
}
checkEmptyTables(repositoryName);
// restore
restore(repositoryName, bch, backupManagerImpl);
checkConent(repositoryName);
// clean again via DBCleaner
repository = repositoryService.getRepository(repositoryName);
WorkspaceEntry entry = repository.getConfiguration().getWorkspaceEntries().get(0);
DataSource ds =
(DataSource)new InitialContext().lookup(entry.getContainer().getParameterValue(
JDBCWorkspaceDataContainer.SOURCE_NAME));
Connection conn = ds.getConnection();
conn.setAutoCommit(false);
try
{
if (repositoryName.equals("db3"))
{
DBCleanerTool repositoryDBCleaner =
DBCleanService.getRepositoryDBCleaner(conn, repository.getConfiguration());
// clean and rollback first
repositoryDBCleaner.clean();
conn.rollback();
repositoryDBCleaner.rollback();
conn.commit();
checkConent(repositoryName);
// clean
repositoryDBCleaner.clean();
repositoryDBCleaner.commit();
conn.commit();
}
else
{
try
{
DBCleanerTool repositoryDBCleaner =
DBCleanService.getRepositoryDBCleaner(conn, repository.getConfiguration());
fail("Exception should be thrown");
}
catch (DBCleanException e)
{
}
}
}
finally
{
conn.close();
}
if (repositoryName.equals("db3"))
{
checkEmptyTables(repositoryName);
}
// restore
restore(repositoryName, bch, backupManagerImpl);
checkConent(repositoryName);
// clean every workspace again via DBCleaner
repository = repositoryService.getRepository(repositoryName);
for (WorkspaceEntry wsEntry : repository.getConfiguration().getWorkspaceEntries())
{
ds =
(DataSource)new InitialContext().lookup(wsEntry.getContainer().getParameterValue(
JDBCWorkspaceDataContainer.SOURCE_NAME));
conn = ds.getConnection();
conn.setAutoCommit(false);
DBCleanerTool workspaceDBCleaner = DBCleanService.getWorkspaceDBCleaner(conn, wsEntry);
try
{
// clean and rollback first
workspaceDBCleaner.clean();
conn.rollback();
workspaceDBCleaner.rollback();
conn.commit();
checkConent(repositoryName);
// clean
workspaceDBCleaner.clean();
workspaceDBCleaner.commit();
conn.commit();
}
finally
{
conn.close();
}
}
checkEmptyTables(repositoryName);
// restore
restore(repositoryName, bch, backupManagerImpl);
checkConent(repositoryName);
}
protected ExtendedBackupManager getBackupManager()
{
InitParams initParams = new InitParams();
PropertiesParam pps = new PropertiesParam();
pps.setProperty(BackupManagerImpl.FULL_BACKUP_TYPE,
"org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob");
pps.setProperty(BackupManagerImpl.BACKUP_DIR, "target/backup");
initParams.put(BackupManagerImpl.BACKUP_PROPERTIES, pps);
return new BackupManagerImpl(initParams, repositoryService);
}
protected void addConent(String repositoryName) throws Exception
{
index++;
ManageableRepository repository = repositoryService.getRepository(repositoryName);
for (String wsName : repository.getWorkspaceNames())
{
SessionImpl session = (SessionImpl)repository.login(credentials, wsName);
try
{
Node rootNode = session.getRootNode().addNode("test" + index);
rootNode.addNode("node1").setProperty("prop1", "value1");
rootNode.addNode(NODE_NAME).setProperty(PROPERTY_NAME, "value1");
session.save();
}
finally
{
session.logout();
}
}
}
protected void checkConent(String repositoryName) throws Exception
{
ManageableRepository repository = repositoryService.getRepository(repositoryName);
for (String wsName : repository.getWorkspaceNames())
{
SessionImpl session = (SessionImpl)repository.login(credentials, wsName);
try
{
Node rootNode = session.getRootNode().getNode("test" + index);
assertEquals(rootNode.getNode("node1").getProperty("prop1").getString(), "value1");
assertEquals(rootNode.getNode(NODE_NAME).getProperty(PROPERTY_NAME).getString(), "value1");
}
finally
{
session.logout();
}
}
}
private void restore(String repositoryName, RepositoryBackupChain bch, BackupManagerImpl backupManagerImpl)
throws Exception
{
// restore
File backLog = new File(bch.getLogFilePath());
assertTrue(backLog.exists());
RepositoryBackupChainLog bchLog = new RepositoryBackupChainLog(backLog);
assertNotNull(bchLog.getStartedTime());
assertNotNull(bchLog.getFinishedTime());
backupManagerImpl.restoreExistingRepository(bchLog, repositoryService.getRepository(repositoryName)
.getConfiguration(), false);
JobRepositoryRestore restore = backupManagerImpl.getLastRepositoryRestore(repositoryName);
if (restore != null)
{
if (restore.getStateRestore() != JobRepositoryRestore.REPOSITORY_RESTORE_SUCCESSFUL)
{
fail(restore.getRestoreException().getMessage());
}
}
}
private void checkEmptyTables(String repositoryName) throws Exception
{
ManageableRepository repository = repositoryService.getRepository(repositoryName);
for (WorkspaceEntry wsEntry : repository.getConfiguration().getWorkspaceEntries())
{
String itemTableName = DBInitializerHelper.getItemTableName(wsEntry);
String valueTableName = DBInitializerHelper.getValueTableName(wsEntry);
String refTableName = DBInitializerHelper.getRefTableName(wsEntry);
DataSource ds =
(DataSource)new InitialContext().lookup(wsEntry.getContainer().getParameterValue(
JDBCWorkspaceDataContainer.SOURCE_NAME));
Connection conn = ds.getConnection();
try
{
ResultSet result = conn.createStatement().executeQuery("SELECT COUNT(*) FROM " + itemTableName);
try
{
assertTrue(result.next());
assertEquals(1, result.getInt(1));
}
finally
{
result.close();
}
result = conn.createStatement().executeQuery("SELECT COUNT(*) FROM " + valueTableName);
try
{
assertTrue(result.next());
assertEquals(0, result.getInt(1));
}
finally
{
result.close();
}
result = conn.createStatement().executeQuery("SELECT COUNT(*) FROM " + refTableName);
try
{
assertTrue(result.next());
assertEquals(0, result.getInt(1));
}
finally
{
result.close();
}
}
finally
{
conn.close();
}
}
}
}