Skip to content

Commit 358d14e

Browse files
authored
Merge pull request #18 from SharpGrip/9-research-improve-amazon-s3-adapter
add support for pagination in list objects calls
2 parents 7a4f614 + f2b5c12 commit 358d14e

1 file changed

Lines changed: 70 additions & 25 deletions

File tree

FileSystem.Adapters.AmazonS3/src/AmazonS3Adapter.cs

Lines changed: 70 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,27 @@ public override async Task<IDirectory> GetDirectoryAsync(string virtualPath, Can
7676
}
7777

7878
var request = new ListObjectsV2Request {BucketName = bucketName, Prefix = path};
79-
var response = await client.ListObjectsV2Async(request, cancellationToken);
79+
ListObjectsV2Response response;
8080

81-
if (response.KeyCount == 0)
81+
do
8282
{
83-
throw new DirectoryNotFoundException(path, Prefix);
84-
}
83+
response = await client.ListObjectsV2Async(request, cancellationToken);
8584

86-
foreach (var item in response.S3Objects)
87-
{
88-
if (item.Key == path)
85+
if (response.KeyCount == 0)
8986
{
90-
return ModelFactory.CreateDirectory(item, virtualPath);
87+
throw new DirectoryNotFoundException(path, Prefix);
88+
}
89+
90+
foreach (var item in response.S3Objects)
91+
{
92+
if (item.Key == path)
93+
{
94+
return ModelFactory.CreateDirectory(item, virtualPath);
95+
}
9196
}
92-
}
97+
98+
request.ContinuationToken = response.NextContinuationToken;
99+
} while (response.IsTruncated);
93100

94101
throw new DirectoryNotFoundException(path, Prefix);
95102
}
@@ -109,22 +116,35 @@ public override async Task<IEnumerable<IFile>> GetFilesAsync(string virtualPath
109116
path += "/";
110117
}
111118

119+
if (path == "/")
120+
{
121+
path = "";
122+
}
123+
112124
try
113125
{
114126
var request = new ListObjectsV2Request {BucketName = bucketName, Prefix = path};
115-
var response = await client.ListObjectsV2Async(request, cancellationToken);
127+
ListObjectsV2Response response;
116128

117129
var files = new List<IFile>();
118130

119-
foreach (var item in response.S3Objects)
131+
do
120132
{
121-
var itemName = item.Key.Substring(0, item.Key.Length - path.Length);
133+
response = await client.ListObjectsV2Async(request, cancellationToken);
122134

123-
if (!item.Key.EndsWith("/") && !itemName.Contains('/'))
135+
foreach (var item in response.S3Objects)
124136
{
125-
files.Add(ModelFactory.CreateFile(item, GetVirtualPath(item.Key)));
137+
// var itemName = item.Key.Substring(0, item.Key.Length - path.Length);
138+
var itemName = item.Key.Substring(path.Length).RemoveLeadingForwardSlash();
139+
140+
if (!item.Key.EndsWith("/") && !itemName.Contains('/'))
141+
{
142+
files.Add(ModelFactory.CreateFile(item, GetVirtualPath(item.Key)));
143+
}
126144
}
127-
}
145+
146+
request.ContinuationToken = response.NextContinuationToken;
147+
} while (response.IsTruncated);
128148

129149
return files;
130150
}
@@ -139,22 +159,39 @@ public override async Task<IEnumerable<IDirectory>> GetDirectoriesAsync(string v
139159
await GetDirectoryAsync(virtualPath, cancellationToken);
140160
var path = GetPath(virtualPath);
141161

162+
if (!path.EndsWith("/"))
163+
{
164+
path += "/";
165+
}
166+
167+
if (path == "/")
168+
{
169+
path = "";
170+
}
171+
142172
try
143173
{
144174
var request = new ListObjectsV2Request {BucketName = bucketName, Prefix = path};
145-
var response = await client.ListObjectsV2Async(request, cancellationToken);
175+
ListObjectsV2Response response;
146176

147177
var directories = new List<IDirectory>();
148178

149-
foreach (var item in response.S3Objects)
179+
do
150180
{
151-
var itemName = item.Key.Substring(path.Length).RemoveLeadingForwardSlash();
181+
response = await client.ListObjectsV2Async(request, cancellationToken);
152182

153-
if (item.Key.EndsWith("/") && itemName.Count(c => c.Equals('/')) == 1)
183+
foreach (var item in response.S3Objects)
154184
{
155-
directories.Add(ModelFactory.CreateDirectory(item, GetVirtualPath(item.Key)));
185+
var itemName = item.Key.Substring(path.Length).RemoveLeadingForwardSlash();
186+
187+
if (item.Key.EndsWith("/") && itemName.Count(c => c.Equals('/')) == 1)
188+
{
189+
directories.Add(ModelFactory.CreateDirectory(item, GetVirtualPath(item.Key)));
190+
}
156191
}
157-
}
192+
193+
request.ContinuationToken = response.NextContinuationToken;
194+
} while (response.IsTruncated);
158195

159196
return directories;
160197
}
@@ -197,12 +234,20 @@ public override async Task DeleteDirectoryAsync(string virtualPath, Cancellation
197234
var deleteObjectsRequest = new DeleteObjectsRequest {BucketName = bucketName};
198235
var listObjectsRequest = new ListObjectsV2Request {BucketName = bucketName, Prefix = path};
199236

200-
var response = await client.ListObjectsV2Async(listObjectsRequest, cancellationToken);
237+
ListObjectsV2Response response;
201238

202-
foreach (S3Object entry in response.S3Objects)
239+
do
203240
{
204-
deleteObjectsRequest.AddKey(entry.Key);
205-
}
241+
response = await client.ListObjectsV2Async(listObjectsRequest, cancellationToken);
242+
243+
foreach (S3Object entry in response.S3Objects)
244+
{
245+
deleteObjectsRequest.AddKey(entry.Key);
246+
}
247+
248+
listObjectsRequest.ContinuationToken = response.NextContinuationToken;
249+
} while (response.IsTruncated);
250+
206251

207252
await client.DeleteObjectsAsync(deleteObjectsRequest, cancellationToken);
208253
}

0 commit comments

Comments
 (0)