-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathAzureStorageAttachmentConfiguration.cs
128 lines (108 loc) · 6.62 KB
/
AzureStorageAttachmentConfiguration.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
namespace Microsoft.Azure.ServiceBus
{
using System;
using Storage;
using Storage.Auth;
/// <summary>Runtime configuration for Azure Storage Attachment plugin.</summary>
public class AzureStorageAttachmentConfiguration
{
/// <summary>Constructor to create new configuration object.</summary>
/// <param name="connectionString"></param>
/// <param name="containerName"></param>
/// <param name="messagePropertyToIdentifyAttachmentBlob"></param>
/// <param name="messageMaxSizeReachedCriteria">Default is always use attachments</param>
public AzureStorageAttachmentConfiguration(
string connectionString,
string containerName = AzureStorageAttachmentConfigurationConstants.DefaultContainerName,
string messagePropertyToIdentifyAttachmentBlob = AzureStorageAttachmentConfigurationConstants.DefaultMessagePropertyToIdentifyAttachmentBlob,
Func<Message, bool>? messageMaxSizeReachedCriteria = default)
: this(new PlainTextConnectionStringProvider(connectionString), containerName, messagePropertyToIdentifyAttachmentBlob, messageMaxSizeReachedCriteria)
{
}
/// <summary>Constructor to create new configuration object.</summary>
/// <remarks>Container name is not required as it's included in the SharedAccessSignature.</remarks>
/// <param name="storageCredentials"></param>
/// <param name="blobEndpoint">Blob endpoint in the format of "https://account.blob.core.windows.net/". For the emulator the value is "http://127.0.0.1:10000/devstoreaccount1".</param>
/// <param name="containerName"></param>
/// <param name="messagePropertyToIdentifyAttachmentBlob"></param>
/// <param name="messageMaxSizeReachedCriteria">Default is always use attachments</param>
public AzureStorageAttachmentConfiguration(
StorageCredentials storageCredentials,
string blobEndpoint,
string containerName = AzureStorageAttachmentConfigurationConstants.DefaultContainerName,
string messagePropertyToIdentifyAttachmentBlob = AzureStorageAttachmentConfigurationConstants.DefaultMessagePropertyToIdentifyAttachmentBlob,
Func<Message, bool>? messageMaxSizeReachedCriteria = default)
{
Guard.AgainstNull(nameof(storageCredentials), storageCredentials);
Guard.AgainstEmpty(nameof(blobEndpoint), blobEndpoint);
Guard.AgainstEmpty(nameof(containerName), containerName);
Guard.AgainstEmpty(nameof(messagePropertyToIdentifyAttachmentBlob), messagePropertyToIdentifyAttachmentBlob);
StorageCredentials = storageCredentials;
BlobEndpoint = EnsureBlobEndpointEndsWithSlash(blobEndpoint);
ContainerName = containerName;
MessagePropertyToIdentifyAttachmentBlob = messagePropertyToIdentifyAttachmentBlob;
MessageMaxSizeReachedCriteria = GetMessageMaxSizeReachedCriteria(messageMaxSizeReachedCriteria);
}
static Uri EnsureBlobEndpointEndsWithSlash(string blobEndpoint)
{
if (blobEndpoint.EndsWith("/", StringComparison.OrdinalIgnoreCase))
{
return new Uri(blobEndpoint);
}
// Emulator blob endpoint doesn't end with slash
return new Uri(blobEndpoint + "/");
}
/// <summary>Constructor to create new configuration object.</summary>
/// <param name="connectionStringProvider">Provider to retrieve connection string such as <see cref="PlainTextConnectionStringProvider"/></param>
/// <param name="containerName">Storage container name</param>
/// <param name="messagePropertyToIdentifyAttachmentBlob">Message user property to use for blob URI</param>
/// <param name="messageMaxSizeReachedCriteria">Default is always use attachments</param>
public AzureStorageAttachmentConfiguration(
IProvideStorageConnectionString connectionStringProvider,
string containerName = AzureStorageAttachmentConfigurationConstants.DefaultContainerName,
string messagePropertyToIdentifyAttachmentBlob = AzureStorageAttachmentConfigurationConstants.DefaultMessagePropertyToIdentifyAttachmentBlob,
Func<Message, bool>? messageMaxSizeReachedCriteria = default)
{
Guard.AgainstNull(nameof(connectionStringProvider), connectionStringProvider);
Guard.AgainstEmpty(nameof(containerName), containerName);
Guard.AgainstEmpty(nameof(messagePropertyToIdentifyAttachmentBlob), messagePropertyToIdentifyAttachmentBlob);
var connectionString = connectionStringProvider.GetConnectionString().GetAwaiter().GetResult();
var account = CloudStorageAccount.Parse(connectionString);
ConnectionStringProvider = connectionStringProvider;
StorageCredentials = account.Credentials;
BlobEndpoint = EnsureBlobEndpointEndsWithSlash(account.BlobEndpoint.ToString());
ContainerName = containerName;
MessagePropertyToIdentifyAttachmentBlob = messagePropertyToIdentifyAttachmentBlob;
MessageMaxSizeReachedCriteria = GetMessageMaxSizeReachedCriteria(messageMaxSizeReachedCriteria);
}
Func<Message, bool> GetMessageMaxSizeReachedCriteria(Func<Message, bool>? messageMaxSizeReachedCriteria)
{
if (messageMaxSizeReachedCriteria == null)
{
return _ => true;
}
return message =>
{
try
{
return messageMaxSizeReachedCriteria(message);
}
catch (Exception exception)
{
throw new Exception("An exception occurred when executing the MessageMaxSizeReachedCriteria delegate.", exception);
}
};
}
internal IProvideStorageConnectionString? ConnectionStringProvider { get; }
internal string ContainerName { get; }
internal string? MessagePropertyForBlobSasUri { get; set; }
internal TimeSpan? BlobSasTokenValidationTime { get; set; }
internal string MessagePropertyToIdentifyAttachmentBlob { get; }
internal Func<Message, bool> MessageMaxSizeReachedCriteria { get; }
internal StorageCredentials StorageCredentials { get; }
internal bool UsingSas => StorageCredentials.IsSAS;
internal Uri BlobEndpoint { get; }
internal Func<Message, string> BlobNameResolver { get; set; } = message => Guid.NewGuid().ToString();
internal Func<Message, byte[]?> BodyReplacer { get; set; } = message => null;
}
}