Ejemplo n.º 1
0
 public WriteErrorDialogViewModel GetWriteErrorDialogViewModel(TransferException exception)
 {
     return(new WriteErrorDialogViewModel
     {
         SourceFilePath = exception.SourceFile,
         TargetFilePath = exception.TargetFile
     });
 }
Ejemplo n.º 2
0
        public static VfsException ToException(this VfsFault fault)
        {
            VfsException exception;

            switch (fault.FaultType)
            {
            case VfsFaultType.ResourceNotFound:
                exception = new VirtualResourceNotFoundException(fault.CreateFaultMessage());
                break;

            case VfsFaultType.ResourceAccess:
                exception = new ResourceAccessException(fault.CreateFaultMessage());
                break;

            case VfsFaultType.ResourceOverwrite:
                exception = new ResourceOverwriteException(fault.CreateFaultMessage());
                break;

            case VfsFaultType.ResourceLocked:
                exception = new ResourceLockedException(fault.CreateFaultMessage());
                break;

            case VfsFaultType.ResourcePathInvalid:
                exception = new InvalidResourcePathException(fault.CreateFaultMessage());
                break;

            case VfsFaultType.TransferError:
                exception = new TransferException(fault.CreateFaultMessage());
                break;

            case VfsFaultType.TransferUnknown:
                exception = new UnknownTransferException(fault.CreateFaultMessage());
                break;

            case VfsFaultType.TransferStatusError:
                exception = new TransferStatusException(fault.CreateFaultMessage());
                break;

            case VfsFaultType.DataBlockError:
                exception = new DataBlockException(fault.CreateFaultMessage());
                break;

            case VfsFaultType.Undefined:
                exception = new VfsFaultException(fault.CreateFaultMessage(), fault);
                break;

            default:
                Debug.WriteLine("Unsupported VFS fault type: " + fault.FaultType);
                exception = new VfsFaultException(fault.CreateFaultMessage(), fault);
                break;
            }

            exception.EventId = fault.EventId;
            return(exception);
        }
Ejemplo n.º 3
0
        private IEnumerable <TransferEntry> EnumerateLocationNonRecursive(string fileName, CancellationToken cancellationToken)
        {
            Utils.CheckCancellation(cancellationToken);

            if (fileName == null || fileName.Length == 0 || fileName.Length > MaxDirectoryAndFileNameLength)
            {
                // Empty string or exceed-limit-length file name surely match no files.
                yield break;
            }

            if (this.listContinuationToken != null)
            {
                int compareResult = string.Compare(fileName, this.listContinuationToken.FilePath, StringComparison.Ordinal);
                if (compareResult <= 0)
                {
                    yield break;
                }
            }

            CloudFile          cloudFile      = this.location.FileDirectory.GetFileReference(fileName);
            FileRequestOptions requestOptions = Transfer_RequestOptions.DefaultFileRequestOptions;
            ErrorEntry         errorEntry     = null;
            bool exist = false;

            try
            {
                exist = cloudFile.ExistsAsync(requestOptions, null, cancellationToken).Result;
            }
            catch (Exception ex)
            {
                string errorMessage = string.Format(
                    CultureInfo.CurrentCulture,
                    Resources.FailedToEnumerateDirectory,
                    this.location.FileDirectory.SnapshotQualifiedUri.AbsoluteUri,
                    fileName);

                // Use TransferException to be more specific about the cloud file URI.
                TransferException exception =
                    new TransferException(TransferErrorCode.FailToEnumerateDirectory, errorMessage, ex);

                errorEntry = new ErrorEntry(exception);
            }

            if (null != errorEntry)
            {
                yield return(errorEntry);
            }
            else if (exist)
            {
                yield return(new AzureFileEntry(fileName, cloudFile, new AzureFileListContinuationToken(fileName)));
            }
        }
Ejemplo n.º 4
0
        public static void VerifyTransferException(Exception exception, TransferErrorCode expectedErrorCode, params string[] expectedMessages)
        {
            TransferException transferException = exception as TransferException;

            if (transferException == null)
            {
                Test.Error("Verify exception is a transfer exception.");
                return;
            }

            Test.Assert(transferException.ErrorCode == expectedErrorCode, "Verify error code: {0}, expected: {1}", transferException.ErrorCode, expectedErrorCode);
            VerificationHelper.VerifyExceptionErrorMessage(exception, expectedMessages);
        }
        private void RenameExistingFile(TransferException exception, CopyAction?action, Action <CopyAction?, string> rename, Action <Exception> chooseDifferentOption)
        {
            var name = WindowManager.ShowTextInputDialog(Resx.Rename, Resx.NewName + Strings.Colon, Path.GetFileName(exception.TargetFile), null);

            if (!string.IsNullOrWhiteSpace(name))
            {
                rename.Invoke(action, name);
            }
            else
            {
                chooseDifferentOption.Invoke(exception);
            }
        }
        private void ProcessError(Exception exception)
        {
            if (_isAborted)
            {
                FinishTransfer(); return;
            }
            if (IsPaused)
            {
                return;
            }

            var ftp = Pane <FtpContentViewModel>();

            if (ftp != null && !ftp.IsConnected)
            {
                exception = new TransferException(TransferErrorType.LostConnection, string.Format(Resx.ConnectionLostMessage, ftp.Connection.Name), exception)
                {
                    Pane = ftp
                };
            }

            var result = ShowCorrespondingErrorDialog(exception);

            switch (result.Behavior)
            {
            case ErrorResolutionBehavior.Retry:
                BytesTransferred            -= _currentFileBytesTransferred;
                _currentFileBytesTransferred = 0;
                ProcessQueueItem(result.Action);
                break;

            case ErrorResolutionBehavior.Rename:
                RenameExistingFile((TransferException)exception, CopyAction.Rename, ProcessQueueItem, ProcessError);
                break;

            case ErrorResolutionBehavior.Skip:
                if (_queue != null)
                {
                    BytesTransferred += _queue.Peek().FileSystemItem.Size ?? 0 - _currentFileBytesTransferred;
                }
                ProcessSuccess(new OperationResult(TransferResult.Skipped));
                break;

            case ErrorResolutionBehavior.Cancel:
                FinishTransfer();
                break;
            }
        }
