GroupDocsGists
10/19/2017 - 11:14 AM

AzureInputDataHandler.cs

// For complete examples and data files, please go to https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET
/// <summary>
/// The implementation of GroupDocs.Viewer data handler for Azure Blob Storage.
/// </summary>
public class AzureInputDataHandler : IInputDataHandler
{
        /// <summary>
        /// The blob delimiter.
        /// </summary>
        private const char Delimiter = '/';
        /// <summary>
        /// The endpoint template.
        /// </summary>
        private const string EndpointTemplate = "https://{account-name}.blob.core.windows.net/";
        /// <summary>
        /// The cloud blob container.
        /// </summary>
        private readonly CloudBlobContainer _container;
        /// <summary>
        /// Initializes a new instance of the <see cref="AzureInputDataHandler"/> class.
        /// </summary>
        /// <param name="accountName"></param>
        /// <param name="accountKey"></param>
        /// <param name="containerName"></param>
        public AzureInputDataHandler(string accountName, string accountKey, string containerName)
            : this(GetEndpoint(accountName), accountName, accountKey, containerName)
        {
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AzureInputDataHandler"/> class.
        /// </summary>
        /// <param name="endpoint">The endpoint e.g. https://youraccountname.blob.core.windows.net/ </param>
        /// <param name="accountName">The account name.</param>
        /// <param name="accountKey">The account key.</param>
        /// <param name="containerName">The container name.</param>
        public AzureInputDataHandler(Uri endpoint, string accountName, string accountKey, string containerName)
        {
            try
            {
                StorageCredentials storageCredentials = new StorageCredentials(accountName, accountKey);
                CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(storageCredentials, endpoint, null, null, null);
                CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
                TimeSpan? serverTimeout = cloudBlobClient.DefaultRequestOptions.ServerTimeout;
                cloudBlobClient.DefaultRequestOptions.ServerTimeout = TimeSpan.FromSeconds(10);
                _container = cloudBlobClient.GetContainerReference(containerName);
                _container.CreateIfNotExists();
                cloudBlobClient.DefaultRequestOptions.ServerTimeout = serverTimeout;
            }
            catch (StorageException e)
            {
                throw new System.Exception("Unable to recognize that Account Name/Account Key or container name is invalid.", e);
            }
            catch (FormatException e)
            {
                throw new System.Exception("Unable to recognize that Account Name/Account Key.", e);
            }
        }
        /// <summary>
        /// Gets the file description.
        /// </summary>
        /// <param name="guid">The unique identifier.</param>
        /// <returns>GroupDocs.Viewer.Domain.FileDescription.</returns>
        public FileDescription GetFileDescription(string guid)
        {
            try
            {
                string blobName = GetNormalizedBlobName(guid);
                CloudBlob blob = _container.GetBlobReference(blobName);
                blob.FetchAttributes();
                return new FileDescription(blobName, false)
                {
                    LastModificationDate = GetDateTimeOrEmptyDate(blob.Properties.LastModified),
                    Size = blob.Properties.Length
                };
            }
            catch (StorageException ex)
            {
                throw new System.Exception("Unabled to get file description.", ex);
            }
        }
        public Stream GetFile(string guid)
        {
            try
            {
                string blobName = GetNormalizedBlobName(guid);
                CloudBlob blob = _container.GetBlobReference(blobName);
                MemoryStream memoryStream = new MemoryStream();
                blob.DownloadToStream(memoryStream);
                memoryStream.Position = 0;
                return memoryStream;
            }
            catch (StorageException ex)
            {
                throw new System.Exception("Unabled to get file.", ex);
            }
        }
        /// <summary>
        /// Gets the last modification date.
        /// </summary>
        /// <param name="guid">The unique identifier.</param>
        /// <returns>System.DateTime.</returns>
        public DateTime GetLastModificationDate(string guid)
        {
            FileDescription fileDescription = GetFileDescription(guid);
            return fileDescription.LastModificationDate;
        }
        /// <summary>
        /// Loads files/folders structure for specified path
        /// </summary>
        /// <param name="fileTreeOptions">The file tree options.</param>
        /// <returns>System.Collections.Generic.List&lt;GroupDocs.Viewer.Domain.FileDescription&gt;.</returns>
        public List<FileDescription> LoadFileTree(FileTreeOptions fileTreeOptions)
        {
            try
            {
                string path = GetNormalizedBlobName(fileTreeOptions.Path);
                List<FileDescription> fileTree = GetFileTree(path);
                switch (fileTreeOptions.OrderBy)
                {
                    case FileTreeOptions.FileTreeOrderBy.Name:
                        fileTree = fileTreeOptions.OrderAsc
                            ? fileTree.OrderBy(_ => _.Name).ToList()
                            : fileTree.OrderByDescending(_ => _.Name).ToList();
                        break;
                    case FileTreeOptions.FileTreeOrderBy.LastModificationDate:
                        fileTree = fileTreeOptions.OrderAsc
                            ? fileTree.OrderBy(_ => _.LastModificationDate).ToList()
                            : fileTree.OrderByDescending(_ => _.LastModificationDate).ToList();
                        break;
                    case FileTreeOptions.FileTreeOrderBy.Size:
                        fileTree = fileTreeOptions.OrderAsc
                            ? fileTree.OrderBy(_ => _.Size).ToList()
                            : fileTree.OrderByDescending(_ => _.Size).ToList();
                        break;
                    default:
                        break;
                }
                return fileTree;
            }
            catch (StorageException ex)
            {
                throw new System.Exception("Failed to load file tree.", ex);
            }
        }
        /// <summary>
        /// Gets the endpoint e.g. https://youraccountname.blob.core.windows.net/
        /// </summary>
        /// <param name="accountName">The account name.</param>
        /// <returns>Endpoint Uri.</returns>
        private static Uri GetEndpoint(string accountName)
        {
            string endpoint = EndpointTemplate.Replace("{account-name}", accountName);
            return new Uri(endpoint);
        }
        /// <summary>
        /// Gets the file tree.
        /// </summary>
        /// <param name="blobName">The blob name.</param>
        /// <returns>The file tree.</returns>
        private List<FileDescription> GetFileTree(string blobName)
        {
            CloudBlobDirectory directory = _container.GetDirectoryReference(blobName);
            List<FileDescription> fileTree = new List<FileDescription>();
            foreach (IListBlobItem blob in directory.ListBlobs())
            {
                FileDescription fileDescription;
                CloudBlobDirectory blobDirectory = blob as CloudBlobDirectory;
                if (blobDirectory != null)
                {
                    fileDescription = new FileDescription(blobDirectory.Prefix, true);
                }
                else
                {
                    ICloudBlob blobFile = (ICloudBlob)blob;
                    fileDescription = new FileDescription(blobFile.Name, false)
                    {
                        Size = blobFile.Properties.Length,
                        LastModificationDate = GetDateTimeOrEmptyDate(blobFile.Properties.LastModified)
                    };
                }
                fileTree.Add(fileDescription);
            }
            return fileTree;
        }
        /// <summary>
/// <summary>
    /// The implementation of GroupDocs.Viewer data handler for Azure Blob Storage.
    /// </summary>
    public class AzureInputDataHandler : IInputDataHandler
    {
        /// <summary>
        /// The blob delimiter.
        /// </summary>
        private const char Delimiter = '/';
        /// <summary>
        /// The endpoint template.
        /// </summary>
        private const string EndpointTemplate = "https://{account-name}.blob.core.windows.net/";
        /// <summary>
        /// The cloud blob container.
        /// </summary>
        private readonly CloudBlobContainer _container;
        /// <summary>
        /// Initializes a new instance of the <see cref="AzureInputDataHandler"/> class.
        /// </summary>
        /// <param name="accountName"></param>
        /// <param name="accountKey"></param>
        /// <param name="containerName"></param>
        public AzureInputDataHandler(string accountName, string accountKey, string containerName)
            : this(GetEndpoint(accountName), accountName, accountKey, containerName)
        {
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AzureInputDataHandler"/> class.
        /// </summary>
        /// <param name="endpoint">The endpoint e.g. https://youraccountname.blob.core.windows.net/ </param>
        /// <param name="accountName">The account name.</param>
        /// <param name="accountKey">The account key.</param>
        /// <param name="containerName">The container name.</param>
        public AzureInputDataHandler(Uri endpoint, string accountName, string accountKey, string containerName)
        {
            try
            {
                StorageCredentials storageCredentials = new StorageCredentials(accountName, accountKey);
                CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(storageCredentials, endpoint, null, null, null);
                CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
                TimeSpan? serverTimeout = cloudBlobClient.DefaultRequestOptions.ServerTimeout;
                cloudBlobClient.DefaultRequestOptions.ServerTimeout = TimeSpan.FromSeconds(10);
                _container = cloudBlobClient.GetContainerReference(containerName);
                _container.CreateIfNotExists();
                cloudBlobClient.DefaultRequestOptions.ServerTimeout = serverTimeout;
            }
            catch (StorageException e)
            {
                throw new System.Exception("Unable to recognize that Account Name/Account Key or container name is invalid.", e);
            }
            catch (FormatException e)
            {
                throw new System.Exception("Unable to recognize that Account Name/Account Key.", e);
            }
        }
        /// <summary>
        /// Gets the file description.
        /// </summary>
        /// <param name="guid">The unique identifier.</param>
        /// <returns>GroupDocs.Viewer.Domain.FileDescription.</returns>
        public FileDescription GetFileDescription(string guid)
        {
            try
            {
                string blobName = GetNormalizedBlobName(guid);
                CloudBlob blob = _container.GetBlobReference(blobName);
                blob.FetchAttributes();
                return new FileDescription(blobName, false)
                {
                    LastModificationDate = GetDateTimeOrEmptyDate(blob.Properties.LastModified),
                    Size = blob.Properties.Length
                };
            }
            catch (StorageException ex)
            {
                throw new System.Exception("Unabled to get file description.", ex);
            }
        }
        public Stream GetFile(string guid)
        {
            try
            {
                string blobName = GetNormalizedBlobName(guid);
                CloudBlob blob = _container.GetBlobReference(blobName);
                MemoryStream memoryStream = new MemoryStream();
                blob.DownloadToStream(memoryStream);
                memoryStream.Position = 0;
                return memoryStream;
            }
            catch (StorageException ex)
            {
                throw new System.Exception("Unabled to get file.", ex);
            }
        }
        /// <summary>
        /// Gets the last modification date.
        /// </summary>
        /// <param name="guid">The unique identifier.</param>
        /// <returns>System.DateTime.</returns>
        public DateTime GetLastModificationDate(string guid)
        {
            FileDescription fileDescription = GetFileDescription(guid);
            return fileDescription.LastModificationDate;
        }
        /// <summary>
        /// Gets files and folders for specified path.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>System.Collections.Generic.List&lt;GroupDocs.Viewer.Domain.FileDescription&gt;.</returns>
        public List<FileDescription> GetEntities(string path)
        {
            try
            {
                string normalizedPath = GetNormalizedBlobName(path);
                return GetFilesAndDirectories(normalizedPath);
            }
            catch (StorageException ex)
            {
                throw new System.Exception("Failed to load file tree.", ex);
            }
        }

        /// <summary>
        /// Gets the file tree.
        /// </summary>
        /// <param name="blobName">The blob name.</param>
        /// <returns>The file tree.</returns>
        private List<FileDescription> GetFilesAndDirectories(string blobName)
        {
            CloudBlobDirectory directory = _container.GetDirectoryReference(blobName);
            List<FileDescription> fileTree = new List<FileDescription>();
            foreach (IListBlobItem blob in directory.ListBlobs())
            {
                FileDescription fileDescription;
                CloudBlobDirectory blobDirectory = blob as CloudBlobDirectory;
                if (blobDirectory != null)
                {
                    fileDescription = new FileDescription(blobDirectory.Prefix, true);
                }
                else
                {
                    ICloudBlob blobFile = (ICloudBlob)blob;
                    fileDescription = new FileDescription(blobFile.Name, false)
                    {
                        Size = blobFile.Properties.Length,
                        LastModificationDate = GetDateTimeOrEmptyDate(blobFile.Properties.LastModified)
                    };
                }
                fileTree.Add(fileDescription);
            }
            return fileTree;
        }
        /// <summary>
        /// Gets normalized blob name, updates guid from dir\\file.ext to dir/file.ext
        /// </summary>
        /// <param name="guid">The unique identifier.</param>
        /// <returns>Normalized blob name.</returns>
        private string GetNormalizedBlobName(string guid)
        {
            return Regex.Replace(guid, @"\\+", Delimiter.ToString()).Trim(Delimiter);
        }

        /// <summary>
        /// Gets the endpoint e.g. https://youraccountname.blob.core.windows.net/
        /// </summary>
        /// <param name="accountName">The account name.</param>
        /// <returns>Endpoint Uri.</returns>
        private static Uri GetEndpoint(string accountName)
        {
            string endpoint = EndpointTemplate.Replace("{account-name}", accountName);
            return new Uri(endpoint);
        }
        /// <summary>
        /// Gets the file tree.
        /// </summary>
        /// <param name="blobName">The blob name.</param>
        /// <returns>The file tree.</returns>
        private List<FileDescription> GetFileTree(string blobName)
        {
            CloudBlobDirectory directory = _container.GetDirectoryReference(blobName);
            List<FileDescription> fileTree = new List<FileDescription>();
            foreach (IListBlobItem blob in directory.ListBlobs())
            {
                FileDescription fileDescription;
                CloudBlobDirectory blobDirectory = blob as CloudBlobDirectory;
                if (blobDirectory != null)
                {
                    fileDescription = new FileDescription(blobDirectory.Prefix, true);
                }
                else
                {
                    ICloudBlob blobFile = (ICloudBlob)blob;
                    fileDescription = new FileDescription(blobFile.Name, false)
                    {
                        Size = blobFile.Properties.Length,
                        LastModificationDate = GetDateTimeOrEmptyDate(blobFile.Properties.LastModified)
                    };
                }
                fileTree.Add(fileDescription);
            }
            return fileTree;
        }
        /// <summary>
        /// Gets date time or empty date.
        /// </summary>
        /// <param name="dateTimeOffset">The date time offset.</param>
        /// <returns>Date time or empty date.</returns>
        private DateTime GetDateTimeOrEmptyDate(DateTimeOffset? dateTimeOffset)
        {
            DateTime emptyDate = new DateTime(1, 1, 1);
            return dateTimeOffset.HasValue ? dateTimeOffset.Value.DateTime : emptyDate;
        }

        public void SaveDocument(CachedDocumentDescription description, Stream stream)
        {
            //TODO
        }
        /// <summary>
        /// Adds file to storage.
        /// </summary>
        /// <param name="guid">This is user defined key that identifies file in the storage.</param>
        /// <param name="content">Stream to save data to storage.</param>
        public void AddFile(string guid, Stream content)
        {
            try
            {
                string blobName = GetNormalizedBlobName(guid);
                ICloudBlob blob = _container.GetBlockBlobReference(blobName);
                blob.UploadFromStream(content);
            }
            catch (StorageException ex)
            {
                throw new System.Exception("Unabled to add file.", ex);
            }
        }

        public List<FileDescription> LoadFileTree(FileListOptions fileListOptions)
        {
            //TODO
            return new List<FileDescription>();
        }
        [Obsolete]
        public List<FileDescription> LoadFileTree(FileTreeOptions fileTreeOptions)
        {
            //TODO
            return new List<FileDescription>();
        }
}