public void Upload(string sourceFileOrFolderPath, string destinationFolderName, bool sourceIsFile = false)
        {
            var destinationFolder = this._storeInformation.FileSharePath;

            if (!String.IsNullOrEmpty(destinationFolderName))
            {
                destinationFolder += PathSeparator + destinationFolderName;
            }

            AppTrace.TraceSource.WriteInfo(TraceType, "Moving backup from {0} to {1}", sourceFileOrFolderPath, destinationFolder);

            var workFolder = Path.GetTempPath();

            string sourceFolder;

            if (!sourceIsFile)
            {
                sourceFolder = sourceFileOrFolderPath;
            }
            else
            {
                sourceFolder = Path.GetDirectoryName(sourceFileOrFolderPath);
            }

            // Check if the source folder can be accessed under impersonation, if not ACL it accordingly
            try
            {
                BackupRestoreUtility.PerformIOWithRetries(
                    () =>
                {
                    if (CheckFolderAccessUnderImpersonation(sourceFolder, FileAccess.Read))
                    {
                        UpdateAclOnFolder(sourceFolder, FileSystemRights.Read);
                    }
                });
            }
            catch (Exception e)
            {
                throw new IOException(String.Format("Unable to create staging directory for work directory {0}.", workFolder), e);
            }

            if (sourceIsFile)
            {
                CopyFileToDestination(sourceFileOrFolderPath, destinationFolder, "", 3);
            }
            else
            {
                var sourceDirInfo = new DirectoryInfo(sourceFolder);
                foreach (var file in sourceDirInfo.GetFiles("*", SearchOption.AllDirectories))
                {
                    var sourceRelative = file.DirectoryName.Substring(sourceFolder.Trim('\\').Length).Trim('\\');
                    CopyFileToDestination(file.FullName, destinationFolder, sourceRelative, 3);
                }
            }
        }
