public IAsyncEnumerable <IFile> GetFiles(AlphaNumericString tag) { return(new AsyncEnumerable <IFile>(async yield => { var container = GetContainer(tag); if (!await container.ExistsAsync()) { yield.Break(); } BlobContinuationToken continuationToken = null; do { var blobs = await container .ListBlobsSegmentedAsync(continuationToken) .ConfigureAwait(false); foreach (var blob in blobs.Results.OfType <CloudBlockBlob>()) { await blob.FetchAttributesAsync(yield.CancellationToken); await yield.ReturnAsync(new CloudBlobFile(blob)).ConfigureAwait(false); } continuationToken = blobs.ContinuationToken; } while (continuationToken != null); })); }
private async Task CreateFilesAsync(AlphaNumericString tag, IEnumerable <IFile> files) { foreach (var file in files) { Assert.True(await Storage.CreateFileAsync(file, tag)); } }
/// <summary> /// Creates the <paramref name="file"/> at the SFTP backend. The file we be /// located in the path `<paramref name="tag"/>` relative to the <see cref="RootDirectory"/>. /// If a file with the same name as the given <paramref name="file"/> already exist, /// that file will be deleted. /// </summary> /// <param name="file">The file to create at the SFTP backend.</param> /// <param name="tag">The name of the folder relative to the <see cref="RootDirectory"/> that the file will be uploaded to. The tag will be escaped.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// A flag indicating whether the file was successfully uploaded or not. /// </returns> public async Task <bool> CreateFileAsync(IFile file, AlphaNumericString tag, CancellationToken cancellationToken = default) { ThrowIfDisposed(); ConnectIfDisconnected(); if (file == null) { throw new ArgumentNullException(nameof(file)); } var tagPath = GetTagPath(tag); if (!_sftpClient.Exists(tagPath)) { _sftpClient.CreateDirectory(tagPath); } var filePath = GetFilePath(file, tag); using (var stream = await file.OpenReadStreamAsync(cancellationToken)) { await _sftpClient.UploadFileAsync(filePath, stream, cancellationToken); } return(true); }
public async Task <bool> DeleteFileAsync(IFileInfo file, AlphaNumericString tag, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); ConnectIfDisconnected(); var filePath = GetFilePath(file, tag); cancellationToken.ThrowIfCancellationRequested(); if (!_sftpClient.Exists(filePath)) { return(false); } cancellationToken.ThrowIfCancellationRequested(); _sftpClient.DeleteFile(filePath); if (tag != string.Empty) { var tagPath = GetTagPath(tag); var filesInTag = await _sftpClient.ListDirectoryAsync(GetTagPath(tag), cancellationToken); if (!filesInTag.Any(f => f.Name != ".." && f.Name != ".")) { _sftpClient.DeleteDirectory(tagPath); } } return(true); }
private CloudBlobContainer GetContainer(AlphaNumericString tag) { /* * A container name must be a valid DNS name, conforming to the following naming rules: * * Container names must start with a letter or number, and can contain only letters, numbers, and the dash (-) character. * Every dash (-) character must be immediately preceded and followed by a letter or number; consecutive dashes are not permitted in container names. * All letters in a container name must be lowercase. * Container names must be from 3 through 63 characters long. */ const int minLength = 3; const int maxLength = 63; const char paddingChar = '0'; var containerName = tag.ToLower(); if (containerName == string.Empty) { containerName = EmptyContainer; } if (containerName.Length < minLength) { containerName = containerName.PadRight(minLength, paddingChar); } if (containerName.Length > maxLength) { containerName = containerName.Substring(0, maxLength); } return(_client.GetContainerReference(containerName)); }
public Task MoveFileAsync(IFileInfo file, AlphaNumericString tag, AlphaNumericString destinationTag, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); ConnectIfDisconnected(); var filePath = GetFilePath(file, tag); cancellationToken.ThrowIfCancellationRequested(); if (!_sftpClient.Exists(filePath)) { return(Task.FromResult(0)); } var destinationTagPath = GetTagPath(destinationTag); cancellationToken.ThrowIfCancellationRequested(); if (!_sftpClient.Exists(destinationTagPath)) { cancellationToken.ThrowIfCancellationRequested(); _sftpClient.CreateDirectory(destinationTagPath); } cancellationToken.ThrowIfCancellationRequested(); var sftpFile = _sftpClient.Get(filePath); cancellationToken.ThrowIfCancellationRequested(); sftpFile.MoveTo(GetFilePath(file, destinationTag)); return(Task.FromResult(0)); }
public async Task <bool> DeleteTagAsync(AlphaNumericString tag, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); ConnectIfDisconnected(); var path = GetTagPath(tag); if (!_sftpClient.Exists(path)) { return(false); } var files = await _sftpClient.ListDirectoryAsync(path, cancellationToken); foreach (var file in files.Where(f => f.IsRegularFile)) { file.Delete(); } if (!files.Any(f => f.IsDirectory()) && tag != string.Empty) { _sftpClient.DeleteDirectory(path); } return(true); }
public virtual Task <bool> CreateFileAsync(IFile file, AlphaNumericString tag, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); if (file == null) { throw new ArgumentNullException(nameof(file)); } IFile pgpFile; if (SupportsSigning && SupportsEncryption) { pgpFile = file.ToSignedAndEncrypted(PublicKey, PrivateKey, Password); } else if (SupportsSigning) { pgpFile = file.ToSigned(PrivateKey, Password); } else { pgpFile = file.ToEncrypted(PublicKey); } return(Storage.CreateFileAsync(pgpFile, tag, cancellationToken)); }
public async Task GetGetFilesWithInvalidContainerName(AlphaNumericString tag) { try { await Storage.GetFiles(tag).FirstOrDefaultAsync(); } catch { Assert.False(true, "Expected storage to pad the tag to necessary length."); } }
public async Task <bool> DeleteFileAsync(IFileInfo file, AlphaNumericString tag, CancellationToken cancellationToken = default) { var container = GetContainer(tag); if (!await container.ExistsAsync(cancellationToken)) { return(false); } var fileReference = container.GetBlockBlobReference(file.FileName); return(await fileReference.DeleteIfExistsAsync(cancellationToken)); }
public async Task CreateAsync(Guid id, string mark, string model, float capacity, DateTime dateOc, DateTime dateReview, int carType) { if (carType != Convert.ToInt32(CarType.Car) && carType != Convert.ToInt32(CarType.SmallTruck) && carType != Convert.ToInt32(CarType.Truck)) { throw new Exception($"Car Type: '{carType}' is invalid."); } var markAlphaNumericString = new AlphaNumericString(mark); var modelAlphaNumericString = new AlphaNumericString(model); var @car = new Car(id, markAlphaNumericString, modelAlphaNumericString, capacity, dateOc, dateReview, carType); await _carRepository.AddAsync(@car); }
public async Task <bool> CreateFileAsync(IFile file, AlphaNumericString tag, CancellationToken cancellationToken = default) { var container = GetContainer(tag); await container.CreateIfNotExistsAsync(cancellationToken); var fileReference = container.GetBlockBlobReference(file.FileName); fileReference.Properties.ContentType = file.ContentType; using (var readStream = await file.OpenReadStreamAsync(cancellationToken)) { await fileReference.UploadFromStreamAsync(readStream, cancellationToken); } return(true); }
public async Task <IFile> GetFileAsync(IFileInfo fileInfo, AlphaNumericString tag, CancellationToken cancellationToken = default) { var container = GetContainer(tag); if (!await container.ExistsAsync(cancellationToken)) { return(null); } var file = container.GetBlockBlobReference(fileInfo.FileName); if (!await file.ExistsAsync(cancellationToken)) { return(null); } return(new CloudBlobFile(file)); }
public Task <IFile> GetFileAsync(IFileInfo fileInfo, AlphaNumericString tag, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); ConnectIfDisconnected(); var filePath = GetFilePath(fileInfo, tag); cancellationToken.ThrowIfCancellationRequested(); if (!_sftpClient.Exists(filePath)) { return(Task.FromResult <IFile>(null)); } cancellationToken.ThrowIfCancellationRequested(); var file = _sftpClient.Get(filePath); return(Task.FromResult <IFile>(new SftpRegularFile(_sftpClient.ConnectionInfo, file))); }
public async Task UpdateAsync(Guid id, string mark, string model, float capacity, DateTime dateOc, DateTime dateReview, int carType) { var @car = await _carRepository.GetOrFailAsync(id); if (carType != Convert.ToInt32(CarType.Car) && carType != Convert.ToInt32(CarType.SmallTruck) && carType != Convert.ToInt32(CarType.Truck)) { throw new Exception($"Car Type: '{carType}' is invalid."); } var markAlphaNumericString = new AlphaNumericString(mark); var modelAlphaNumericString = new AlphaNumericString(model); @car.setMark(markAlphaNumericString); @car.setModel(modelAlphaNumericString); @car.setCapacity(capacity); @car.setDateOc(dateOc); @car.setDateReview(dateReview); @car.setCarType(carType); await _carRepository.UpdateAsync(@car); }
public IAsyncEnumerable <IFile> GetFiles(AlphaNumericString tag) { ThrowIfDisposed(); ConnectIfDisconnected(); var tagPath = GetTagPath(tag); if (!_sftpClient.Exists(tagPath)) { return(AsyncEnumerable.Empty <IFile>()); } return(new AsyncEnumerable <IFile>(async yield => { var files = await _sftpClient.ListDirectoryAsync(tagPath, yield.CancellationToken); foreach (var file in files.Where(f => f.IsRegularFile)) { await yield.ReturnAsync(new SftpRegularFile(_sftpClient.ConnectionInfo, file)); } })); }
public async Task MoveFileAsync(IFileInfo file, AlphaNumericString tag, AlphaNumericString destinationTag, CancellationToken cancellationToken = default) { var container = GetContainer(tag); if (!await container.ExistsAsync(cancellationToken)) { return; } var cloudBlobFile = container.GetBlockBlobReference(file.FileName); if (!await cloudBlobFile.ExistsAsync(cancellationToken)) { return; } var destinationContainer = GetContainer(destinationTag); await destinationContainer.CreateIfNotExistsAsync(cancellationToken); var destinationBlob = destinationContainer.GetBlockBlobReference(file.FileName); await destinationBlob.StartCopyAsync(cloudBlobFile, cancellationToken); await cloudBlobFile.DeleteAsync(cancellationToken); }
public TagWithFiles(AlphaNumericString tag, IEnumerable <IFile> files) { Tag = tag; Files = files.ToArray(); }
/// <summary> /// Creates the given <paramref name="file"/> and associates /// the file with the given <paramref name="tag"/> synchronously. /// </summary> /// <param name="storage">The storage to create the file at.</param> /// <param name="file">The file to create.</param> /// <param name="tag">The tag to associate the file with.</param> /// <returns> /// A flag indicating whether the file was successfully created or not. /// </returns> public static bool CreateFile(this IStorage storage, IFile file, AlphaNumericString tag) => AsyncHelpers.RunSync(() => storage.CreateFileAsync(file, tag));
/// <summary> /// Re-associates the given <paramref name="file"/>, currently associated with the given <paramref name="tag"/>, /// with the <paramref name="destinationTag"/>, synchronously. /// </summary> /// <param name="storage">The storage the file is located at.</param> /// <param name="file">The file to re-associate with a new tag.</param> /// <param name="tag">The tag the file is currently associated with.</param> /// <param name="destinationTag">The tag that the file should be re-associated with.</param> public static void MoveFile(this IStorage storage, IFileInfo file, AlphaNumericString tag, AlphaNumericString destinationTag) => AsyncHelpers .RunSync(() => storage.MoveFileAsync(file, tag, destinationTag));
public Task <bool> DeleteTagAsync(AlphaNumericString tag, CancellationToken cancellationToken = default) { return(_storage.DeleteTagAsync(tag, cancellationToken)); }
/// <summary> /// Creates a prefixed storage of the given <paramref name="storage"/> which /// will prefix all the tags. /// </summary> /// <param name="storage">The storage to prefix.</param> /// <param name="prefix">The prefix.</param> /// <returns>A prefixed storage which will add the given <paramref name="prefix"/> to the tags.</returns> public static IStorage PrefixWith(this IStorage storage, AlphaNumericString prefix) { return(new PrefixedStorage(storage, prefix)); }
/// <summary> /// Moves the given <paramref name="fileInfo"/> located at the given <paramref name="storage"/> /// to the <paramref name="destination"/> storage /// where it will be associated with the given <paramref name="destinationTag"/>. /// This will delete the file from the <paramref name="storage"/> the file is currently located at. /// </summary> /// <param name="storage">The storage the file is currently located at.</param> /// <param name="fileInfo">The file that should be moved.</param> /// <param name="tag">The tag the file is currently associated with.</param> /// <param name="destination">The storage the file will be moved to.</param> /// <param name="destinationTag">The tag the file should be associated with at the destination storage.</param> public static async Task MoveFileAsync(this IStorage storage, IFileInfo fileInfo, AlphaNumericString tag, IStorage destination, AlphaNumericString destinationTag) { var file = await storage.GetFileAsync(fileInfo, tag); if (file == null) { return; } await destination.CreateFileAsync(file, destinationTag); await storage.DeleteFileAsync(file, tag); }
public Task MoveFileAsync(IFileInfo file, AlphaNumericString tag, AlphaNumericString destinationTag, CancellationToken cancellationToken = default) { return(_storage.MoveFileAsync(file, tag, destinationTag, cancellationToken)); }
public IAsyncEnumerable <IFile> GetFiles(AlphaNumericString tag) => _storage.GetFiles(tag);
/// <summary> /// Returns the file corresponding to the given <paramref name="file"/> from the /// given <paramref name="storage"/>, synchronously. /// </summary> /// <param name="storage">The storage the file is located at.</param> /// <param name="file">The file to retrieve.</param> /// <param name="tag">The tag the file is associated with.</param> /// <returns> /// The corresponding file or null if the file couldn't be found. /// </returns> public static IFile GetFile(this IStorage storage, IFileInfo file, AlphaNumericString tag) => AsyncHelpers .RunSync(() => storage.GetFileAsync(file, tag));
public async Task <bool> DeleteTagAsync(AlphaNumericString tag, CancellationToken cancellationToken = default) { var container = GetContainer(tag); return(await container.DeleteIfExistsAsync(cancellationToken)); }
/// <summary> /// Deletes the given <paramref name="tag"/> from the given <paramref name="storage"/> /// synchronously. /// </summary> /// <param name="storage">The storage to delete the tag from.</param> /// <param name="tag">The tag to delete.</param> /// <returns> /// A flag indicating whether the tag was successfully deleted or not. /// </returns> public static bool DeleteTag(this IStorage storage, AlphaNumericString tag) => AsyncHelpers .RunSync(() => storage.DeleteTagAsync(tag));
public Task <IFile> GetFileAsync(IFileInfo file, AlphaNumericString tag, CancellationToken cancellationToken = default) { return(_storage.GetFileAsync(file, tag, cancellationToken)); }
public Task <bool> CreateFileAsync(IFile file, AlphaNumericString tag, CancellationToken cancellationToken = default) { return(_storage.CreateFileAsync(file, tag, cancellationToken)); }