Tuesday, December 19, 2017

Azure Storage Account File Storage Wrapper For Basic Functions

In one of our project we had to upload/download files to azure file storage.
Therefore, I build this small wrapper classes to make use of Azure file storage easy.

AzureStorageAccountClient

This client is supposed to provide function to connect to different storage account such as (Blob, File and etc storage)


    public class AzureStorageAccountClient
    {
        private readonly ILogger logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        public AzureStorageAccountClient(string connectionString)
        {
            ConnectionString = connectionString;
        }

        public string ConnectionString { get; }

        public IAzureStorageShareClient FileClientConnect()
        {
            string message = string.Empty;
            try
            {
                return new AzureStorageShareClient(CloudStorageAccount.Parse(ConnectionString).CreateCloudFileClient());
            }
            catch (Exception ex)
            {
                logger.Critical("Error in Azure Client", ex);
                throw;
            }
        }
    }


AzureStorageShareClient

This class provides functions to perform on share storage client.


   public interface IAzureStorageShareClient
    {
        CloudFileClient CloudFileClient { get; }
    }

    public class AzureStorageShareClient : IAzureStorageShareClient
    {
        public AzureStorageShareClient(CloudFileClient cloudFileClient)
        {
            CloudFileClient = cloudFileClient;
        }

        public CloudFileClient CloudFileClient { get; }
    }   



AzureStorageFileDirectoryClient

This class provides functionality to different Directoy related operations.


    public interface IAzureStorageFileDirectoryClient
    {
        CloudFileShare CloudFileShare { get; }

        CloudFileDirectory CloudFileDirectory { get; set; }
    }

    public class AzureStorageFileDirectoryClient : IAzureStorageFileDirectoryClient
    {
        public AzureStorageFileDirectoryClient(CloudFileShare cloudFileShare)
        {
            CloudFileShare = cloudFileShare;
        }

        public CloudFileShare CloudFileShare { get; }

        public CloudFileDirectory CloudFileDirectory { get; set; }
    }


AzureStorageFileClient

This class provides functions to different File related operations


    public interface IAzureStorageFileClient
    {
        CloudFileDirectory CloudFileDirectory { get; set; }

        CloudFile CloudFile { get; }
    }

    public class AzureStorageFileClient : IAzureStorageFileClient
    {
        public AzureStorageFileClient(CloudFile cloudFile)
        {
            CloudFile = cloudFile;
        }

        public CloudFileDirectory CloudFileDirectory { get; set; }

        public CloudFile CloudFile { get; }
    }



As you have noted none of the above classes have any functions.
Below is the extension class that provides functions available to those interfaces.

AzureStorageAccountExtensions


    public static class AzureStorageAccountExtensions
    {
        public static async Task GetOrAddShare(this IAzureStorageShareClient client, string shareName)
        {
            var cloudFileShare = client.CloudFileClient.GetShareReference(shareName);
            await cloudFileShare.CreateIfNotExistsAsync().ConfigureAwait(false);
            return new AzureStorageFileDirectoryClient(cloudFileShare);
        }

        public static async Task GetOrAddFolder(this IAzureStorageFileDirectoryClient client, string folderPath)
        {
            var cloudRootDirectory = client.CloudFileShare.GetRootDirectoryReference();
            var cloudFileDirectory = cloudRootDirectory.GetDirectoryReference(folderPath);
            await cloudFileDirectory.CreateIfNotExistsAsync().ConfigureAwait(false);
            client.CloudFileDirectory = cloudFileDirectory;
            return client;
        }

        public static IEnumerable ListFiles(this IAzureStorageFileDirectoryClient client)
        {
            return client.CloudFileDirectory.ListFilesAndDirectories().Where(f => !f.Uri.LocalPath.Contains(".folder"));
        }

        public static async Task AddFile(this IAzureStorageFileDirectoryClient client, string fileName, long length)
        {
            await client.CloudFileDirectory.CreateIfNotExistsAsync().ConfigureAwait(false);

            var cloudFile = client.CloudFileDirectory.GetFileReference(fileName);
            if (!await cloudFile.ExistsAsync().ConfigureAwait(false))
            {
                await cloudFile.CreateAsync(length).ConfigureAwait(false);
            }

            return new AzureStorageFileClient(cloudFile);
        }

        public static async Task GetFile(this IAzureStorageFileDirectoryClient client, string fileName)
        {
            var cloudFile = client.CloudFileDirectory.GetFileReference(fileName);
            if (await cloudFile.ExistsAsync().ConfigureAwait(false))
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    await cloudFile.DownloadToStreamAsync(ms).ConfigureAwait(false);
                    return ms.ToArray();
                }
            }

            return null;
        }

        public static async void UploadFile(this IAzureStorageFileClient client, byte[] data)
        {
            await client.CloudFile.UploadFromByteArrayAsync(data, 0, data.Length).ConfigureAwait(false);
        }
    }