Ejemplo n.º 7
0
 public WriteErrorDialogViewModel GetWriteErrorDialogViewModel(TransferException exception)
 {
     var exceptionType = exception.Type;
     var viewModel = new WriteErrorDialogViewModel
     {
         IsCancelEnabled = true,
         IsSkipEnabled = true,
         IsSkipAllEnabled = true,
         IsRenameEnabled = true,
         SourceFilePath = exception.SourceFile,
         ExceptionType = exceptionType
     };
     if (exceptionType == TransferErrorType.WriteAccessError)
     {
         viewModel.IsOverwriteEnabled = true;
         viewModel.IsOverwriteAllEnabled = true;
         viewModel.IsOverwriteAllSmallerEnabled = true;
         viewModel.TargetFilePath = exception.TargetFile;
     }
     return viewModel;
 }
        /// <summary>
        /// Enumerates the blobs present in the storage location referenced by this object.
        /// </summary>
        /// <param name="cancellationToken">CancellationToken to cancel the method.</param>
        /// <returns>Enumerable list of TransferEntry objects found in the storage location referenced by this object.</returns>
        public IEnumerable <TransferEntry> EnumerateLocation(CancellationToken cancellationToken)
        {
            Utils.CheckCancellation(cancellationToken);

            string filePattern = this.SearchPattern ?? string.Empty;

            // Exceed-limit-length patterns surely match no files.
            int maxFileNameLength = this.GetMaxFileNameLength();

            if (filePattern.Length > maxFileNameLength)
            {
                yield break;
            }

            CloudBlobContainer    container         = this.location.BlobDirectory.Container;
            BlobRequestOptions    requestOptions    = Transfer_RequestOptions.DefaultBlobRequestOptions;
            BlobContinuationToken continuationToken = (this.listContinuationToken == null ? null : this.listContinuationToken.BlobContinuationToken);
            bool   passedContinuationToken          = (this.listContinuationToken == null);
            string dirPrefix     = this.location.BlobDirectory.Prefix;
            string patternPrefix = dirPrefix + filePattern;

            do
            {
                BlobResultSegment resultSegment = null;

                ErrorEntry errorEntry = null;

                Utils.CheckCancellation(cancellationToken);
                try
                {
                    resultSegment = container.ListBlobsSegmentedAsync(
                        patternPrefix,
                        true,
                        BlobListingDetails.Snapshots | BlobListingDetails.Metadata,
                        ListBlobsSegmentSize,
                        continuationToken,
                        requestOptions,
                        null,
                        cancellationToken).Result;
                }
                catch (Exception ex)
                {
                    string errorMessage = string.Format(
                        CultureInfo.CurrentCulture,
                        Resources.FailedToEnumerateDirectory,
                        this.location.BlobDirectory.Uri.AbsoluteUri,
                        filePattern);

                    TransferException exception =
                        new TransferException(TransferErrorCode.FailToEnumerateDirectory, errorMessage, ex);
                    errorEntry = new ErrorEntry(exception);
                }

                if (null != errorEntry)
                {
                    // Just return an error entry if we cannot access the container
                    yield return(errorEntry);

                    // TODO: What should we do if some entries have been listed successfully?
                    yield break;
                }

                foreach (IListBlobItem blobItem in resultSegment.Results)
                {
                    Utils.CheckCancellation(cancellationToken);
                    CloudBlob blob = blobItem as CloudBlob;

                    if (null != blob)
                    {
                        if (!this.IncludeSnapshots && blob.SnapshotTime.HasValue)
                        {
                            continue;
                        }

                        if (!passedContinuationToken)
                        {
                            int compareResult = string.Compare(this.listContinuationToken.BlobName, blob.Name, StringComparison.Ordinal);
                            if (compareResult < 0)
                            {
                                passedContinuationToken = true;
                            }
                            else if (0 == compareResult)
                            {
                                if (IsSnapshotTimeEarlier(this.listContinuationToken.SnapshotTime, blob.SnapshotTime))
                                {
                                    passedContinuationToken = true;
                                }
                            }

                            if (!passedContinuationToken)
                            {
                                continue;
                            }
                        }

                        // TODO: currrently not support search for files with prefix specified without considering sub-directory.
                        bool returnItOrNot = this.Recursive ?
                                             blob.Name.StartsWith(patternPrefix, StringComparison.Ordinal) :
                                             blob.Name.Equals(patternPrefix, StringComparison.Ordinal);

                        if (returnItOrNot)
                        {
                            yield return(new AzureBlobEntry(
                                             blob.Name.Remove(0, dirPrefix.Length),
                                             blob,
                                             new AzureBlobListContinuationToken(continuationToken, blob.Name, blob.SnapshotTime)));
                        }
                    }
                }

                continuationToken = resultSegment.ContinuationToken;
            }while (continuationToken != null);
        }
