public void MigrationWorker(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; string destinationRootPath = (string)e.Argument; this.mLogger.Debug("MigrationWorker - destinationRootPath: {0}", destinationRootPath); // Stopwatch to track how long the migration takes Stopwatch watch = new Stopwatch(); // Start stopwatch to get how long it takes to get the total number of checked items watch.Start(); IEnumerable <ListViewItem> lvItems = GetListViewItems(this.lstSrcReports).Cast <ListViewItem>(); // Get total count of items in ListView that are checked int totalItems = lvItems.Where(lv => lv.Checked == true).Count(); // Stop stopwatch after getting the total number of checked items, and log how long it took watch.Stop(); this.mLogger.Debug("MigrationWorker - Took {0} seconds to get checked ListView items", watch.Elapsed.TotalSeconds); // Start stopwatch to get how long it takes to migrate everything watch.Start(); int progressCounter = 0; int reportsMigratedCounter = 0; int reportsTotalCount = 0; int foldersMigratedCounter = 0; int foldersTotalCount = 0; int dataSourcesMigratedCounter = 0; int dataSourcesTotalCount = 0; // Export folders // Get path of ListView items in the folder group that are checked. var folderPaths = from lv in lvItems where lv.Group.Name == "foldersGroup" && lv.Checked == true select((FolderItem)lv.Tag).Path; foldersTotalCount = folderPaths.Count(); this.mLogger.Debug("MigrationWorker - Folder migration START!"); this.mLogger.Debug("MigrationWorker - Migrating {0} folders...", foldersTotalCount); foreach (string folderPath in folderPaths) { FolderItem folderItem = null; MigrationStatus status = new MigrationStatus() { Success = false }; if (!string.IsNullOrEmpty(folderPath)) { folderItem = this.mReportServerReader.GetFolder(folderPath); if (folderItem != null) { status.Item = folderItem; status.FromPath = folderItem.Path; this.mLogger.Debug("MigrationWorker - BEFORE FolderItem.FromPath = {0}; SourceRootPath = {1}", status.FromPath, this.mSourceRootPath); this.mLogger.Debug("MigrationWorker - BEFORE FolderItem.FromPath = {0}; DestinationRootPath = {1}", status.FromPath, this.mDestinationRootPath); // Get the destination path for this item (e.g. '/SSRSMigrate_AW_Tests/Data Sources' to '/SSRSMigrate_AW_Destination/Data Sources' string destItemPath = SSRSUtil.GetFullDestinationPathForItem( this.mSourceRootPath, this.mDestinationRootPath, folderItem.Path); this.mLogger.Debug("MigrationWorker - AFTER FolderItem.FromPath = {0}; destItemPath = {1}", status.FromPath, destItemPath); folderItem.Path = destItemPath; status.ToPath = destItemPath; this.mLogger.Debug("MigrationWorker - FolderItem.FromPath = {0}; ToPath = {1}", status.FromPath, status.ToPath); try { string warning = this.mReportServerWriter.WriteFolder(folderItem); if (!string.IsNullOrEmpty(warning)) { status.Warnings = new string[] { warning } } ; status.Success = true; ++foldersMigratedCounter; if (this.mEngine.Loaded) { try { this.mEngine.CallMethod("OnMigration_FolderItem", folderItem, status); } catch (Exception er) { mLogger.Error(er, "Error calling script"); this.mDebugForm.LogMessage( string.Format("Error calling script when migrating from '{0}' to '{1}': {2}", status.FromPath, status.ToPath, er.Message), er); } } } catch (ItemAlreadyExistsException er) { this.mLogger.Error(er, "Folder item already exists."); status.Success = false; status.Error = er; this.mDebugForm.LogMessage( string.Format("Folder can't be migrated from '{0}' to '{1}', it already exists.", status.FromPath, status.ToPath), er); } } else { this.mLogger.Warn("MigrationWorker - FolderItem for path '{0}' returned NULL.", folderPath); } } // Always report progress, even if a ListViewItem has an empty path and even if the item isn't retrieved by ReportServerReader. // This will keep the progress bar value from suddenly jumping up several values. if (worker != null) { worker.ReportProgress(((++progressCounter * 100) / totalItems), status); } else { this.mLogger.Warn("MigrationWorker - worker is NULL."); } } this.mLogger.Debug("MigrationWorker - Folder migration END!"); // Export data sources var dataSources = from lv in lvItems where lv.Group.Name == "dataSourcesGroup" && lv.Checked == true select(DataSourceItem) lv.Tag; dataSourcesTotalCount = dataSources.Count(); this.mLogger.Debug("MigrationWorker - DataSource migration START!"); this.mLogger.Debug("MigrationWorker - Migrating {0} datasources...", dataSourcesTotalCount); foreach (DataSourceItem dataSource in dataSources) { string dataSourcePath = dataSource.Path; DataSourceItem dataSourceItem = null; MigrationStatus status = new MigrationStatus() { Success = false }; this.mLogger.Info("MigrationWorker - Start migration of DataSource '{0}'...", dataSourcePath); if (!string.IsNullOrEmpty(dataSourcePath)) { dataSourceItem = this.mReportServerReader.GetDataSource(dataSourcePath); if (dataSourceItem != null) { status.Item = dataSourceItem; status.FromPath = dataSourceItem.Path; // Update the DataSource if it was changed via 'Edit Data Source...' this.mLogger.Debug("MigrationWorker - Checking DataSource equality between source and destination..."); if (!dataSourceItem.Equals(dataSource)) { this.mLogger.Debug("MigrationWorker - DataSources are not equal"); dataSourceItem = dataSource; } else { this.mLogger.Debug("MigrationWorker - DataSources are equal."); } this.mLogger.Debug("MigrationWorker - BEFORE DataSourceItem.FromPath = {0}; SourceRootPath = {1}", status.FromPath, this.mSourceRootPath); this.mLogger.Debug("MigrationWorker - BEFORE DataSourceItem.FromPath = {0}; DestinationRootPath = {1}", status.FromPath, this.mDestinationRootPath); // Get the destination path for this item (e.g. '/SSRSMigrate_AW_Tests/Data Sources/AWDataSource' to '/SSRSMigrate_AW_Destination/Data Sources/AWDataSource' string destItemPath = SSRSUtil.GetFullDestinationPathForItem( this.mSourceRootPath, this.mDestinationRootPath, dataSourceItem.Path); this.mLogger.Debug("MigrationWorker - AFTER DataSourceItem.FromPath = {0}; destItemPath = {1}", status.FromPath, destItemPath); dataSourceItem.Path = destItemPath; status.ToPath = destItemPath; this.mLogger.Debug("MigrationWorker - DataSourceItem.FromPath = {0}; ToPath = {1}", status.FromPath, status.ToPath); try { string warning = this.mReportServerWriter.WriteDataSource(dataSourceItem); if (!string.IsNullOrEmpty(warning)) { status.Warnings = new string[] { warning } } ; status.Success = true; ++dataSourcesMigratedCounter; try { if (this.mEngine.Loaded) { this.mEngine.CallMethod("OnMigration_DataSourceItem", dataSourceItem, status); } } catch (Exception er) { mLogger.Error(er, "Error calling script"); this.mDebugForm.LogMessage( string.Format("Error calling script when migrating from '{0}' to '{1}': {2}", status.FromPath, status.ToPath, er.Message), er); } } catch (ItemAlreadyExistsException er) { this.mLogger.Error(er, "Data Source item already exists."); status.Success = false; status.Error = er; this.mDebugForm.LogMessage( string.Format("Data Source can't be migrated from '{0}' to '{1}', it already exists.", status.FromPath, status.ToPath), er); } } else { this.mLogger.Warn("MigrationWorker - DataSourceItem for path '{0}' returned NULL.", dataSourcePath); } this.mLogger.Info("MigrationWorker - End migration of DataSource '{0}'...", dataSourcePath); } else { this.mLogger.Warn("MigrationWorker - DataSource.Path is NULL or empty or '{0}'; skipping...", dataSource.Name); } // Always report progress, even if a ListViewItem has an empty path and even if the item isn't retrieved by ReportServerReader. // This will keep the progress bar value from suddenly jumping up several values. if (worker != null) { worker.ReportProgress(((++progressCounter * 100) / totalItems), status); } else { this.mLogger.Warn("MigrationWorker - worker is NULL."); } } this.mLogger.Debug("MigrationWorker - DataSource migration END!"); // Export reports var reportPaths = from lv in lvItems where lv.Group.Name == "reportsGroup" && lv.Checked == true select((ReportItem)lv.Tag).Path; reportsTotalCount = reportPaths.Count(); this.mLogger.Debug("MigrationWorker - Report migration START!"); this.mLogger.Debug("MigrationWorker - Migrating {0} reports...", reportsTotalCount); foreach (string reportPath in reportPaths) { ReportItem reportItem = null; MigrationStatus status = new MigrationStatus() { Success = false }; if (!string.IsNullOrEmpty(reportPath)) { reportItem = this.mReportServerReader.GetReport(reportPath); if (reportItem != null) { status.Item = reportItem; status.FromPath = reportItem.Path; this.mLogger.Debug( "MigrationWorker - Getting destination path for '{0}' using source path root '{1}' and destination root path '{2}'...", reportItem.Path, this.mSourceRootPath, this.mDestinationRootPath); this.mLogger.Debug("MigrationWorker - BEFORE ReportItem.FromPath = {0}; SourceRootPath = {1}", status.FromPath, this.mSourceRootPath); this.mLogger.Debug("MigrationWorker - BEFORE ReportItem.FromPath = {0}; DestinationRootPath = {1}", status.FromPath, this.mDestinationRootPath); // Get the destination path for this item (e.g. '/SSRSMigrate_AW_Tests/Reports/Company Sales' to '/SSRSMigrate_AW_Destination/Reports/Company Sales' string destItemPath = SSRSUtil.GetFullDestinationPathForItem( this.mSourceRootPath, this.mDestinationRootPath, reportItem.Path); this.mLogger.Debug("MigrationWorker - AFTER ReportItem.FromPath = {0}; destItemPath = {1}", status.FromPath, destItemPath); reportItem.Path = destItemPath; status.ToPath = destItemPath; this.mLogger.Debug("MigrationWorker - ReportItem.FromPath = {0}; ToPath = {1}", status.FromPath, status.ToPath); reportItem.Definition = SSRSUtil.UpdateReportDefinition( this.mDestinationServerUrl, this.mSourceRootPath, this.mDestinationRootPath, reportItem.Definition); try { string[] warnings = this.mReportServerWriter.WriteReport(reportItem); if (warnings != null) { if (warnings.Length > 0) { status.Warnings = warnings; } } status.Success = true; ++reportsMigratedCounter; try { if (this.mEngine.Loaded) { this.mEngine.CallMethod("OnMigration_ReportItem", reportItem, status); } } catch (Exception er) { mLogger.Error(er, "Error calling script"); this.mDebugForm.LogMessage( string.Format("Error calling script when migrating from '{0}' to '{1}': {2}", status.FromPath, status.ToPath, er.Message), er); } } catch (ItemAlreadyExistsException er) { this.mLogger.Error(er, "Report item already exists."); status.Success = false; status.Error = er; this.mDebugForm.LogMessage( string.Format("Report can't be migrated from '{0}' to '{1}', it already exists.", status.FromPath, status.ToPath), er); } } else { this.mLogger.Warn("MigrationWorker - ReportItem for path '{0}' returned NULL.", reportPath); } } // Always report progress, even if a ListViewItem has an empty path and even if the item isn't retrieved by ReportServerReader. // This will keep the progress bar value from suddenly jumping up several values. if (worker != null) { worker.ReportProgress(((++progressCounter * 100) / totalItems), status); } else { this.mLogger.Warn("MigrationWorker - worker is NULL."); } } this.mLogger.Debug("MigrationWorker - Report migration END!"); // Stop stopwatch and get how long it took for the migration to complete successfully watch.Stop(); double averageItem = watch.Elapsed.TotalSeconds / progressCounter; string result = string.Format("{0}/{1} folders, {2}/{3} data sources, {4}/{5} reports migrated in {6}h {7}m {8}s (@ {9:0.00} items/s)", foldersMigratedCounter, foldersTotalCount, dataSourcesMigratedCounter, dataSourcesTotalCount, reportsMigratedCounter, reportsTotalCount, watch.Elapsed.Hours, watch.Elapsed.Minutes, watch.Elapsed.Seconds, averageItem); this.mLogger.Info("MigrationWorker - {0}", result); e.Result = result; }