1
- using Cofoundry . Core . Configuration ;
1
+ using Azure ;
2
+ using Azure . Storage . Blobs ;
3
+ using Azure . Storage . Blobs . Models ;
4
+ using Cofoundry . Core . Configuration ;
2
5
using Cofoundry . Domain . Data ;
3
- using Microsoft . Azure . Storage ;
4
- using Microsoft . Azure . Storage . Blob ;
5
6
using System ;
6
7
using System . Collections . Concurrent ;
7
8
using System . Collections . Generic ;
@@ -20,7 +21,7 @@ public class AzureBlobFileService : IFileStoreService
20
21
{
21
22
#region constructor
22
23
23
- private readonly CloudBlobClient _blobClient ;
24
+ private readonly BlobServiceClient _blobServiceClient ;
24
25
private static ConcurrentDictionary < string , byte > _initializedContainers = new ConcurrentDictionary < string , byte > ( ) ;
25
26
26
27
public AzureBlobFileService (
@@ -31,11 +32,10 @@ AzureSettings settings
31
32
32
33
if ( string . IsNullOrWhiteSpace ( settings . BlobStorageConnectionString ) )
33
34
{
34
- throw new InvalidConfigurationException ( typeof ( AzureSettings ) , "The BlobStorageConnectionString is required to use the AzureBlobFileService" ) ;
35
+ throw new InvalidConfigurationException ( typeof ( AzureSettings ) , $ "The { nameof ( settings . BlobStorageConnectionString ) } setting is required to use the { nameof ( AzureBlobFileService ) } ") ;
35
36
}
36
37
37
- var storageAccount = CloudStorageAccount . Parse ( settings . BlobStorageConnectionString ) ;
38
- _blobClient = storageAccount . CreateCloudBlobClient ( ) ;
38
+ _blobServiceClient = new BlobServiceClient ( settings . BlobStorageConnectionString ) ;
39
39
}
40
40
41
41
#endregion
@@ -51,9 +51,9 @@ AzureSettings settings
51
51
public async Task < bool > ExistsAsync ( string containerName , string fileName )
52
52
{
53
53
var container = await GetBlobContainerAsync ( containerName ) ;
54
- var blockBlob = container . GetBlockBlobReference ( fileName ) ;
54
+ var blobClient = container . GetBlobClient ( fileName ) ;
55
55
56
- return await blockBlob . ExistsAsync ( ) ;
56
+ return await blobClient . ExistsAsync ( ) ;
57
57
}
58
58
59
59
/// <summary>
@@ -65,22 +65,16 @@ public async Task<bool> ExistsAsync(string containerName, string fileName)
65
65
public async Task < Stream > GetAsync ( string containerName , string fileName )
66
66
{
67
67
var container = await GetBlobContainerAsync ( containerName ) ;
68
- CloudBlockBlob blockBlob = container . GetBlockBlobReference ( fileName ) ;
69
- Stream stream = null ;
68
+ var blobClient = container . GetBlobClient ( fileName ) ;
70
69
71
70
try
72
71
{
73
- return await blockBlob . OpenReadAsync ( ) ;
72
+ return await blobClient . OpenReadAsync ( ) ;
74
73
}
75
- catch ( StorageException ex )
74
+ catch ( RequestFailedException ex ) when ( ex . ErrorCode == BlobErrorCode . BlobNotFound )
76
75
{
77
- if ( ex . RequestInformation . HttpStatusCode != 404 )
78
- {
79
- throw ;
80
- }
76
+ return null ;
81
77
}
82
-
83
- return stream ;
84
78
}
85
79
86
80
/// <summary>
@@ -97,13 +91,13 @@ public Task CreateAsync(string containerName, string fileName, Stream stream)
97
91
public async Task CreateOrReplaceAsync ( string containerName , string fileName , Stream stream )
98
92
{
99
93
var container = await GetBlobContainerAsync ( containerName ) ;
100
- CloudBlockBlob blockBlob = container . GetBlockBlobReference ( fileName ) ;
94
+ var blockClient = container . GetBlobClient ( fileName ) ;
101
95
102
96
if ( stream . Position != 0 )
103
97
{
104
98
stream . Position = 0 ;
105
99
}
106
- await blockBlob . UploadFromStreamAsync ( stream ) ;
100
+ await blockClient . UploadAsync ( stream , true ) ;
107
101
}
108
102
109
103
/// <summary>
@@ -122,8 +116,9 @@ public Task CreateIfNotExistsAsync(string containerName, string fileName, Stream
122
116
public async Task DeleteAsync ( string containerName , string fileName )
123
117
{
124
118
var container = await GetBlobContainerAsync ( containerName ) ;
125
- CloudBlockBlob blockBlob = container . GetBlockBlobReference ( fileName ) ;
126
- await blockBlob . DeleteIfExistsAsync ( DeleteSnapshotsOption . IncludeSnapshots , null , null , null ) ;
119
+ var blockBlob = container . GetBlobClient ( fileName ) ;
120
+
121
+ await blockBlob . DeleteIfExistsAsync ( DeleteSnapshotsOption . IncludeSnapshots ) ;
127
122
}
128
123
129
124
/// <summary>
@@ -134,22 +129,15 @@ public async Task DeleteAsync(string containerName, string fileName)
134
129
public async Task DeleteDirectoryAsync ( string containerName , string directoryName )
135
130
{
136
131
var container = await GetBlobContainerAsync ( containerName ) ;
137
- var directory = container . GetDirectoryReference ( directoryName ) ;
138
132
139
- BlobContinuationToken continuationToken = null ;
140
- var blobs = new List < IListBlobItem > ( ) ;
133
+ var blobs = new List < BlobItem > ( ) ;
141
134
142
- do
135
+ await foreach ( var item in container . GetBlobsAsync ( BlobTraits . None , BlobStates . None , directoryName ) )
143
136
{
144
- // each segment is max 5000 items
145
- var segment = await directory . ListBlobsSegmentedAsync ( true , BlobListingDetails . None , null , continuationToken , null , null ) ;
146
- continuationToken = segment . ContinuationToken ;
147
- blobs . AddRange ( segment . Results ) ;
148
-
137
+ blobs . Add ( item ) ;
149
138
}
150
- while ( continuationToken != null ) ;
151
139
152
- await DeleteBlobsAsync ( blobs ) ;
140
+ await DeleteBlobsAsync ( container , blobs ) ;
153
141
}
154
142
155
143
/// <summary>
@@ -170,54 +158,36 @@ public async Task ClearContainerAsync(string containerName)
170
158
{
171
159
var container = await GetBlobContainerAsync ( containerName ) ;
172
160
173
- BlobContinuationToken continuationToken = null ;
174
- var blobs = new List < IListBlobItem > ( ) ;
161
+ var blobs = new List < BlobItem > ( ) ;
175
162
176
- do
163
+ await foreach ( var item in container . GetBlobsAsync ( ) )
177
164
{
178
- // each segment is max 5000 items
179
- var segment = await container . ListBlobsSegmentedAsync ( null , true , BlobListingDetails . None , null , continuationToken , null , null ) ;
180
- continuationToken = segment . ContinuationToken ;
181
- blobs . AddRange ( segment . Results ) ;
182
-
165
+ blobs . Add ( item ) ;
183
166
}
184
- while ( continuationToken != null ) ;
185
167
186
- await DeleteBlobsAsync ( blobs ) ;
168
+ await DeleteBlobsAsync ( container , blobs ) ;
187
169
}
188
170
189
171
#endregion
190
172
191
173
#region privates
192
174
193
- private async Task DeleteBlobsAsync ( IEnumerable < IListBlobItem > blobs )
175
+ private async Task DeleteBlobsAsync ( BlobContainerClient container , IEnumerable < BlobItem > blobs )
194
176
{
195
177
foreach ( var blobItem in blobs )
196
178
{
197
- var blockBlob = blobItem as CloudBlockBlob ;
198
- if ( blockBlob != null )
199
- {
200
- await blockBlob . DeleteIfExistsAsync ( DeleteSnapshotsOption . IncludeSnapshots , null , null , null ) ;
201
- }
202
- else
203
- {
204
- var pageBlob = blobItem as CloudPageBlob ;
205
- if ( pageBlob != null )
206
- {
207
- await pageBlob . DeleteIfExistsAsync ( DeleteSnapshotsOption . IncludeSnapshots , null , null , null ) ;
208
- }
209
- }
179
+ await container . DeleteBlobIfExistsAsync ( blobItem . Name , DeleteSnapshotsOption . IncludeSnapshots ) ;
210
180
}
211
181
}
212
182
213
183
private async Task CreateAsync ( string containerName , string fileName , Stream stream , bool throwExceptionIfNotExists )
214
184
{
215
185
var container = await GetBlobContainerAsync ( containerName ) ;
216
- var blockBlob = container . GetBlockBlobReference ( fileName ) ;
186
+ var blobClient = container . GetBlobClient ( fileName ) ;
217
187
218
188
// Don't overwrite:
219
189
// http://stackoverflow.com/a/14938608/716689
220
- var accessCondition = AccessCondition . GenerateIfNotExistsCondition ( ) ;
190
+ // var accessCondition = AccessCondition.GenerateIfNotExistsCondition();
221
191
222
192
try
223
193
{
@@ -226,25 +196,22 @@ private async Task CreateAsync(string containerName, string fileName, Stream str
226
196
stream . Position = 0 ;
227
197
}
228
198
229
- await blockBlob . UploadFromStreamAsync ( stream , accessCondition , null , null ) ;
199
+ await blobClient . UploadAsync ( stream ) ;
200
+ //await blobClient.UploadFromStreamAsync(stream, accessCondition, null, null);
230
201
}
231
- catch ( StorageException ex )
202
+ catch ( RequestFailedException ex ) when ( ex . ErrorCode == BlobErrorCode . BlobAlreadyExists )
232
203
{
233
- if ( ex . RequestInformation . HttpStatusCode == 409 )
234
- {
235
- if ( throwExceptionIfNotExists ) throw new InvalidOperationException ( "File already exists" , ex ) ;
236
- }
237
- else
204
+ if ( throwExceptionIfNotExists )
238
205
{
239
- throw ;
206
+ throw new InvalidOperationException ( "File already exists" , ex ) ;
240
207
}
241
208
}
242
209
}
243
210
244
- private async Task < CloudBlobContainer > GetBlobContainerAsync ( string containerName )
211
+ private async Task < BlobContainerClient > GetBlobContainerAsync ( string containerName )
245
212
{
246
213
containerName = containerName . ToLower ( ) ;
247
- var container = _blobClient . GetContainerReference ( containerName ) ;
214
+ var container = _blobServiceClient . GetBlobContainerClient ( containerName ) ;
248
215
249
216
// initalize container
250
217
if ( _initializedContainers . TryAdd ( containerName , 0 ) )
0 commit comments