private static void OnFailure(Exception exception, string errorDetailsFile) { BackupCopier.TraceSource.WriteWarning( BackupCopier.TraceType, "BackupCopier operation failed with the following exception: {0}", exception); if (!string.IsNullOrEmpty(errorDetailsFile)) { try { var errorDetails = new StringBuilder(exception.Message); var inner = exception.InnerException; while (inner != null) { errorDetails.AppendFormat(" --> {0}: {1}", inner.GetType().Name, inner.Message); inner = inner.InnerException; } BackupCopier.WriteStringToFile( errorDetailsFile, BackupCopier.GetFabricErrorCodeOrEFail(exception) + "," + errorDetails.ToString(), false, Encoding.Unicode); } catch (Exception innerEx) { BackupCopier.TraceSource.WriteWarning( BackupCopier.TraceType, "Failed to write error details: {0}", innerEx.ToString()); } } }
/// return 0 if program completes successfully, -1 otherwise. public static int Main(string[] args) { #if !DotNetCoreClr ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; #endif if (args.Length < 1) { Console.WriteLine("This is for internal use only"); return(-1); } /* BackupCopier arguments for UploadBackup to Azure BlobStore */ // /operation:AzureBlobStoreUpload - required // /connectionString:<Connectionstring> - required // /isConnectionStringEncrypted:<true|false> - required // /containerName:<Name of the Azure Blob Container> - required // /backupStoreBaseFolderPath:<Base folder under given container> - required // /sourceFileOrFolderPath:<Full path to source file or folder which needs to be uploaded> - required // /backupMetadataFilePath:<Full path to source backup metadata file which needs to be uploaded > -required // /targetFolderPath:<path to target folder where above file/folder needs to be uploaded> - required // /timeout:<ticks> - optional // /workingDir:<DirectoryPath> - optional // /errorDetailsFile:<ErrorDetailsFilePath> - optional /* BackupCopier arguments for DownloadBackup from Azure BlobStore */ // /operation:AzureBlobStoreload - required // /connectionString:<Connectionstring> - required // /isConnectionStringEncrypted:<true|false> - required // /containerName:<Name of the Azure Blob Container> - required // /backupStoreBaseFolderPath:<Base folder under given container> - required // /sourceFileOrFolderPath:<Full path to source file or folder which needs to be downloaded> - required // /targetFolderPath:<path to target folder where above file/folder needs to be downloaded> - required // /timeout:<ticks> - optional // /workingDir:<DirectoryPath> - optional // /errorDetailsFile:<ErrorDetailsFilePath> - optional /* BackupCopier arguments for UploadBackup to File Share */ // /operation:FileShareUpload - required // /fileShareAccessType:<DomainUser|None> - required // /fileSharePath:<File share path> - required // /isPasswordEncrypted:<true|false> - required // /primaryUserName:<Primary user Name for FileShare access> - optional; primaryUserName & primaryPassword both should be either present or absent together. // /primaryPassword:<Password for Primary user Name for FileShare access> - optional; primaryUserName & primaryPassword both should be either present or absent together. // /secondaryUserName:<Secondary user Name for FileShare access> - optional; secondaryUserName & secondaryPassword both should be either present or absent together. // /secondaryPassword:<Password for Secondary user Name for FileShare access> - optional; secondaryUserName & secondaryPassword both should be either present or absent together. // /sourceFileOrFolderPath:<Full path to source file or folder which needs to be uploaded> - required // /backupMetadataFilePath:<Full path to source backup metadata file which needs to be uploaded > -required // /targetFolderPath:<path to target folder where above file/folder needs to be uploaded> - required // /timeout:<ticks> - optional // /workingDir:<DirectoryPath> - optional // /errorDetailsFile:<ErrorDetailsFilePath> - optional /* BackupCopier arguments for DownloadBackup from File Share */ // /operation:FileShareDownload - required // /fileShareAccessType:<DomainUser|None> - required // /fileSharePath:<File share path> - required // /isPasswordEncrypted:<true|false> - required // /primaryUserName:<Primary user Name for FileShare access> - optional; primaryUserName & primaryPassword both should be either present or absent together. // /primaryPassword:<Password for Primary user Name for FileShare access> - optional; primaryUserName & primaryPassword both should be either present or absent together. // /secondaryUserName:<Secondary user Name for FileShare access> - optional; secondaryUserName & secondaryPassword both should be either present or absent together. // /secondaryPassword:<Password for Secondary user Name for FileShare access> - optional; secondaryUserName & secondaryPassword both should be either present or absent together. // /sourceFileOrFolderPath:<Full path to source file or folder which needs to be downloaded> - required // /targetFolderPath:<path to target folder where above file/folder needs to be downloaded> - required // /timeout:<ticks> - optional // /workingDir:<DirectoryPath> - optional // /errorDetailsFile:<ErrorDetailsFilePath> - optional Dictionary <string, string> commandArgs = null; Exception exception = null; string errorDetailsFile = null; try { Dictionary <string, string> applicationParameters = null; commandArgs = ParseAndValidateParameters( args, out applicationParameters); errorDetailsFile = commandArgs.ContainsKey(StringConstants.ErrorDetailsFile) ? commandArgs[StringConstants.ErrorDetailsFile] : null; string workingDirectory = commandArgs.ContainsKey(StringConstants.WorkingDir) ? commandArgs[StringConstants.WorkingDir] : Directory.GetCurrentDirectory(); string progressFile = commandArgs.ContainsKey(StringConstants.ProgressFile) ? commandArgs[StringConstants.ProgressFile] : null; StringBuilder stringToTrace = new StringBuilder(); foreach (var commandArg in commandArgs) { // Skipping tracing credentials. if (CommandArgsForCredentials.Contains(commandArg.Key)) { stringToTrace.AppendFormat("{0}:{1}", commandArg.Key, "***"); stringToTrace.AppendLine(); } else { stringToTrace.AppendFormat("{0}:{1}", commandArg.Key, commandArg.Value); stringToTrace.AppendLine(); } } BackupCopier.TraceSource.WriteInfo( BackupCopier.TraceType, "BackupCopier called with - {0}", stringToTrace.ToString()); TimeSpan timeout = commandArgs.ContainsKey(StringConstants.Timeout) ? TimeSpan.FromTicks(long.Parse(commandArgs[StringConstants.Timeout], CultureInfo.InvariantCulture)) : TimeSpan.MaxValue; Timer timer = null; if (timeout != TimeSpan.MaxValue) { BackupCopier.TraceSource.WriteInfo( BackupCopier.TraceType, "BackupCopier enabled timeout monitor: {0}", timeout); timer = new Timer(OnTimeout, errorDetailsFile, timeout, TimeSpan.FromMilliseconds(-1)); } string operationValue = commandArgs[StringConstants.OperationKeyName]; IBackupStoreManager backupStoreManager; bool isUpload = true; switch (operationValue) { case StringConstants.AzureBlobStoreUpload: { backupStoreManager = ConstuctAzureBlobBackupStoreManager(commandArgs); isUpload = true; } break; case StringConstants.AzureBlobStoreDownload: { backupStoreManager = ConstuctAzureBlobBackupStoreManager(commandArgs); isUpload = false; } break; case StringConstants.DsmsAzureBlobStoreUpload: { backupStoreManager = ConstuctDsmsAzureBlobBackupStoreManager(commandArgs); isUpload = true; } break; case StringConstants.DsmsAzureBlobStoreDownload: { backupStoreManager = ConstuctDsmsAzureBlobBackupStoreManager(commandArgs); isUpload = false; } break; case StringConstants.FileShareUpload: { backupStoreManager = ConstuctFileShareBackupStoreManager(commandArgs); isUpload = true; } break; case StringConstants.FileShareDownload: { backupStoreManager = ConstuctFileShareBackupStoreManager(commandArgs); isUpload = false; } break; default: throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Argument {0} with value {1} is not supported", StringConstants.OperationKeyName, operationValue)); } if (isUpload) { long totalFileSize = BackupCopier.GetSize(commandArgs[StringConstants.SourceFileOrFolderPathKeyName]) + BackupCopier.GetSize(commandArgs[StringConstants.BackupMetadataFilePathKeyName]); Stopwatch stopwatch = new Stopwatch(); stopwatch.Restart(); // Upload backup file or folder. backupStoreManager.Upload( commandArgs[StringConstants.SourceFileOrFolderPathKeyName], commandArgs[StringConstants.TargetFolderPathKeyName], !File.GetAttributes(commandArgs[StringConstants.SourceFileOrFolderPathKeyName]).HasFlag(FileAttributes.Directory)); // Upload metadata file. backupStoreManager.Upload( commandArgs[StringConstants.BackupMetadataFilePathKeyName], null, true); stopwatch.Stop(); BackupCopier.TraceSource.WriteInfo( BackupCopier.TelemetryTraceType, "{0}, {1}, {2}, {3}, {4}, {5}, {6}", commandArgs[StringConstants.SourceFileOrFolderPathKeyName], commandArgs[StringConstants.BackupMetadataFilePathKeyName], commandArgs.ContainsKey(StringConstants.FileSharePathKeyName) ? commandArgs[StringConstants.FileSharePathKeyName] : String.Empty, commandArgs.ContainsKey(StringConstants.TargetFolderPathKeyName) ? commandArgs[StringConstants.TargetFolderPathKeyName] : String.Empty, commandArgs.ContainsKey(StringConstants.BackupStoreBaseFolderPathKeyName) ? commandArgs[StringConstants.BackupStoreBaseFolderPathKeyName] : String.Empty, totalFileSize, stopwatch.Elapsed.TotalMilliseconds); } else { backupStoreManager.Download(commandArgs[StringConstants.SourceFileOrFolderPathKeyName], commandArgs[StringConstants.TargetFolderPathKeyName], commandArgs[StringConstants.SourceFileOrFolderPathKeyName].EndsWith(StringConstants.ZipExtension)); } } catch (AggregateException ae) { exception = ae.InnerException; StringBuilder exceptionStringBuilder = new StringBuilder("Aggregate exception has "); exceptionStringBuilder.Append(ae.InnerExceptions.Count); exceptionStringBuilder.Append(" exceptions. "); ae.InnerExceptions.ForEach(innerException => exceptionStringBuilder.AppendLine(innerException.Message)); BackupCopier.TraceSource.WriteWarning( BackupCopier.TraceType, "AggregateException: {0}", exceptionStringBuilder.ToString()); } catch (Exception e) { exception = e; } if (exception != null) { OnFailure(exception, errorDetailsFile); return(unchecked ((int)NativeTypes.FABRIC_ERROR_CODE.FABRIC_E_BACKUPCOPIER_UNEXPECTED_ERROR)); } else { BackupCopier.TraceSource.WriteInfo( BackupCopier.TraceType, "BackupCopier operation completed successfully."); return(0); } }