11using System ;
22using System . Collections . Generic ;
33using System . IO ;
4+ using System . Net ;
45using System . Runtime . CompilerServices ;
56using System . Threading ;
67using System . Threading . Tasks ;
@@ -19,20 +20,18 @@ public class AWSStorage : BaseStorage<AWSStorageOptions>, IAWSStorage
1920{
2021 private readonly ILogger < AWSStorage > ? _logger ;
2122
22- public IAmazonS3 StorageClient { get ; }
23-
2423 public AWSStorage ( AWSStorageOptions options , ILogger < AWSStorage > ? logger = null ) : base ( options )
2524 {
2625 _logger = logger ;
2726 StorageClient = new AmazonS3Client ( new BasicAWSCredentials ( options . PublicKey , options . SecretKey ) , options . OriginalOptions ) ;
2827 }
28+
2929
30-
31- protected override async Task < Result > CreateContainerInternalAsync ( CancellationToken cancellationToken = default )
30+ public override async Task < Result > RemoveContainerAsync ( CancellationToken cancellationToken = default )
3231 {
3332 try
3433 {
35- await StorageClient . EnsureBucketExistsAsync ( StorageOptions . Bucket ) ;
34+ await StorageClient . DeleteBucketAsync ( StorageOptions . Bucket , cancellationToken ) ;
3635 return Result . Succeed ( ) ;
3736 }
3837 catch ( Exception ex )
@@ -42,11 +41,59 @@ protected override async Task<Result> CreateContainerInternalAsync(CancellationT
4241 }
4342 }
4443
45- public override async Task < Result > RemoveContainerAsync ( CancellationToken cancellationToken = default )
44+ public override async IAsyncEnumerable < BlobMetadata > GetBlobMetadataListAsync ( string ? directory = null ,
45+ [ EnumeratorCancellation ] CancellationToken cancellationToken = default )
46+ {
47+ var objectsRequest = new ListObjectsRequest
48+ {
49+ BucketName = StorageOptions . Bucket ,
50+ Prefix = directory ,
51+ MaxKeys = 1_000_000
52+ } ;
53+
54+ await EnsureContainerExist ( ) ;
55+
56+ do
57+ {
58+ var objectsResponse = await StorageClient . ListObjectsAsync ( objectsRequest , cancellationToken ) ;
59+
60+ foreach ( var entry in objectsResponse . S3Objects )
61+ {
62+ var objectMetaRequest = new GetObjectMetadataRequest
63+ {
64+ BucketName = StorageOptions . Bucket ,
65+ Key = entry . Key
66+ } ;
67+
68+ var objectMetaResponse = await StorageClient . GetObjectMetadataAsync ( objectMetaRequest , cancellationToken ) ;
69+
70+ yield return new BlobMetadata
71+ {
72+ FullName = entry . Key ,
73+ Name = Path . GetFileName ( entry . Key ) ,
74+ Uri = new Uri ( $ "https://s3.amazonaws.com/{ StorageOptions . Bucket } /{ entry . Key } ") ,
75+ MimeType = objectMetaResponse . Headers . ContentType ,
76+ Length = objectMetaResponse . Headers . ContentLength
77+ } ;
78+ }
79+
80+ // If response is truncated, set the marker to get the next set of keys.
81+ if ( objectsResponse . IsTruncated )
82+ {
83+ objectsRequest . Marker = objectsResponse . NextMarker ;
84+ }
85+ else
86+ {
87+ objectsRequest = null ;
88+ }
89+ } while ( objectsRequest is not null ) ;
90+ }
91+
92+ protected override async Task < Result > CreateContainerInternalAsync ( CancellationToken cancellationToken = default )
4693 {
4794 try
4895 {
49- await StorageClient . DeleteBucketAsync ( StorageOptions . Bucket , cancellationToken ) ;
96+ await StorageClient . EnsureBucketExistsAsync ( StorageOptions . Bucket ) ;
5097 return Result . Succeed ( ) ;
5198 }
5299 catch ( Exception ex )
@@ -64,7 +111,7 @@ protected override async Task<Result> DeleteDirectoryInternalAsync(string direct
64111
65112 await foreach ( var item in items . WithCancellation ( cancellationToken ) )
66113 {
67- await StorageClient . DeleteAsync ( StorageOptions . Bucket , item . FullName , null , cancellationToken : cancellationToken ) ;
114+ await StorageClient . DeleteAsync ( StorageOptions . Bucket , item . FullName , null , cancellationToken ) ;
68115 }
69116
70117 return Result . Succeed ( ) ;
@@ -76,7 +123,8 @@ protected override async Task<Result> DeleteDirectoryInternalAsync(string direct
76123 }
77124 }
78125
79- protected override async Task < Result < BlobMetadata > > UploadInternalAsync ( Stream stream , UploadOptions options ,
126+ protected override async Task < Result < BlobMetadata > > UploadInternalAsync ( Stream stream ,
127+ UploadOptions options ,
80128 CancellationToken cancellationToken = default )
81129 {
82130 var putRequest = new PutObjectRequest
@@ -102,7 +150,8 @@ protected override async Task<Result<BlobMetadata>> UploadInternalAsync(Stream s
102150 }
103151 }
104152
105- protected override async Task < Result < LocalFile > > DownloadInternalAsync ( LocalFile localFile , DownloadOptions options ,
153+ protected override async Task < Result < LocalFile > > DownloadInternalAsync ( LocalFile localFile ,
154+ DownloadOptions options ,
106155 CancellationToken cancellationToken = default )
107156 {
108157 try
@@ -116,7 +165,7 @@ protected override async Task<Result<LocalFile>> DownloadInternalAsync(LocalFile
116165 Uri = new Uri ( $ "https://s3.amazonaws.com/{ StorageOptions . Bucket } /{ options . FullPath } ") ,
117166 MimeType = response . Headers . ContentType ,
118167 Length = response . Headers . ContentLength ,
119- Container = StorageOptions . Bucket ,
168+ Container = StorageOptions . Bucket
120169 } ;
121170
122171 await localFile . CopyFromStreamAsync ( await StorageClient . GetObjectStreamAsync ( StorageOptions . Bucket , options . FullPath , null ,
@@ -131,7 +180,6 @@ await localFile.CopyFromStreamAsync(await StorageClient.GetObjectStreamAsync(Sto
131180 }
132181 }
133182
134-
135183 protected override async Task < Result < bool > > DeleteInternalAsync ( DeleteOptions options , CancellationToken cancellationToken = default )
136184 {
137185 try
@@ -160,7 +208,6 @@ await StorageClient.DeleteObjectAsync(new DeleteObjectRequest
160208 }
161209 }
162210
163-
164211 protected override async Task < Result < bool > > ExistsInternalAsync ( ExistOptions options , CancellationToken cancellationToken = default )
165212 {
166213 try
@@ -171,8 +218,10 @@ protected override async Task<Result<bool>> ExistsInternalAsync(ExistOptions opt
171218 }
172219 catch ( AmazonS3Exception ex )
173220 {
174- if ( ex . StatusCode == System . Net . HttpStatusCode . NotFound )
221+ if ( ex . StatusCode == HttpStatusCode . NotFound )
222+ {
175223 return Result < bool > . Succeed ( false ) ;
224+ }
176225
177226 return Result < bool > . Fail ( ex ) ;
178227 }
@@ -183,7 +232,6 @@ protected override async Task<Result<bool>> ExistsInternalAsync(ExistOptions opt
183232 }
184233 }
185234
186-
187235 protected override async Task < Result < BlobMetadata > > GetBlobMetadataInternalAsync ( MetadataOptions options ,
188236 CancellationToken cancellationToken = default )
189237 {
@@ -215,55 +263,8 @@ protected override async Task<Result<BlobMetadata>> GetBlobMetadataInternalAsync
215263 }
216264 }
217265
218- public override async IAsyncEnumerable < BlobMetadata > GetBlobMetadataListAsync ( string ? directory = null ,
219- [ EnumeratorCancellation ] CancellationToken cancellationToken = default )
220- {
221- var objectsRequest = new ListObjectsRequest
222- {
223- BucketName = StorageOptions . Bucket ,
224- Prefix = directory ,
225- MaxKeys = 1_000_000
226- } ;
227-
228- await EnsureContainerExist ( ) ;
229-
230- do
231- {
232- var objectsResponse = await StorageClient . ListObjectsAsync ( objectsRequest , cancellationToken ) ;
233-
234- foreach ( var entry in objectsResponse . S3Objects )
235- {
236- var objectMetaRequest = new GetObjectMetadataRequest
237- {
238- BucketName = StorageOptions . Bucket ,
239- Key = entry . Key
240- } ;
241-
242- var objectMetaResponse = await StorageClient . GetObjectMetadataAsync ( objectMetaRequest , cancellationToken ) ;
243-
244- yield return new BlobMetadata
245- {
246- FullName = entry . Key ,
247- Name = Path . GetFileName ( entry . Key ) ,
248- Uri = new Uri ( $ "https://s3.amazonaws.com/{ StorageOptions . Bucket } /{ entry . Key } ") ,
249- MimeType = objectMetaResponse . Headers . ContentType ,
250- Length = objectMetaResponse . Headers . ContentLength
251- } ;
252- }
253-
254- // If response is truncated, set the marker to get the next set of keys.
255- if ( objectsResponse . IsTruncated )
256- {
257- objectsRequest . Marker = objectsResponse . NextMarker ;
258- }
259- else
260- {
261- objectsRequest = null ;
262- }
263- } while ( objectsRequest is not null ) ;
264- }
265-
266- protected override async Task < Result > SetLegalHoldInternalAsync ( bool hasLegalHold , LegalHoldOptions options ,
266+ protected override async Task < Result > SetLegalHoldInternalAsync ( bool hasLegalHold ,
267+ LegalHoldOptions options ,
267268 CancellationToken cancellationToken = default )
268269 {
269270 try
@@ -280,8 +281,8 @@ protected override async Task<Result> SetLegalHoldInternalAsync(bool hasLegalHol
280281 Key = options . FullPath ,
281282 LegalHold = new ObjectLockLegalHold
282283 {
283- Status = status ,
284- } ,
284+ Status = status
285+ }
285286 } ;
286287
287288 await StorageClient . PutObjectLegalHoldAsync ( request , cancellationToken ) ;
@@ -294,7 +295,6 @@ protected override async Task<Result> SetLegalHoldInternalAsync(bool hasLegalHol
294295 }
295296 }
296297
297-
298298 protected override async Task < Result < bool > > HasLegalHoldInternalAsync ( LegalHoldOptions options , CancellationToken cancellationToken = default )
299299 {
300300 try
0 commit comments