-
Notifications
You must be signed in to change notification settings - Fork 2k
/
AzureBlobLeaseProviderOptions.cs
169 lines (150 loc) · 7.07 KB
/
AzureBlobLeaseProviderOptions.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
using System;
using System.Threading.Tasks;
using Azure;
using Azure.Core;
using Azure.Storage;
using Azure.Storage.Blobs;
using Microsoft.Extensions.Options;
using Orleans.Runtime;
using Orleans.Streaming.AzureStorage;
namespace Orleans.Configuration
{
/// <summary>
/// Options for configuring a lease provider backed by Azure Blob Storage leases.
/// </summary>
public class AzureBlobLeaseProviderOptions
{
private BlobServiceClient _blobServiceClient;
public string BlobContainerName { get; set; } = DefaultBlobContainerName;
public const string DefaultBlobContainerName = "Leases";
/// <summary>
/// Options to be used when configuring the blob storage client, or <see langword="null"/> to use the default options.
/// </summary>
[Obsolete($"Set the {nameof(BlobServiceClient)} property directly.")]
public BlobClientOptions ClientOptions { get; set; }
/// <summary>
/// The optional delegate used to create a <see cref="BlobServiceClient"/> instance.
/// </summary>
internal Func<Task<BlobServiceClient>> CreateClient { get; private set; }
/// <summary>
/// Gets or sets the client used to access the Azure Blob Service.
/// </summary>
public BlobServiceClient BlobServiceClient
{
get => _blobServiceClient;
set
{
_blobServiceClient = value;
CreateClient = () => Task.FromResult(value);
}
}
/// <summary>
/// Configures the <see cref="BlobServiceClient"/> using a connection string.
/// </summary>
[Obsolete($"Set the {nameof(BlobServiceClient)} property directly.")]
public void ConfigureBlobServiceClient(string connectionString)
{
BlobServiceClient = new BlobServiceClient(connectionString, ClientOptions);
}
/// <summary>
/// Configures the <see cref="BlobServiceClient"/> using an authenticated service URI.
/// </summary>
[Obsolete($"Set the {nameof(BlobServiceClient)} property directly.")]
public void ConfigureBlobServiceClient(Uri serviceUri)
{
BlobServiceClient = new BlobServiceClient(serviceUri, ClientOptions);
}
/// <summary>
/// Configures the <see cref="BlobServiceClient"/> using the provided callback.
/// </summary>
[Obsolete($"Set the {nameof(BlobServiceClient)} property directly.")]
public void ConfigureBlobServiceClient(Func<Task<BlobServiceClient>> createClientCallback)
{
CreateClient = createClientCallback ?? throw new ArgumentNullException(nameof(createClientCallback));
}
/// <summary>
/// Configures the <see cref="BlobServiceClient"/> using an authenticated service URI and a <see cref="Azure.Core.TokenCredential"/>.
/// </summary>
[Obsolete($"Set the {nameof(BlobServiceClient)} property directly.")]
public void ConfigureBlobServiceClient(Uri serviceUri, TokenCredential tokenCredential)
{
BlobServiceClient = new BlobServiceClient(serviceUri, tokenCredential, ClientOptions);
}
/// <summary>
/// Configures the <see cref="BlobServiceClient"/> using an authenticated service URI and a <see cref="Azure.AzureSasCredential"/>.
/// </summary>
[Obsolete($"Set the {nameof(BlobServiceClient)} property directly.")]
public void ConfigureBlobServiceClient(Uri serviceUri, AzureSasCredential azureSasCredential)
{
BlobServiceClient = new BlobServiceClient(serviceUri, azureSasCredential, ClientOptions);
}
/// <summary>
/// Configures the <see cref="BlobServiceClient"/> using an authenticated service URI and a <see cref="StorageSharedKeyCredential"/>.
/// </summary>
[Obsolete($"Set the {nameof(BlobServiceClient)} property directly.")]
public void ConfigureBlobServiceClient(Uri serviceUri, StorageSharedKeyCredential sharedKeyCredential)
{
BlobServiceClient = new BlobServiceClient(serviceUri, sharedKeyCredential, ClientOptions);
}
}
/// <summary>
/// Configuration validator for AzureBlobLeaseProviderOptions
/// </summary>
public class AzureBlobLeaseProviderOptionsValidator : IConfigurationValidator
{
private readonly AzureBlobLeaseProviderOptions options;
private readonly string name;
/// <summary>
/// Constructor
/// </summary>
/// <param name="options">The option to be validated.</param>
public AzureBlobLeaseProviderOptionsValidator(IOptions<AzureBlobLeaseProviderOptions> options)
{
this.options = options.Value;
}
/// <summary>
/// Creates creates validator for named instance of AzureBlobLeaseProviderOptions options.
/// </summary>
/// <param name="services"></param>
/// <param name="name"></param>
/// <returns></returns>
public static IConfigurationValidator Create(IServiceProvider services, string name)
{
var options = services.GetOptionsByName<AzureBlobLeaseProviderOptions>(name);
return new AzureBlobLeaseProviderOptionsValidator(options, name);
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="options">The option to be validated.</param>
/// <param name="name">The option name to be validated.</param>
private AzureBlobLeaseProviderOptionsValidator(AzureBlobLeaseProviderOptions options, string name)
{
this.options = options;
this.name = name ?? string.Empty;
}
public void ValidateConfiguration()
{
// name can be null, but not empty or white space.
if(this.name != null && string.IsNullOrWhiteSpace(this.name))
{
throw new OrleansConfigurationException($"Named option {nameof(AzureBlobLeaseProviderOptions)} of name {this.name} is invalid. Name cannot be empty or whitespace.");
}
if (this.options.CreateClient is null)
{
throw new OrleansConfigurationException($"No credentials specified for Azure Blob Service lease provider \"{name}\". Use the {options.GetType().Name}.{nameof(AzureBlobLeaseProviderOptions.ConfigureBlobServiceClient)} method to configure the Azure Blob Service client.");
}
try
{
AzureBlobUtils.ValidateContainerName(this.options.BlobContainerName);
}
catch (ArgumentException e)
{
var errorStr = string.IsNullOrEmpty(this.name)
? $"Configuration for {nameof(AzureBlobLeaseProviderOptions)} {this.name} is invalid. {nameof(this.options.BlobContainerName)} is not valid"
: $"Configuration for {nameof(AzureBlobLeaseProviderOptions)} is invalid. {nameof(this.options.BlobContainerName)} is not valid";
throw new OrleansConfigurationException(errorStr , e);
}
}
}
}