public WriteErrorDialogViewModel GetWriteErrorDialogViewModel(TransferException exception) { return(new WriteErrorDialogViewModel { SourceFilePath = exception.SourceFile, TargetFilePath = exception.TargetFile }); }
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); }
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))); } }
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; } }
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); }
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"); } }
/// <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)); } } }
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); } }
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> /// 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)); } } }