Ejemplo n.º 9
0
        private void ResumeInAllDirectionsHelper(bool directoryTransfer)
        {
            List <TransferItem> allItems = directoryTransfer ? AllTransferDirectionTest.GetTransformItemsForAllDirTransferDirections(resume: true)
                : AllTransferDirectionTest.GetTransformItemsForAllSingleTransferDirections(true);

            int fileCount = expectedFileNodes.Keys.Count;

            // Execution and store checkpoints
            CancellationTokenSource tokenSource = new CancellationTokenSource();

            TransferContext transferContext = null;

            if (directoryTransfer)
            {
                transferContext = new DirectoryTransferContext();
            }
            else
            {
                transferContext = new SingleTransferContext();
            }

            var progressChecker = new ProgressChecker(fileCount, 1024 * fileCount);

            transferContext.ProgressHandler = progressChecker.GetProgressHandler();
            allItems.ForEach(item =>
            {
                item.CancellationToken = tokenSource.Token;
                item.TransferContext   = transferContext;
            });

            var options = new TestExecutionOptions <DMLibDataInfo>();

            options.DisableDestinationFetch = true;

            // Checkpoint names
            const string PartialStarted    = "PartialStarted",
                         AllStarted        = "AllStarted",
                         AllStartedAndWait = "AllStartedAndWait",
                         BeforeCancel      = "BeforeCancel",
                         AfterCancel       = "AfterCancel";
            Dictionary <string, TransferCheckpoint> checkpoints = new Dictionary <string, TransferCheckpoint>();

            TransferItem randomItem = allItems[random.Next(0, allItems.Count)];

            randomItem.AfterStarted = () =>
            {
                Test.Info("Store check point after transfer item: {0}.", randomItem.ToString());
                checkpoints.Add(PartialStarted, transferContext.LastCheckpoint);
            };

            options.AfterAllItemAdded = () =>
            {
                if (!progressChecker.DataTransferred.WaitOne(30000))
                {
                    Test.Error("No progress in 30s.");
                }

                checkpoints.Add(AllStarted, transferContext.LastCheckpoint);
                Thread.Sleep(1000);
                checkpoints.Add(AllStartedAndWait, transferContext.LastCheckpoint);
                Thread.Sleep(1000);
                checkpoints.Add(BeforeCancel, transferContext.LastCheckpoint);
                tokenSource.Cancel();
                checkpoints.Add(AfterCancel, transferContext.LastCheckpoint);
            };

            var result = this.RunTransferItems(allItems, options);

            // Resume with stored checkpoints in random order
            var checkpointList = new List <KeyValuePair <string, TransferCheckpoint> >();

            checkpointList.AddRange(checkpoints);
            checkpointList.Shuffle();

            foreach (var pair in checkpointList)
            {
                Test.Info("===Resume with checkpoint '{0}'===", pair.Key);
                options = new TestExecutionOptions <DMLibDataInfo>();
                options.DisableDestinationFetch = true;

                progressChecker.Reset();

                if (directoryTransfer)
                {
                    transferContext = new DirectoryTransferContext(DMLibTestHelper.RandomReloadCheckpoint(pair.Value))
                    {
                        ProgressHandler = progressChecker.GetProgressHandler(),

                        // The checkpoint can be stored when DMLib doesn't check overwrite callback yet.
                        // So it will case an skip file error if the desination file already exists and
                        // We don't have overwrite callback here.
                        ShouldOverwriteCallbackAsync = DMLibInputHelper.GetDefaultOverwiteCallbackY()
                    };
                }
                else
                {
                    transferContext = new SingleTransferContext(DMLibTestHelper.RandomReloadCheckpoint(pair.Value))
                    {
                        ProgressHandler = progressChecker.GetProgressHandler(),

                        // The checkpoint can be stored when DMLib doesn't check overwrite callback yet.
                        // So it will case an skip file error if the desination file already exists and
                        // We don't have overwrite callback here.
                        ShouldOverwriteCallbackAsync = DMLibInputHelper.GetDefaultOverwiteCallbackY()
                    };
                }

                int expectedFailureCount = 0;

                transferContext.FileFailed += (resource, eventArgs) =>
                {
                    TransferException exception = eventArgs.Exception as TransferException;
                    if (null != exception && exception.ErrorCode == TransferErrorCode.MismatchCopyId)
                    {
                        Interlocked.Increment(ref expectedFailureCount);
                    }
                };

                TransferEventChecker eventChecker = new TransferEventChecker();
                eventChecker.Apply(transferContext);

                List <TransferItem> itemsToResume = allItems.Select(item =>
                {
                    TransferItem itemToResume    = item.Clone();
                    itemToResume.TransferContext = transferContext;
                    return(itemToResume);
                }).ToList();

                result = this.RunTransferItems(itemsToResume, options);

                foreach (DMLibDataType destDataType in DataTypes)
                {
                    if (DMLibDataType.URI == destDataType)
                    {
                        continue;
                    }

                    DataAdaptor <DMLibDataInfo> destAdaptor = GetDestAdaptor(destDataType);
                    DMLibDataInfo destDataInfo = destAdaptor.GetTransferDataInfo(string.Empty);

                    foreach (FileNode destFileNode in destDataInfo.EnumerateFileNodes())
                    {
                        string   fileName       = destFileNode.Name;
                        FileNode sourceFileNode = expectedFileNodes[fileName];

                        Test.Assert(DMLibDataHelper.Equals(sourceFileNode, destFileNode), "Verify transfer result.");
                    }
                }

                if (!directoryTransfer)
                {
                    Test.Assert(result.Exceptions.Count == expectedFailureCount, "Verify no error happens. Expect {0}, Actual: {1}", expectedFailureCount, result.Exceptions.Count);
                }
                else
                {
                    Test.Assert(result.Exceptions.Count == 0, "Verify no exception happens. Actual: {0}", result.Exceptions.Count);
                    Test.Assert(eventChecker.FailedFilesNumber == expectedFailureCount, "Verify no unexpected error happens. Expect {0}, Actual: {1}", expectedFailureCount, eventChecker.FailedFilesNumber);
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ErrorEntry" /> class.
 /// </summary>
 /// <param name="ex">Exception to store.</param>
 public ErrorEntry(TransferException ex)
     : base(null, null)
 {
     this.Exception = ex;
 }
        public void OverwriteDestination()
        {
            string destExistYName    = "destExistY";
            string destExistNName    = "destExistN";
            string destNotExistYName = "destNotExistY";

            DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty);

            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistYName, 1024);
            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistNName, 1024);
            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destNotExistYName, 1024);

            DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty);

            DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistYName, 1024);
            DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistNName, 1024);

            var options = new TestExecutionOptions <DMLibDataInfo>();

            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                options.DestTransferDataInfo = destDataInfo;
            }

            options.TransferItemModifier = (fileNode, transferItem) =>
            {
                string          fileName        = fileNode.Name;
                TransferContext transferContext = new TransferContext();

                if (fileName.Equals(destExistYName))
                {
                    transferContext.OverwriteCallback = DMLibInputHelper.GetDefaultOverwiteCallbackY();
                }
                else if (fileName.Equals(destExistNName))
                {
                    transferContext.OverwriteCallback = DMLibInputHelper.GetDefaultOverwiteCallbackN();
                }
                else if (fileName.Equals(destNotExistYName))
                {
                    transferContext.OverwriteCallback = DMLibInputHelper.GetDefaultOverwiteCallbackY();
                }

                transferItem.TransferContext = transferContext;
            };

            var result = this.ExecuteTestCase(sourceDataInfo, options);

            DMLibDataInfo expectedDataInfo = new DMLibDataInfo(string.Empty);

            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destExistYName));
                expectedDataInfo.RootNode.AddFileNode(destDataInfo.RootNode.GetFileNode(destExistNName));
                expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destNotExistYName));
            }
            else
            {
                expectedDataInfo = sourceDataInfo;
            }

            // Verify transfer result
            Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, result.DataInfo), "Verify transfer result.");

            // Verify exception
            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                Test.Assert(result.Exceptions.Count == 1, "Verify there's only one exceptions.");
                TransferException transferException = result.Exceptions[0] as TransferException;
                Test.Assert(transferException != null, "Verify the exception is a TransferException");

                VerificationHelper.VerifyTransferException(transferException, TransferErrorCode.NotOverwriteExistingDestination,
                                                           "Skiped file", destExistNName);
            }
        }
        public void DirectoryOverwriteDestination()
        {
            string destExistYName    = "destExistY";
            string destExistNName    = "destExistN";
            string destNotExistYName = "destNotExistY";

            DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty);

            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistYName, 1024);
            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistNName, 1024);
            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destNotExistYName, 1024);

            DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty);

            DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistYName, 1024);
            DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistNName, 1024);

            TransferContext transferContext = new TransferContext();

            transferContext.OverwriteCallback = (string sourcePath, string destinationPath) =>
            {
                if (sourcePath.EndsWith(destExistNName))
                {
                    return(false);
                }
                else
                {
                    return(true);
                }
            };

            int skipCount    = 0;
            int successCount = 0;

            transferContext.FileSkipped += (object sender, TransferEventArgs args) =>
            {
                Interlocked.Increment(ref skipCount);
                TransferException transferException = args.Exception as TransferException;
                Test.Assert(transferException != null, "Verify the exception is a TransferException");

                VerificationHelper.VerifyTransferException(transferException, TransferErrorCode.NotOverwriteExistingDestination,
                                                           "Skiped file", destExistNName);
            };

            transferContext.FileTransferred += (object sender, TransferEventArgs args) =>
            {
                Interlocked.Increment(ref successCount);
            };

            var options = new TestExecutionOptions <DMLibDataInfo>();

            options.IsDirectoryTransfer = true;
            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                options.DestTransferDataInfo = destDataInfo;
            }

            options.TransferItemModifier = (fileNode, transferItem) =>
            {
                transferItem.TransferContext = transferContext;

                dynamic transferOptions = DefaultTransferDirectoryOptions;
                transferOptions.Recursive = true;
                transferItem.Options      = transferOptions;
            };

            var result = this.ExecuteTestCase(sourceDataInfo, options);

            DMLibDataInfo expectedDataInfo = new DMLibDataInfo(string.Empty);

            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destExistYName));
                expectedDataInfo.RootNode.AddFileNode(destDataInfo.RootNode.GetFileNode(destExistNName));
                expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destNotExistYName));
            }
            else
            {
                expectedDataInfo = sourceDataInfo;
            }

            // Verify transfer result
            Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, result.DataInfo), "Verify transfer result.");

            // Verify exception
            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                Test.Assert(successCount == 2, "Verify success transfers");
                Test.Assert(skipCount == 1, "Verify skipped transfer");
            }
            else
            {
                Test.Assert(successCount == 3, "Very all transfers are success");
                Test.Assert(skipCount == 0, "Very no transfer is skipped");
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Enumerates the files present in the storage location referenced by this object.
        /// </summary>
        /// <param name="cancellationToken">CancellationToken to cancel the method.</param>
        /// <returns>Enumerable list of TransferEntry objects found in the storage location referenced by this object.</returns>
        public IEnumerable <TransferEntry> EnumerateLocation(CancellationToken cancellationToken)
        {
            Utils.CheckCancellation(cancellationToken);

            string filePattern = string.IsNullOrEmpty(this.SearchPattern) ? DefaultFilePattern : this.SearchPattern;

            SearchOption         searchOption        = this.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
            IEnumerable <string> directoryEnumerator = null;
            ErrorEntry           errorEntry          = null;

            Utils.CheckCancellation(cancellationToken);

#if DOTNET5_4
            string fullPath = null;
            if (Interop.CrossPlatformHelpers.IsWindows)
            {
                fullPath = LongPath.ToUncPath(this.location.DirectoryPath);
            }
            else
            {
                fullPath = Path.GetFullPath(this.location.DirectoryPath);
            }
#else
            string fullPath = LongPath.ToUncPath(this.location.DirectoryPath);
#endif
            fullPath = AppendDirectorySeparator(fullPath);

            try
            {
                // Directory.GetFiles/EnumerateFiles will be broken when encounted special items, such as
                // files in recycle bins or the folder "System Volume Information". Rewrite this function
                // because our listing should not be stopped by these unexpected files.
                directoryEnumerator = EnumerateDirectoryHelper.EnumerateFiles(
                    fullPath,
                    filePattern,
                    this.listContinuationToken == null ? null : this.listContinuationToken.FilePath,
                    searchOption,
                    cancellationToken);
            }
            catch (Exception ex)
            {
                string errorMessage = string.Format(
                    CultureInfo.CurrentCulture,
                    Resources.FailedToEnumerateDirectory,
                    this.location.DirectoryPath,
                    filePattern);

                TransferException exception =
                    new TransferException(TransferErrorCode.FailToEnumerateDirectory, errorMessage, ex);
                errorEntry = new ErrorEntry(exception);
            }

            if (null != errorEntry)
            {
                // We any exception we might get from Directory.GetFiles/
                // Directory.EnumerateFiles. Just return an error entry
                // to indicate error occured in this case.
                yield return(errorEntry);
            }

            if (null != directoryEnumerator)
            {
                foreach (string entry in directoryEnumerator)
                {
                    Utils.CheckCancellation(cancellationToken);

                    string relativePath = entry;

                    if (relativePath.StartsWith(fullPath, StringComparison.OrdinalIgnoreCase))
                    {
                        relativePath = relativePath.Remove(0, fullPath.Length);
                    }

                    var continuationToken = new FileListContinuationToken(relativePath);
                    if (relativePath.Length > Constants.MaxRelativePathLength)
                    {
                        relativePath = relativePath.Substring(0, Constants.MaxRelativePathLength / 2) + "..." + relativePath.Substring(relativePath.Length - Constants.MaxRelativePathLength / 2);
                    }

                    yield return(new FileEntry(
                                     relativePath,
                                     LongPath.Combine(this.location.DirectoryPath, relativePath),
                                     continuationToken));
                }
            }
        }
Ejemplo n.º 14
0
        private IEnumerable <TransferEntry> EnumerateLocationRecursive(CancellationToken cancellationToken)
        {
            string fullPrefix = Uri.UnescapeDataString(this.location.FileDirectory.SnapshotQualifiedUri.AbsolutePath);

            // Normalize full prefix to end with slash.
            if (!string.IsNullOrEmpty(fullPrefix) && !fullPrefix.EndsWith("/", StringComparison.OrdinalIgnoreCase))
            {
                fullPrefix += '/';
            }

            Stack <CloudFileDirectory> directoriesToList = new Stack <CloudFileDirectory>();

            directoriesToList.Push(this.location.FileDirectory);

            string[] pathSegList             = null;
            bool     passedContinuationToken = false;
            int      pathSegListIndex        = 0;

            if (null != this.listContinuationToken)
            {
                pathSegList = this.listContinuationToken.FilePath.Split(new char[] { UriDelimiter });
            }
            else
            {
                passedContinuationToken = true;
            }

            while (0 != directoriesToList.Count)
            {
                CloudFileDirectory directory       = directoriesToList.Pop();
                string             dirAbsolutePath = Uri.UnescapeDataString(directory.SnapshotQualifiedUri.AbsolutePath);
                if (dirAbsolutePath[dirAbsolutePath.Length - 1] != UriDelimiter)
                {
                    dirAbsolutePath = dirAbsolutePath + UriDelimiter;
                }

                Stack <CloudFileDirectory> innerDirList = new Stack <CloudFileDirectory>();

                FileContinuationToken continuationToken = null;

                // To check whether reached continuation token by dir or file in this round.
                bool   checkFile            = false;
                bool   passedSubFolder      = false;
                string continuationTokenSeg = null;
                if (!passedContinuationToken)
                {
                    if (pathSegList.Length - 1 == pathSegListIndex)
                    {
                        checkFile = true;
                    }

                    continuationTokenSeg = pathSegList[pathSegListIndex];
                    pathSegListIndex++;
                }

                do
                {
                    FileResultSegment resultSegment = null;
                    Utils.CheckCancellation(cancellationToken);

                    ErrorEntry errorEntry = null;

                    try
                    {
                        FileRequestOptions requestOptions = Transfer_RequestOptions.DefaultFileRequestOptions;
                        resultSegment = directory.ListFilesAndDirectoriesSegmentedAsync(
                            ListFilesSegmentSize,
                            continuationToken,
                            requestOptions,
                            null,
                            cancellationToken).Result;
                    }
                    catch (Exception ex)
                    {
                        string errorMessage = string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.FailedToEnumerateDirectory,
                            this.location.FileDirectory.SnapshotQualifiedUri.AbsoluteUri,
                            string.Empty);

                        TransferException exception =
                            new TransferException(TransferErrorCode.FailToEnumerateDirectory, errorMessage, ex);
                        errorEntry = new ErrorEntry(exception);
                    }

                    if (null != errorEntry)
                    {
                        yield return(errorEntry);

                        yield break;
                    }

                    continuationToken = resultSegment.ContinuationToken;

                    foreach (IListFileItem fileItem in resultSegment.Results)
                    {
                        Utils.CheckCancellation(cancellationToken);

                        if (fileItem is CloudFileDirectory)
                        {
                            if (checkFile || passedContinuationToken || passedSubFolder)
                            {
                                innerDirList.Push(fileItem as CloudFileDirectory);
                            }
                            else
                            {
                                CloudFileDirectory cloudDir = fileItem as CloudFileDirectory;
                                string             fullPath = Uri.UnescapeDataString(cloudDir.SnapshotQualifiedUri.AbsolutePath);
                                string             segName  = fullPath.Remove(0, dirAbsolutePath.Length);

                                int compareResult = string.Compare(segName, continuationTokenSeg, StringComparison.OrdinalIgnoreCase);

                                if (compareResult >= 0)
                                {
                                    passedSubFolder = true;
                                    innerDirList.Push(cloudDir);

                                    if (compareResult > 0)
                                    {
                                        passedContinuationToken = true;
                                    }
                                }
                            }
                        }
                        else if (fileItem is CloudFile)
                        {
                            if (!checkFile && !passedContinuationToken)
                            {
                                continue;
                            }

                            CloudFile cloudFile = fileItem as CloudFile;

                            string fullPath     = Uri.UnescapeDataString(cloudFile.SnapshotQualifiedUri.AbsolutePath);
                            string relativePath = fullPath.Remove(0, fullPrefix.Length);

                            if (passedContinuationToken)
                            {
                                yield return(new AzureFileEntry(
                                                 relativePath,
                                                 cloudFile,
                                                 new AzureFileListContinuationToken(relativePath)));
                            }
                            else
                            {
                                string segName       = fullPath.Remove(0, dirAbsolutePath.Length);
                                int    compareResult = string.Compare(segName, continuationTokenSeg, StringComparison.OrdinalIgnoreCase);

                                if (compareResult < 0)
                                {
                                    continue;
                                }

                                passedContinuationToken = true;

                                if (compareResult > 0)
                                {
                                    yield return(new AzureFileEntry(
                                                     relativePath,
                                                     cloudFile,
                                                     new AzureFileListContinuationToken(relativePath)));
                                }
                            }
                        }
                    }
                }while (continuationToken != null);

                if (checkFile)
                {
                    passedContinuationToken = true;
                }

                if (innerDirList.Count <= 0)
                {
                    if (!checkFile && !passedContinuationToken)
                    {
                        passedContinuationToken = true;
                    }
                }
                else
                {
                    while (innerDirList.Count > 0)
                    {
                        directoriesToList.Push(innerDirList.Pop());
                    }
                }
            }
        }
        public void OverwriteDestination()
        {
            string destExistYName    = "destExistY";
            string destExistNName    = "destExistN";
            string destNotExistYName = "destNotExistY";

            DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty);

            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistYName, 1024);
            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistNName, 1024);
            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destNotExistYName, 1024);

            DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty);

            DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistYName, 1024);
            DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistNName, 1024);

            var options = new TestExecutionOptions <DMLibDataInfo>();

            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                options.DestTransferDataInfo = destDataInfo;
            }

            options.TransferItemModifier = (fileNode, transferItem) =>
            {
                string          fileName        = fileNode.Name;
                TransferContext transferContext = new SingleTransferContext();

                if (fileName.Equals(destExistYName))
                {
                    transferContext.ShouldOverwriteCallbackAsync = DMLibInputHelper.GetDefaultOverwiteCallbackY();
                }
                else if (fileName.Equals(destExistNName))
                {
                    transferContext.ShouldOverwriteCallbackAsync = DMLibInputHelper.GetDefaultOverwiteCallbackN();
                }
                else if (fileName.Equals(destNotExistYName))
                {
                    transferContext.ShouldOverwriteCallbackAsync = DMLibInputHelper.GetDefaultOverwiteCallbackY();
                }

                transferItem.TransferContext = transferContext;

                dynamic transferOptions = DefaultTransferOptions;

                if (DMLibTestContext.SourceType == DMLibDataType.CloudFile &&
                    DMLibTestContext.DestType == DMLibDataType.CloudFile)
                {
                    transferOptions.PreserveSMBAttributes  = true;
                    transferOptions.PreserveSMBPermissions = true;
                }

                transferItem.Options = transferOptions;
            };

            var result = this.ExecuteTestCase(sourceDataInfo, options);

            DMLibDataInfo expectedDataInfo = new DMLibDataInfo(string.Empty);

            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destExistYName));
                expectedDataInfo.RootNode.AddFileNode(destDataInfo.RootNode.GetFileNode(destExistNName));
                expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destNotExistYName));
            }
            else
            {
                expectedDataInfo = sourceDataInfo;
            }

            // Verify transfer result
            Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, result.DataInfo), "Verify transfer result.");

            // Verify exception
            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                Test.Assert(result.Exceptions.Count == 1, "Verify there's only one exceptions.");
                TransferException transferException = result.Exceptions[0] as TransferException;
                Test.Assert(transferException != null, "Verify the exception is a TransferException");

                VerificationHelper.VerifyTransferException(transferException, TransferErrorCode.NotOverwriteExistingDestination,
                                                           "Skipped file", destExistNName);
            }

            if (DMLibTestContext.SourceType == DMLibDataType.CloudFile &&
                DMLibTestContext.DestType == DMLibDataType.CloudFile)
            {
                Helper.CompareSMBProperties(expectedDataInfo.RootNode, result.DataInfo.RootNode, true);
                Helper.CompareSMBPermissions(
                    expectedDataInfo.RootNode,
                    result.DataInfo.RootNode,
                    PreserveSMBPermissions.Owner | PreserveSMBPermissions.Group | PreserveSMBPermissions.DACL | PreserveSMBPermissions.SACL);
            }
        }
        public void DirectoryOverwriteDestination()
        {
            string destExistYName    = "destExistY";
            string destExistNName    = "destExistN";
            string destNotExistYName = "destNotExistY";

            DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty);

            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistYName, 1024);
            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistNName, 1024);
            DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destNotExistYName, 1024);

            DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty);

            DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistYName, 1024);
            DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistNName, 1024);

            TransferContext transferContext = new DirectoryTransferContext();

            transferContext.ShouldOverwriteCallbackAsync = async(source, destination) =>
            {
                if (DMLibTestHelper.TransferInstanceToString(source).EndsWith(destExistNName))
                {
                    return(false);
                }
                else
                {
                    return(true);
                }
            };

            int skipCount    = 0;
            int successCount = 0;

            transferContext.FileSkipped += (object sender, TransferEventArgs args) =>
            {
                Interlocked.Increment(ref skipCount);
                TransferException transferException = args.Exception as TransferException;
                Test.Assert(transferException != null, "Verify the exception is a TransferException");

                VerificationHelper.VerifyTransferException(transferException, TransferErrorCode.NotOverwriteExistingDestination,
                                                           "Skipped file", destExistNName);
            };

            transferContext.FileTransferred += (object sender, TransferEventArgs args) =>
            {
                Interlocked.Increment(ref successCount);
            };

            var options = new TestExecutionOptions <DMLibDataInfo>();

            options.IsDirectoryTransfer = true;
            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                options.DestTransferDataInfo = destDataInfo;
            }

            options.TransferItemModifier = (fileNode, transferItem) =>
            {
                transferItem.TransferContext = transferContext;

                dynamic transferOptions = DefaultTransferDirectoryOptions;
                transferOptions.Recursive = true;

                if (DMLibTestContext.SourceType == DMLibDataType.CloudFile &&
                    DMLibTestContext.DestType == DMLibDataType.CloudFile)
                {
                    transferOptions.PreserveSMBAttributes  = true;
                    transferOptions.PreserveSMBPermissions = true;
                }

                transferItem.Options         = transferOptions;
                transferItem.TransferContext = transferContext;
            };

            var result = this.ExecuteTestCase(sourceDataInfo, options);

            DMLibDataInfo expectedDataInfo = new DMLibDataInfo(string.Empty);

            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destExistYName));
                expectedDataInfo.RootNode.AddFileNode(destDataInfo.RootNode.GetFileNode(destExistNName));
                expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destNotExistYName));
            }
            else
            {
                expectedDataInfo = sourceDataInfo;
            }

            // Verify transfer result
            Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, result.DataInfo), "Verify transfer result.");

            // Verify exception
            if (DMLibTestContext.DestType != DMLibDataType.Stream)
            {
                VerificationHelper.VerifySingleTransferStatus(result, 2, 1, 0, 1024 * 2);
                Test.Assert(successCount == 2, "Verify success transfers");
                Test.Assert(skipCount == 1, "Verify skipped transfer");
            }
            else
            {
                VerificationHelper.VerifySingleTransferStatus(result, 3, 0, 0, 1024 * 3);
                Test.Assert(successCount == 3, "Very all transfers are success");
                Test.Assert(skipCount == 0, "Very no transfer is skipped");
            }

            if (DMLibTestContext.SourceType == DMLibDataType.CloudFile &&
                DMLibTestContext.DestType == DMLibDataType.CloudFile)
            {
                Helper.CompareSMBProperties(expectedDataInfo.RootNode, result.DataInfo.RootNode, true);
                Helper.CompareSMBPermissions(
                    expectedDataInfo.RootNode,
                    result.DataInfo.RootNode,
                    PreserveSMBPermissions.Owner | PreserveSMBPermissions.Group | PreserveSMBPermissions.DACL | PreserveSMBPermissions.SACL);
            }
        }
