private static void BackupOrRestore(bool isBackup, ConfigPair storageConfig, ConfigPair databaseConfig, List <ConfigPair> pipelineConfig, IUpdateNotification updateNotifier) { string deviceSetName = Guid.NewGuid().ToString(); IBackupStorage storage = storageConfig.TransformationType.GetConstructor(new Type[0]).Invoke(new object[0]) as IBackupStorage; IBackupDatabase databaseComp = databaseConfig.TransformationType.GetConstructor(new Type[0]).Invoke(new object[0]) as IBackupDatabase; try { int numDevices = storage.GetNumberOfDevices(storageConfig.Parameters); string instanceName = databaseComp.GetInstanceName(databaseConfig.Parameters); string clusterNetworkName = databaseComp.GetClusterNetworkName(databaseConfig.Parameters); SqlPlatform sqlPlatform = VirtualBackupDeviceFactory.DiscoverSqlPlatform(instanceName, clusterNetworkName); //NotifyWhenReady notifyWhenReady = new NotifyWhenReady(deviceName, isBackup);)) using (IVirtualDeviceSet deviceSet = VirtualBackupDeviceFactory.NewVirtualDeviceSet(sqlPlatform)) { using (SqlThread sql = new SqlThread()) { bool sqlStarted = false; bool sqlFinished = false; ParallelExecutionException exceptions = new ParallelExecutionException(); try { IStreamNotification streamNotification = new InternalStreamNotification(updateNotifier); long estimatedTotalBytes; List <string> deviceNames = sql.PreConnect(clusterNetworkName, instanceName, deviceSetName, numDevices, databaseComp, databaseConfig.Parameters, isBackup, updateNotifier, out estimatedTotalBytes); using (DisposableList <Stream> fileStreams = new DisposableList <Stream>(isBackup ? storage.GetBackupWriter(storageConfig.Parameters) : storage.GetRestoreReader(storageConfig.Parameters, out estimatedTotalBytes))) using (DisposableList <Stream> topOfPilelines = new DisposableList <Stream>(CreatePipeline(pipelineConfig, fileStreams, isBackup, streamNotification, estimatedTotalBytes))) { VirtualDeviceSetConfig config = new VirtualDeviceSetConfig(); config.Features = FeatureSet.PipeLike; config.DeviceCount = (uint)topOfPilelines.Count; deviceSet.CreateEx(instanceName, deviceSetName, config); sql.BeginExecute(); sqlStarted = true; deviceSet.GetConfiguration(TimeSpan.FromMinutes(1)); List <IVirtualDevice> devices = new List <IVirtualDevice>(); foreach (string devName in deviceNames) { devices.Add(deviceSet.OpenDevice(devName)); } using (DisposableList <DeviceThread> threads = new DisposableList <DeviceThread>(devices.Count)) { for (int i = 0; i < devices.Count; i++) { DeviceThread dThread = new DeviceThread(); threads.Add(dThread); dThread.Initialize(isBackup, topOfPilelines[i], devices[i], deviceSet); } foreach (DeviceThread dThread in threads) { dThread.BeginCopy(); } updateNotifier.OnStart(); //Console.WriteLine(string.Format("{0} started", isBackup ? "Backup" : "Restore")); Exception sqlE = sql.EndExecute(); sqlFinished = true; if (sqlE != null) { exceptions.Exceptions.Add(sqlE); } foreach (DeviceThread dThread in threads) { Exception devE = dThread.EndCopy(); if (devE != null) { exceptions.Exceptions.Add(devE); } } } } } catch (Exception e) { exceptions.Exceptions.Add(e); } finally { if (sqlStarted && !sqlFinished) { Exception sqlE = sql.EndExecute(); sqlFinished = true; if (sqlE != null) { exceptions.Exceptions.Add(sqlE); } } } if (exceptions.HasExceptions) { throw exceptions; } } } } catch { storage.CleanupOnAbort(); throw; } }
private static void BackupOrRestore(int commandType, ConfigPair storageConfig, ConfigPair databaseConfig, List <ConfigPair> pipelineConfig, IUpdateNotification updateNotifier, out List <string> returndevices) { var isBackup = commandType == 1; var deviceSetName = Guid.NewGuid().ToString(); var constructorInfo = storageConfig.TransformationType.GetConstructor(new Type[0]); if (constructorInfo == null) { throw new ArgumentException("Unable to transformation type"); } var storage = constructorInfo.Invoke(new object[0]) as IBackupStorage; var constructor = databaseConfig.TransformationType.GetConstructor(new Type[0]); if (constructor == null) { throw new ArgumentException("Unable to transformation type"); } var databaseComp = constructor.Invoke(new object[0]) as IBackupDatabase; try { if (storage == null) { returndevices = null; return; } var numDevices = storage.GetNumberOfDevices(storageConfig.Parameters); //get instance name e.g. myserver\myinstance if (databaseComp == null) { returndevices = null; return; } var instanceName = databaseComp.GetInstanceName(databaseConfig.Parameters); //get the cluster networking name usually diffrent than the currently running node name var clusterNetworkName = databaseComp.GetClusterNetworkName(databaseConfig.Parameters); //get bit version of our platform x86,x64 or IA64 var sqlPlatform = databaseConfig.Parameters.ContainsKey("user") ? VirtualBackupDeviceFactory.DiscoverSqlPlatform(instanceName, clusterNetworkName, databaseConfig.Parameters["user"][0], databaseConfig.Parameters.ContainsKey("password") ? databaseConfig.Parameters["password"][0] : null) : VirtualBackupDeviceFactory.DiscoverSqlPlatform(instanceName, clusterNetworkName, null, null); //NotifyWhenReady notifyWhenReady = new NotifyWhenReady(deviceName, isBackup);)) using (var deviceSet = VirtualBackupDeviceFactory.NewVirtualDeviceSet(sqlPlatform)) { //Since it is possible to have multiple backup/restore targets we encapsulate each call to a device in its own thread using (var sql = new SqlThread()) { var sqlStarted = false; var sqlFinished = false; returndevices = new List <string>(); var exceptions = new ParallelExecutionException(); try { IStreamNotification streamNotification = new InternalStreamNotification(updateNotifier); long estimatedTotalBytes; var deviceNames = sql.PreConnect(clusterNetworkName, instanceName, deviceSetName, numDevices, databaseComp, databaseConfig.Parameters, commandType, updateNotifier, out estimatedTotalBytes); using ( var fileStreams = new DisposableList <Stream>(isBackup ? storage.GetBackupWriter(storageConfig.Parameters, estimatedTotalBytes) : storage.GetRestoreReader(storageConfig.Parameters, out estimatedTotalBytes))) using ( var topOfPilelines = new DisposableList <Stream>(CreatePipeline(pipelineConfig, fileStreams, isBackup, streamNotification, estimatedTotalBytes))) { ReturnByteScale(estimatedTotalBytes, isBackup); var config = new VirtualDeviceSetConfig { Features = FeatureSet.PipeLike, DeviceCount = (uint)topOfPilelines.Count }; deviceSet.CreateEx(instanceName, deviceSetName, config); sql.BeginExecute(); sqlStarted = true; deviceSet.GetConfiguration(TimeSpan.FromMinutes(360)); var devices = deviceNames.Select(deviceSet.OpenDevice).ToList(); returndevices = deviceNames; using (var threads = new DisposableList <DeviceThread>(devices.Count)) { for (var i = 0; i < devices.Count; i++) { var dThread = new DeviceThread(); threads.Add(dThread); dThread.Initialize(isBackup, topOfPilelines[i], devices[i], deviceSet); } foreach (var dThread in threads) { dThread.BeginCopy(); } updateNotifier.OnStart(); var sqlE = sql.EndExecute(); sqlFinished = true; if (sqlE != null) { exceptions.Exceptions.Add(sqlE); } foreach (var devE in threads.Select(dThread => dThread.EndCopy()).Where(devE => devE != null)) { exceptions.Exceptions.Add(devE); } } } } catch (Exception e) { exceptions.Exceptions.Add(e); } finally { if (exceptions.HasExceptions) { throw exceptions; } if (sqlStarted && !sqlFinished) { var sqlE = sql.EndExecute(); if (sqlE != null) { exceptions.Exceptions.Add(sqlE); } } } } } } catch { if (storage != null) { storage.CleanupOnAbort(); } throw; } }