public override void ExecuteCommand() { if (!String.IsNullOrEmpty(DatabaseName)) { ConnectionString.InitialCatalog = DatabaseName; } Log.Info("Exporting {0} on {1} to {2}", ConnectionString.InitialCatalog, Util.GetDatabaseServerName(ConnectionString), DestinationStorage.Credentials.AccountName); string serverName = ConnectionString.DataSource; if (serverName.StartsWith("tcp:")) { serverName = serverName.Substring(4); } WASDImportExport.ImportExportHelper helper = new WASDImportExport.ImportExportHelper(Log) { EndPointUri = SqlDacEndpoint.AbsoluteUri, DatabaseName = ConnectionString.InitialCatalog, ServerName = serverName, UserName = ConnectionString.UserID, Password = ConnectionString.Password, StorageKey = Convert.ToBase64String(DestinationStorage.Credentials.ExportKey()) }; // Prep the blob string blobUrl = null; if (!WhatIf) { var client = DestinationStorage.CreateCloudBlobClient(); var container = client.GetContainerReference(DestinationContainer); container.CreateIfNotExists(); var blob = container.GetBlockBlobReference(ConnectionString.InitialCatalog + ".bacpac"); if (blob.Exists()) { Log.Info("Skipping export of {0} because the blob already exists", blob.Name); } else { Log.Info("Starting export to {0}", blob.Uri.AbsoluteUri); // Export! blobUrl = helper.DoExport(blob.Uri.AbsoluteUri, WhatIf); } } Log.Info("Export Complete"); }
protected internal override async Task <JobContinuation> Resume() { if (RequestGUID == null || TargetDatabaseConnection == null || EndPointUri == null) { throw new ArgumentNullException("Job could not resume properly due to incorrect parameters"); } var endPointUri = EndPointUri; WASDImportExport.ImportExportHelper helper = new WASDImportExport.ImportExportHelper() { EndPointUri = endPointUri, ServerName = TargetDatabaseConnection.DataSource, UserName = TargetDatabaseConnection.UserID, Password = TargetDatabaseConnection.Password, }; var statusInfoList = helper.CheckRequestStatus(RequestGUID); var statusInfo = statusInfoList.FirstOrDefault(); if (statusInfo.Status == "Failed") { Log.ExportFailed(statusInfo.ErrorMessage); throw new Exception(statusInfo.ErrorMessage); } if (statusInfo.Status == "Completed") { var exportedBlobPath = statusInfo.BlobUri; Log.ExportCompleted(exportedBlobPath); // Clean up exports await CleanExports(TargetDatabaseConnection, DateTime.Parse(ExportTimestampUtc)); return(Complete()); } Log.Exporting(statusInfo.Status); var parameters = new Dictionary <string, string>(); parameters["RequestGUID"] = RequestGUID; parameters["ExportTimestampUtc"] = ExportTimestampUtc; parameters["TargetDatabaseConnection"] = TargetDatabaseConnection.ConnectionString; parameters["EndPointUri"] = endPointUri; return(Suspend(TimeSpan.FromMinutes(1), parameters)); }
protected internal override async Task <JobContinuation> Execute() { // Load Defaults var endPointUri = EndPointUri ?? Config.Sql.ImportEndPoint; if (String.IsNullOrEmpty(endPointUri)) { endPointUri = NuGet.Services.Constants.EastUSEndpoint; } Log.ImportEndpoint(endPointUri); var cstr = GetConnectionString() ?? Config.Sql.GetConnectionString(KnownSqlConnection.Primary); if (cstr == null || cstr.InitialCatalog == null || cstr.Password == null || cstr.DataSource == null || cstr.UserID == null) { throw new ArgumentNullException("One of the connection string parameters or the string itself is null"); } cstr.TrimNetworkProtocol(); Log.PreparingToImport(cstr.ToString()); if (String.IsNullOrEmpty(GalleryDBName)) { GalleryDBName = DefaultGalleryDBName; } Log.GalleryDBName(GalleryDBName); if (String.IsNullOrEmpty(BackupPrefix)) { BackupPrefix = DefaultBackupPrefix; } if (SourceStorageAccountName == null && SourceStorageAccountKey == null) { var sourceCredentials = Config.Storage.Primary.Credentials; SourceStorageAccountName = sourceCredentials.AccountName; SourceStorageAccountKey = sourceCredentials.ExportBase64EncodedKey(); } else { if (SourceStorageAccountName == null) { throw new ArgumentNullException("Source Storage Account Name is null"); } if (SourceStorageAccountKey == null) { throw new ArgumentNullException("Source Storage Account Key is null"); } } if (String.IsNullOrEmpty(BacpacFile)) { var storageCredentials = new StorageCredentials(SourceStorageAccountName, SourceStorageAccountKey); var blobEndPoint = String.Format(@"https://{0}.blob.core.windows.net", SourceStorageAccountName); var cloudBlobClient = new CloudBlobClient(new Uri(blobEndPoint), storageCredentials); BacpacFile = GetLatestBackupBacpacFile(cloudBlobClient); } var dotIndex = BacpacFile.IndexOf('.'); BacpacFile = dotIndex > -1 ? BacpacFile.Substring(0, dotIndex) : BacpacFile; TargetDatabaseName = BacpacFile; if (await DoesDBExist(cstr, TargetDatabaseName)) { Log.DatabaseAlreadyExists("Database {0} already exists.Skipping...", TargetDatabaseName); // If we reached this point, certainly, the import is incomplete/failed // Because, if RENAME failed after a successful import, we keep trying again until rename is successful // If import failed, we do not RENAME at all. So, DO NOT RENAME HERE return(Complete()); } WASDImportExport.ImportExportHelper helper = new WASDImportExport.ImportExportHelper() { EndPointUri = endPointUri, DatabaseName = TargetDatabaseName, ServerName = cstr.DataSource, UserName = cstr.UserID, Password = cstr.Password, StorageKey = SourceStorageAccountKey, }; var blobAbsoluteUri = String.Format(@"https://{0}.blob.core.windows.net/bacpac-files/{1}.bacpac", SourceStorageAccountName, BacpacFile); Log.StartingImport(TargetDatabaseName, cstr.DataSource, BacpacFile); var requestGUID = helper.DoImport(Log, blobAbsoluteUri, whatIf: WhatIf); if (requestGUID != null) { Log.ImportStarted(requestGUID); var parameters = new Dictionary <string, string>(); parameters["RequestGUID"] = requestGUID; parameters["TargetDatabaseConnection"] = cstr.ConnectionString; parameters["EndPointUri"] = endPointUri; parameters["TargetDatabaseName"] = TargetDatabaseName; parameters["GalleryDBName"] = GalleryDBName; return(Suspend(TimeSpan.FromMinutes(5), parameters)); } else { throw new Exception("Request to import database unsuccessful. No request GUID obtained"); } }
protected internal override async Task <JobContinuation> Resume() { if (RenameAttempts > 0) { if (TargetDatabaseConnection == null || TargetDatabaseName == null || String.IsNullOrEmpty(GalleryDBName)) { throw new ArgumentNullException("Job could not resume properly due to incorrect parameters"); } return(await RenameImportedDBToGalleryDB()); } else { if (RequestGUID == null || TargetDatabaseConnection == null || EndPointUri == null || TargetDatabaseName == null || String.IsNullOrEmpty(GalleryDBName)) { throw new ArgumentNullException("Job could not resume properly due to incorrect parameters"); } var endPointUri = EndPointUri; WASDImportExport.ImportExportHelper helper = new WASDImportExport.ImportExportHelper() { EndPointUri = endPointUri, ServerName = TargetDatabaseConnection.DataSource, UserName = TargetDatabaseConnection.UserID, Password = TargetDatabaseConnection.Password, DatabaseName = TargetDatabaseName, }; DACWebService.StatusInfo statusInfo = null; try { var statusInfoList = helper.CheckRequestStatus(RequestGUID); statusInfo = statusInfoList.FirstOrDefault(); } catch (Exception ex) { Log.Exception(ex.Message); } if (statusInfo != null) { if (statusInfo.Status == "Failed") { Log.ImportFailed(statusInfo.ErrorMessage); throw new Exception(statusInfo.ErrorMessage); } if (statusInfo.Status == "Completed") { Log.ImportCompleted(statusInfo.DatabaseName, helper.ServerName); // Now, that the import is complete, rename DB RenameAttempts = 1; return(await RenameImportedDBToGalleryDB()); } Log.Importing(statusInfo.Status); } var parameters = new Dictionary <string, string>(); parameters["RequestGUID"] = RequestGUID; parameters["TargetDatabaseConnection"] = TargetDatabaseConnection.ConnectionString; parameters["EndPointUri"] = endPointUri; parameters["TargetDatabaseName"] = TargetDatabaseName; parameters["GalleryDBName"] = GalleryDBName; return(Suspend(TimeSpan.FromMinutes(5), parameters)); } }
protected internal override async Task <JobContinuation> Execute() { // Capture timestamp var timestamp = DateTime.UtcNow.ToString("O"); // Load Defaults var endPointUri = EndPointUri ?? Config.Sql.ExportEndPoint; if (String.IsNullOrEmpty(endPointUri)) { endPointUri = NuGet.Services.Constants.NorthCentralUSEndpoint; } Log.ExportEndpoint(endPointUri); var cstr = GetConnectionString() ?? Config.Sql.GetConnectionString(KnownSqlConnection.Legacy); if (cstr == null || cstr.InitialCatalog == null || cstr.Password == null || cstr.DataSource == null || cstr.UserID == null) { throw new ArgumentNullException("One of the connection string parameters or the string itself is null"); } cstr.TrimNetworkProtocol(); if (DestinationStorageAccountKey == null && DestinationStorageAccountName == null) { var destinationCredentials = Config.Storage.Backup.Credentials; DestinationStorageAccountName = destinationCredentials.AccountName; DestinationStorageAccountKey = destinationCredentials.ExportBase64EncodedKey(); } else { if (DestinationStorageAccountName == null) { throw new ArgumentNullException("Destination Storage Account Name is null"); } if (DestinationStorageAccountKey == null) { throw new ArgumentNullException("Destination Storage Account Key is null"); } } TargetDatabaseName = TargetDatabaseName ?? await GetLatestOnlineBackupDatabase(cstr); if (TargetDatabaseName == null) { throw new InvalidOperationException(String.Format("No database with prefix '{0}' was found to export", ExportPrefix)); } Log.PreparingToExport(TargetDatabaseName, cstr.DataSource); WASDImportExport.ImportExportHelper helper = new WASDImportExport.ImportExportHelper() { EndPointUri = endPointUri, DatabaseName = TargetDatabaseName, ServerName = cstr.DataSource, UserName = cstr.UserID, Password = cstr.Password, StorageKey = DestinationStorageAccountKey, }; // Check if the bacpac file is already present var storageCredentials = new StorageCredentials(DestinationStorageAccountName, DestinationStorageAccountKey); var blobEndPoint = String.Format(@"https://{0}.blob.core.windows.net", DestinationStorageAccountName); var cloudBlobClient = new CloudBlobClient(new Uri(blobEndPoint), storageCredentials); var bacpacFile = String.Format(@"{0}/{1}/{2}.bacpac", blobEndPoint, BlobContainerNames.BacpacFiles, helper.DatabaseName); try { var blob = await cloudBlobClient.GetBlobReferenceFromServerAsync(new Uri(bacpacFile)); if (blob != null) { Log.BacpacFileAlreadyExists(bacpacFile); return(Complete()); } } catch (StorageException) { // Bacpac file does not exist already. Continue } Log.StartingExport(TargetDatabaseName, cstr.DataSource, bacpacFile); var requestGUID = helper.DoExport(Log, bacpacFile, whatIf: WhatIf); if (requestGUID != null) { Log.ExportStarted(requestGUID); var parameters = new Dictionary <string, string>(); parameters["RequestGUID"] = requestGUID; parameters["ExportTimestampUtc"] = timestamp; parameters["TargetDatabaseConnection"] = cstr.ConnectionString; parameters["EndPointUri"] = endPointUri; return(Suspend(TimeSpan.FromMinutes(1), parameters)); } else { throw new Exception("Request to export database is unsuccessful. No request GUID obtained"); } }