using Microsoft.Azure.Cosmos.Table; using Microsoft.Extensions.Options; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Text; using Microsoft.Extensions.DependencyInjection; using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using Azure.Storage.Blobs.Specialized; using Azure.Storage.Sas; using Azure.Storage; using TEAMModelOS.SDK.Extension; using Azure.Storage.Queues; using TEAMModelOS.SDK.Context.Attributes.Azure; using System.Threading.Tasks; using TEAMModelOS.SDK.Module.AzureBlob.Configuration; namespace TEAMModelOS.SDK.DI { public class AzureStorageFactory { private readonly IServiceProvider _services; private readonly IOptionsMonitor _optionsMonitor; private readonly ILogger _logger; public AzureStorageFactory(IServiceProvider services, IOptionsMonitor optionsMonitor, ILogger logger) { if (services == null) throw new ArgumentNullException(nameof(services)); if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor)); _services = services; _optionsMonitor = optionsMonitor; _logger = logger; } public BlobServiceClient GetBlobServiceClient(string name = "Default") { try { var options = _optionsMonitor.Get(name); return new BlobServiceClient(options.StorageAccountConnectionString); } catch (OptionsValidationException e) { _logger?.LogWarning(e, e.Message); return null; } } public BlobContainerClient GetBlobContainerClient(string containerName, string name = "Default") { try { var options = _optionsMonitor.Get(name); return new BlobContainerClient(options.StorageAccountConnectionString, containerName); } catch (OptionsValidationException e) { _logger?.LogWarning(e, e.Message); return null; } } public BlobBatchClient GetBlobBatchClient(string name = "Default") { try { var options = _optionsMonitor.Get(name); BlobServiceClient blobServiceClient = new BlobServiceClient(options.StorageAccountConnectionString); return blobServiceClient.GetBlobBatchClient(); } catch (OptionsValidationException e) { _logger?.LogWarning(e, e.Message); return null; } } /// /// 取得Blob Container SAS (有效期預設一天) /// /// 容器名稱 /// 權限(可多選)Flags /// /// public (string uri, string sas) GetBlobContainerSAS(string containerName, BlobContainerSasPermissions blobContainerSasPermissions, string name = "Default") { try { var keys = Utils.ParseConnectionString(_optionsMonitor.Get(name).StorageAccountConnectionString); var accountname = keys["AccountName"]; var accountkey = keys["AccountKey"]; var endpoint = keys["EndpointSuffix"]; var blobSasBuilder = new BlobSasBuilder { StartsOn = DateTimeOffset.UtcNow.Subtract(new TimeSpan(0, 15, 0)), ExpiresOn = DateTimeOffset.UtcNow.Add(new TimeSpan(1, 0, 15, 0)), BlobContainerName = containerName }; blobSasBuilder.SetPermissions(blobContainerSasPermissions); var sskc = new StorageSharedKeyCredential(accountname, accountkey); BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(sskc); UriBuilder fullUri = new UriBuilder() { Scheme = "https", Host = $"{accountname}.blob.{endpoint}", Path = containerName //Query = sasQueryParameters.ToString() }; return (fullUri.Uri.ToString(), sasQueryParameters.ToString()); } catch { return (null, null); } } /// /// 取得Blob Container SAS (有效期預設一天) /// /// 容器名稱 /// /// /// /// public BlobAuth GetContainerSasUri(BlobSas blobSas, bool isRead, string name = "Default") { try { string containerName = null; var keys = Utils.ParseConnectionString(_optionsMonitor.Get(name).StorageAccountConnectionString); var accountname = keys["AccountName"]; var accountkey = keys["AccountKey"]; var endpoint = keys["EndpointSuffix"]; if (blobSas.role == "system") { containerName = "teammodelos"; } else { containerName = blobSas.name.ToLower().Replace("#", ""); } DateTimeOffset dateTime = DateTimeOffset.UtcNow.Add(new TimeSpan(1, 0, 15, 0)); long time = dateTime.ToUnixTimeMilliseconds(); var blobSasBuilder = new BlobSasBuilder { StartsOn = DateTimeOffset.UtcNow.Subtract(new TimeSpan(0, 15, 0)), ExpiresOn = dateTime, BlobContainerName = containerName }; BlobContainerSasPermissions blobContainerSasPermissions = BlobContainerSasPermissions.Read; if (isRead) { blobContainerSasPermissions = BlobContainerSasPermissions.Read; } else { blobContainerSasPermissions = BlobContainerSasPermissions.Delete | BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Create | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List; } blobSasBuilder.SetPermissions(blobContainerSasPermissions); var sskc = new StorageSharedKeyCredential(accountname, accountkey); BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(sskc); UriBuilder fullUri = new UriBuilder() { Scheme = "https", Host = $"{accountname}.blob.{endpoint}", Path = containerName //Query = sasQueryParameters.ToString() }; return new BlobAuth { url = fullUri.Uri.ToString().Replace(fullUri.Uri.LocalPath, ""), sas = sasQueryParameters.ToString(), timeout = time, name = containerName }; // return (fullUri.Uri.ToString(), sasQueryParameters.ToString()); } catch { return null; } } /// /// 取得Blob SAS (有效期預設一天) /// /// 容器名稱 /// /// 權限(可多選)Flags /// /// public string GetBlobSAS(string containerName, string blobName, BlobSasPermissions blobSasPermissions, string name = "Default") { try { var keys = Utils.ParseConnectionString(_optionsMonitor.Get(name).StorageAccountConnectionString); var accountname = keys["AccountName"]; var accountkey = keys["AccountKey"]; var endpoint = keys["EndpointSuffix"]; var blobSasBuilder = new BlobSasBuilder { StartsOn = DateTimeOffset.UtcNow.Subtract(new TimeSpan(0, 15, 0)), ExpiresOn = DateTimeOffset.UtcNow.Add(new TimeSpan(1, 0, 15, 0)), BlobContainerName = containerName, BlobName = blobName }; blobSasBuilder.SetPermissions(blobSasPermissions); var sskc = new StorageSharedKeyCredential(accountname, accountkey); BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(sskc); UriBuilder fullUri = new UriBuilder() { Scheme = "https", Host = $"{accountname}.blob.{endpoint}", Path = $"{containerName}/{blobName}", Query = sasQueryParameters.ToString() }; return fullUri.Uri.ToString(); } catch { return null; } } /// /// 取得Blob SAS (有效期預設一天) /// /// 容器名稱 /// /// /// /// public BlobAuth GetBlobSasUriRead(string containerName, string blobName, string name = "Default") { try { var keys = Utils.ParseConnectionString(_optionsMonitor.Get(name).StorageAccountConnectionString); var accountname = keys["AccountName"]; var accountkey = keys["AccountKey"]; var endpoint = keys["EndpointSuffix"]; DateTimeOffset dateTime = DateTimeOffset.UtcNow.Add(new TimeSpan(365 * 99, 0, 15, 0)); long time = dateTime.ToUnixTimeMilliseconds(); var blobSasBuilder = new BlobSasBuilder { StartsOn = DateTimeOffset.UtcNow.Subtract(new TimeSpan(0, 15, 0)), ExpiresOn = dateTime, BlobContainerName = containerName, BlobName = blobName }; blobSasBuilder.SetPermissions(BlobSasPermissions.Read); var sskc = new StorageSharedKeyCredential(accountname, accountkey); BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(sskc); UriBuilder fullUri = new UriBuilder() { Scheme = "https", Host = $"{accountname}.blob.{endpoint}", Path = $"{containerName}/{blobName}", Query = sasQueryParameters.ToString() }; return new BlobAuth { url = fullUri.Uri.ToString(), sas = sasQueryParameters.ToString(), timeout = time }; // return fullUri.Uri.ToString(); } catch { return null; } } public CloudTableClient GetCloudTableClient(string name = "Default") { try { var options = _optionsMonitor.Get(name); CloudStorageAccount storageAccount = CloudStorageAccount.Parse(options.StorageAccountConnectionString); return storageAccount.CreateCloudTableClient(); } catch (OptionsValidationException e) { _logger?.LogWarning(e, e.Message); return null; } } /// /// 可讓您管理儲存體帳戶中的所有佇列 /// /// /// public QueueServiceClient GetQueueServiceClient(string name = "Default") { try { var options = _optionsMonitor.Get(name); return new QueueServiceClient(options.StorageAccountConnectionString); } catch (OptionsValidationException e) { _logger?.LogWarning(e, e.Message); return null; } } /// /// 可讓您管理和操作個別佇列及其訊息 /// /// /// /// public QueueClient GetQueueClient(string queueName, string name = "Default") { if (name == null) throw new ArgumentNullException(nameof(name)); try { var options = _optionsMonitor.Get(name); return new QueueClient(options.StorageAccountConnectionString, queueName); } catch (OptionsValidationException e) { _logger?.LogWarning(e, e.Message); return null; } } public async Task InitializeTable() { string TableName = GetTableSpace(); CloudTable cloudTable = GetCloudTableClient().GetTableReference(TableName); await cloudTable.CreateIfNotExistsAsync(); return cloudTable; } private string GetTableSpace() { Type type = typeof(T); string Name = type.Name; object[] attributes = type.GetCustomAttributes(true); foreach (object attribute in attributes) //2.通过映射,找到成员属性上关联的特性类实例, { if (attribute is TableNameAttribute tableSpace) { Name = tableSpace.Name; } } return Name; } } }