Example #2
0
        private void CopyFileToDestinationBlobWorker(FileCopyInfo fileCopyInfo, CloudBlockBlob destinationBlob)
        {
            // First let's try to copy directly from the source location. This should work fine if the
            // source file is not in use.
            bool exceptionWithDirectCopy = false;

            try
            {
                CreateStreamAndUploadToBlob(fileCopyInfo.SourceFullPath, destinationBlob);
                this.TraceSource.WriteInfo(
                    TraceType,
                    "Uploaded file {0} to destination blob {1}",
                    fileCopyInfo.SourceFullPath,
                    destinationBlob.Name);
            }
            catch (Exception e)
            {
                if ((false == (e is IOException)) && (false == (e is FabricException)))
                {
                    throw;
                }

                exceptionWithDirectCopy = true;
            }

            if (exceptionWithDirectCopy)
            {
                // We couldn't copy the file directly to blob. This can happen when the file is in use,
                // because we would be unable to open a handle to the file in that case. Therefore,
                // we make a copy of the file to a temp location and then open a handle to that temp
                // copy for uploading to blob.
                string tempDir = Path.GetTempPath();
                if (!String.IsNullOrWhiteSpace(fileCopyInfo.RelativeDirectoryName))
                {
                    tempDir = Path.Combine(tempDir, fileCopyInfo.RelativeDirectoryName);
                }

                string tempDest = Path.Combine(tempDir, fileCopyInfo.SourceFileName);
                FabricDirectory.CreateDirectory(tempDir);
                try
                {
                    FabricFile.Copy(fileCopyInfo.SourceFullPath, tempDest, true);
                    CreateStreamAndUploadToBlob(tempDest, destinationBlob);
                    this.TraceSource.WriteInfo(
                        TraceType,
                        "Uploaded file {0} to destination blob {1}",
                        fileCopyInfo.SourceFullPath,
                        destinationBlob.Name);
                }
                finally
                {
                    try
                    {
                        BackupRestoreUtility.PerformIOWithRetries(
                            () =>
                        {
                            FabricDirectory.Delete(tempDir, true);
                        });
                    }
                    catch (Exception e)
                    {
                        this.TraceSource.WriteExceptionAsError(
                            TraceType,
                            e,
                            "Failed to delete temporary directory {0}.",
                            tempDir);
                    }
                }
            }
        }
        public void Download(string sourceFileOrFolderName, string destinationFolder, bool sourceIsFile = false)
        {
            var sourceFileOrFolderPath = Path.Combine(this._storeInformation.FileSharePath, sourceFileOrFolderName);

            AppTrace.TraceSource.WriteInfo(TraceType, "Moving backup from {0} to {1}", sourceFileOrFolderPath, destinationFolder);

            // First check if the destination folder exists or not, if not create it
            BackupRestoreUtility.PerformIOWithRetries(
                () =>
            {
                if (!Directory.Exists(destinationFolder))
                {
                    Directory.CreateDirectory(destinationFolder);
                }
            });

            // Check if post impersonation we would be able to copy the content to the destination dir,
            // if not, add ACL appropriately.
            try
            {
                BackupRestoreUtility.PerformIOWithRetries(
                    () =>
                {
                    if (CheckFolderAccessUnderImpersonation(destinationFolder, FileAccess.ReadWrite))
                    {
                        UpdateAclOnFolder(destinationFolder, FileSystemRights.FullControl);
                    }
                });
            }
            catch (Exception e)
            {
                throw new IOException(String.Format("Unable to check for folder access or update ACL for destination folder {0}.", destinationFolder), e);
            }

            if (!sourceIsFile)
            {
                FileInfo[] files         = null;
                var        sourceDirInfo = new DirectoryInfo(sourceFileOrFolderPath);

                BackupRestoreUtility.PerformIOWithRetries(
                    () =>
                    PerformOperationUnderImpersonation(
                        () =>
                {
                    files = sourceDirInfo.GetFiles("*", SearchOption.AllDirectories);
                    return(true);
                })
                    );

                if (null == files)
                {
                    throw new IOException(String.Format("Unable to enumerate files under directory {0}", sourceFileOrFolderPath));
                }

                foreach (var file in files)
                {
                    var sourceRelative = file.DirectoryName.Substring(sourceFileOrFolderPath.Trim(PathSeparator).Length).Trim(PathSeparator);
                    CopyFileToDestination(file.FullName, destinationFolder, sourceRelative, 3);
                }
            }
            else
            {
                CopyFileToDestination(sourceFileOrFolderPath, destinationFolder, String.Empty, 3);
            }
        }
        private void CopyFileToDestination(string source, string destinationPath, string sourceRelative, int retryCount)
        {
            // Compute the destination path
            var    sourceFileName = Path.GetFileName(source);
            string destination    = Path.Combine(destinationPath, sourceRelative);

            destination = Path.Combine(destination, sourceFileName);

            // Figure out the name of the directory at the destination
            string destinationDir;

            try
            {
                destinationDir = Path.GetDirectoryName(destination);
            }
            catch (PathTooLongException e)
            {
                // The path to the destination directory is too long. Skip it.
                AppTrace.TraceSource.WriteExceptionAsError(
                    TraceType,
                    e,
                    "The destination path is too long {0}",
                    destination);
                throw;
            }

            // If the directory at the destination doesn't exist, then create it
            if (!String.IsNullOrEmpty(destinationDir))
            {
                try
                {
                    BackupRestoreUtility.PerformIOWithRetries(
                        () =>
                        this.PerformOperationUnderImpersonation(
                            () =>
                    {
                        if (!FabricDirectory.Exists(destinationDir))
                        {
                            FabricDirectory.CreateDirectory(destinationDir);
                        }

                        return(true);
                    }),
                        retryCount);
                }
                catch (Exception e)
                {
                    AppTrace.TraceSource.WriteExceptionAsError(
                        TraceType,
                        e,
                        "Failed to create directory {0} for copying file {1}.",
                        destinationDir,
                        sourceRelative);
                    throw;
                }
            }

            // Copy the file over to its destination
            try
            {
                BackupRestoreUtility.PerformIOWithRetries(
                    () =>
                {
                    FileCopyInfo copyInfo = new FileCopyInfo
                    {
                        Source      = source,
                        Destination = destination
                    };
                    PerformOperationUnderImpersonation(
                        () => CopyFileToDestination(copyInfo));
                },
                    retryCount);
            }
            catch (Exception e)
            {
                AppTrace.TraceSource.WriteExceptionAsError(
                    TraceType,
                    e,
                    "File copy failed. Source: {0}, destination: {1}",
                    source,
                    destination);
                throw;
            }
        }