Ejemplo n.º 17
0
        private IEnumerable <TransferEntry> EnumerateLocationRecursive(CancellationToken cancellationToken)
        {
            string fullPrefix = null;

            if (null != this.baseDirectory)
            {
                fullPrefix = Uri.UnescapeDataString(this.baseDirectory.SnapshotQualifiedUri.AbsolutePath);
            }
            else
            {
                fullPrefix = Uri.UnescapeDataString(this.location.FileDirectory.SnapshotQualifiedUri.AbsolutePath);
            }

            // Normalize full prefix to end with slash.
            if (!string.IsNullOrEmpty(fullPrefix) && !fullPrefix.EndsWith("/", StringComparison.OrdinalIgnoreCase))
            {
                fullPrefix += '/';
            }

            CloudFileDirectory directory = this.location.FileDirectory;

            Stack <CloudFileDirectory> innerDirList = new Stack <CloudFileDirectory>();

            FileContinuationToken continuationToken = null;
            bool passedContinuationToken            = false;

            if (null == this.listContinuationToken)
            {
                passedContinuationToken = true;
            }

            do
            {
                FileResultSegment resultSegment = null;
                Utils.CheckCancellation(cancellationToken);

                ErrorEntry errorEntry = null;

                try
                {
                    FileRequestOptions requestOptions = Transfer_RequestOptions.DefaultFileRequestOptions;
                    resultSegment = directory.ListFilesAndDirectoriesSegmentedAsync(
                        ListFilesSegmentSize,
                        continuationToken,
                        requestOptions,
                        null,
                        cancellationToken).Result;
                }
                catch (Exception ex)
                {
                    string errorMessage = string.Format(
                        CultureInfo.CurrentCulture,
                        Resources.FailedToEnumerateDirectory,
                        directory.SnapshotQualifiedUri.AbsoluteUri,
                        string.Empty);

                    TransferException exception =
                        new TransferException(TransferErrorCode.FailToEnumerateDirectory, errorMessage, ex);
                    errorEntry = new ErrorEntry(exception);
                }

                if (null != errorEntry)
                {
                    yield return(errorEntry);

                    yield break;
                }

                continuationToken = resultSegment.ContinuationToken;

                foreach (IListFileItem fileItem in resultSegment.Results)
                {
                    Utils.CheckCancellation(cancellationToken);

                    if (fileItem is CloudFileDirectory)
                    {
                        CloudFileDirectory cloudDir = fileItem as CloudFileDirectory;

                        if (!passedContinuationToken)
                        {
                            if (string.Equals(cloudDir.Name, this.listContinuationToken.FilePath, StringComparison.Ordinal))
                            {
                                passedContinuationToken = true;
                                continue;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        string fullPath     = Uri.UnescapeDataString(cloudDir.SnapshotQualifiedUri.AbsolutePath);
                        string relativePath = fullPath.Remove(0, fullPrefix.Length);

                        yield return(new AzureFileDirectoryEntry(
                                         relativePath,
                                         cloudDir,
                                         new AzureFileListContinuationToken(cloudDir.Name)));
                    }
                    else if (fileItem is CloudFile)
                    {
                        CloudFile cloudFile = fileItem as CloudFile;

                        if (!passedContinuationToken)
                        {
                            if (string.Equals(cloudFile.Name, this.listContinuationToken.FilePath, StringComparison.Ordinal))
                            {
                                passedContinuationToken = true;
                                continue;
                            }
                            else
                            {
                                continue;
                            }
                        }

                        string fullPath     = Uri.UnescapeDataString(cloudFile.SnapshotQualifiedUri.AbsolutePath);
                        string relativePath = fullPath.Remove(0, fullPrefix.Length);

                        yield return(new AzureFileEntry(
                                         relativePath,
                                         cloudFile,
                                         new AzureFileListContinuationToken(cloudFile.Name)));
                    }
                }
            }while (continuationToken != null);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ErrorEntry" /> class.
 /// </summary>
 /// <param name="ex">Exception to store.</param>
 public ErrorEntry(TransferException ex)
     : base(null, null)
 {
     this.Exception = ex;
 }
        /// <summary>
        /// Enumerates the files present in the storage location referenced by this object.
        /// </summary>
        /// <param name="cancellationToken">CancellationToken to cancel the method.</param>
        /// <returns>Enumerable list of TransferEntry objects found in the storage location referenced by this object.</returns>
        public IEnumerable<TransferEntry> EnumerateLocation(CancellationToken cancellationToken)
        {
            Utils.CheckCancellation(cancellationToken);

            string filePattern = string.IsNullOrEmpty(this.SearchPattern) ? DefaultFilePattern : this.SearchPattern;

            // Exceed-limit-length patterns surely match no files.
            int maxFileNameLength = this.GetMaxFileNameLength();
            if (filePattern.Length > maxFileNameLength)
            {
                yield break;
            }

            SearchOption searchOption = this.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
            IEnumerable<string> directoryEnumerator = null;
            ErrorEntry errorEntry = null;

            Utils.CheckCancellation(cancellationToken);

            string fullPath = Path.GetFullPath(this.location.DirectoryPath);
            fullPath = AppendDirectorySeparator(fullPath);

            try
            {
                // Directory.GetFiles/EnumerateFiles will be broken when encounted special items, such as
                // files in recycle bins or the folder "System Volume Information". Rewrite this function
                // because our listing should not be stopped by these unexpected files.
                directoryEnumerator = EnumerateDirectoryHelper.EnumerateFiles(
                    fullPath,
                    filePattern,
                    this.listContinuationToken == null ? null : this.listContinuationToken.FilePath,
                    searchOption,
                    cancellationToken);
            }
            catch (Exception ex)
            {
                string errorMessage = string.Format(
                    CultureInfo.CurrentCulture,
                    Resources.FailedToEnumerateDirectory,
                    this.location.DirectoryPath,
                    filePattern);

                TransferException exception =
                    new TransferException(TransferErrorCode.FailToEnumerateDirectory, errorMessage, ex);
                errorEntry = new ErrorEntry(exception);
            }

            if (null != errorEntry)
            {
                // We any exception we might get from Directory.GetFiles/
                // Directory.EnumerateFiles. Just return an error entry
                // to indicate error occured in this case. 
                yield return errorEntry;
            }

            if (null != directoryEnumerator)
            {
                foreach (string entry in directoryEnumerator)
                {
                    Utils.CheckCancellation(cancellationToken);

                    string relativePath = entry;

                    if (relativePath.StartsWith(fullPath, StringComparison.OrdinalIgnoreCase))
                    {
                        relativePath = relativePath.Remove(0, fullPath.Length);
                    }

                    yield return new FileEntry(
                        relativePath,
                        Path.Combine(this.location.DirectoryPath, relativePath),
                        new FileListContinuationToken(relativePath));
                }
            }
        }