Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(storage): multi bucket list api #5576

Merged
merged 48 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
13d6723
updating storage_outputs class for multi-bucket support
Sep 17, 2024
c5c0438
seperated bucket out into its own class instead of using a map
Sep 17, 2024
f22dd48
made bucket_output class a proper output class like the others in amp…
Sep 18, 2024
cc6c55b
Update auth.dart
ekjotmultani Sep 18, 2024
b6f8719
added doc comments and changed name of bucket class
Sep 18, 2024
66ad860
Merge branch 'storagewereoutput-update' of https://github.com/aws-amp…
Sep 18, 2024
3fc0ce9
Delete devtools_options.yaml
ekjotmultani Sep 18, 2024
9114206
added trailing commas to pass ci test
Sep 18, 2024
a17b602
Merge branch 'storage-output-update' of https://github.com/aws-amplif…
Sep 18, 2024
e7906c7
ran dart format on two failing files
Sep 18, 2024
6055a80
feat(core): add storage bucket type (#5478)
NikaHsn Sep 20, 2024
24089ae
Merge pull request #5476 from aws-amplify/storage-output-update
ekjotmultani Sep 23, 2024
d01d0df
updated resource.ts and backend.ts for multiple buckets in our infra-…
Sep 24, 2024
47c1371
updated resource.ts and backend.ts for multiple buckets in our infra-…
Sep 24, 2024
0d4e492
Merge pull request #5492 from aws-amplify/multi-bucket-infra-update
ekjotmultani Sep 24, 2024
d68bb03
feat(storage): update s3 storage service to support multiple s3 clien…
NikaHsn Sep 25, 2024
3eafd51
feat(storage): update uploadData API to accept optional storage bucke…
NikaHsn Oct 14, 2024
077d879
Merge remote-tracking branch 'origin/main' into multi-bucket
Oct 18, 2024
8c45501
allow the s3 list api to accept an optional bucket
Oct 16, 2024
e734d8e
formatting
Oct 16, 2024
119b843
trailing commas
Oct 16, 2024
f3956cf
formatting
Oct 16, 2024
b14468c
format
Oct 16, 2024
ad837d7
fixed formatting and annotated internal member use
Oct 16, 2024
05bc0a8
format
Oct 17, 2024
0c023fd
format
Oct 17, 2024
48940f9
refactored how the default bucket is passed along through the list api
Oct 18, 2024
1ed7691
updated tests to test default bucket functionality
ekjotmultani Oct 21, 2024
980c0d6
cleaning up commits
ekjotmultani Oct 18, 2024
8f2e9a1
allow the s3 list api to accept an optional bucket
Oct 16, 2024
976c6ea
format
Oct 16, 2024
81972ab
fixed formatting and annotated internal member use
Oct 16, 2024
9f4f91a
chore(dep): update mime version to ^2.0.0 (#5568)
NikaHsn Oct 18, 2024
15b62e4
fix(api): Reconnect WebSocket when resuming app from a paused state (…
tyllark Oct 18, 2024
1ee2ff6
chore: Cherry Pick Bump version (#5593)
Equartey Oct 23, 2024
3551eb3
seperated bucket out into its own class instead of using a map
Sep 17, 2024
08d3ed0
made bucket_output class a proper output class like the others in amp…
Sep 18, 2024
56b64ee
added doc comments and changed name of bucket class
Sep 18, 2024
ec7a7a6
Update auth.dart
ekjotmultani Sep 18, 2024
f625f3b
Delete devtools_options.yaml
ekjotmultani Sep 18, 2024
54c5f62
updated doc message to be consistent with other apis, used proper var…
ekjotmultani Oct 23, 2024
132e22c
feat(storage): multi bucket get properties api (#5577)
ekjotmultani Oct 24, 2024
b2783fb
feat(storage): multi bucket remove (#5598)
Equartey Oct 28, 2024
a4d65af
feat(storage): multi bucket download data (#5599)
Equartey Oct 28, 2024
3999314
feat(storage): multi bucket upload file (#5600)
Equartey Oct 29, 2024
e4b9d7f
chore(storage): add e2e tests for upload data api (#5622)
NikaHsn Nov 1, 2024
309fca4
updated tests to account for changes to uploadData api
ekjotmultani Nov 4, 2024
fe69e0e
Merge branch 'multi-bucket' into feat/multi-bucket-list-api
ekjotmultani Nov 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import 'package:aws_common/aws_common.dart';
import 'package:amplify_core/amplify_core.dart';

/// {@template amplify_core.storage.list_options}
/// Configurable options for `Amplify.Storage.list`.
Expand All @@ -15,6 +15,7 @@ class StorageListOptions
const StorageListOptions({
this.pageSize = 1000,
this.nextToken,
this.bucket,
this.pluginOptions,
});

Expand All @@ -27,8 +28,11 @@ class StorageListOptions
/// {@macro amplify_core.storage.list_plugin_options}
final StorageListPluginOptions? pluginOptions;

/// Optionally specify which bucket to retrieve
final StorageBucket? bucket;

@override
List<Object?> get props => [pageSize, nextToken, pluginOptions];
List<Object?> get props => [pageSize, nextToken, pluginOptions, bucket];

@override
String get runtimeTypeName => 'StorageListOptions';
Expand All @@ -37,6 +41,7 @@ class StorageListOptions
Map<String, Object?> toJson() => {
'pageSize': pageSize,
'nextToken': nextToken,
'bucket': bucket,
'pluginOptions': pluginOptions?.toJson(),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,73 @@ void main() {
'$uniquePrefix/file2.txt',
'$uniquePrefix/subdir/file3.txt',
'$uniquePrefix/subdir2#file4.txt',
'$uniquePrefix/file5.txt',
'$uniquePrefix/file6.txt',
'$uniquePrefix/subdir3/file7.txt',
'$uniquePrefix/subdir4#file8.txt',
];
group('standard config', () {
final mainBucket =
StorageBucket.fromOutputs('Storage Integ Test main bucket');
final secondaryBucket = StorageBucket.fromOutputs(
'Storage Integ Test secondary bucket',
);
setUpAll(() async {
await configure(amplifyEnvironments['main']!);

for (final path in uploadedPaths) {
for (var pathIndex = 0;
pathIndex < uploadedPaths.length ~/ 2;
pathIndex++) {
await Amplify.Storage.uploadData(
path: StoragePath.fromString(path),
path: StoragePath.fromString(uploadedPaths[pathIndex]),
data: StorageDataPayload.bytes('test content'.codeUnits),
options: StorageUploadDataOptions(
bucket: mainBucket,
),
).result;
}
for (var pathIndex = uploadedPaths.length ~/ 2;
pathIndex < uploadedPaths.length;
pathIndex++) {
await Amplify.Storage.uploadData(
path: StoragePath.fromString(uploadedPaths[pathIndex]),
data: StorageDataPayload.bytes('test content'.codeUnits),
options: StorageUploadDataOptions(
bucket: secondaryBucket,
),
).result;
}

for (final path in uploadedPaths) {
addTearDownPath(StoragePath.fromString(path));
}
});

group('list() without options', () {
testWidgets('should list all files with unique prefix', (_) async {
final listResult = await Amplify.Storage.list(
// this will use the main bucket by default when no optional bucket is specified
final listResultMainBucket = await Amplify.Storage.list(
path: StoragePath.fromString(uniquePrefix),
).result;

for (final uploadedPath in uploadedPaths) {
final listResultSecondaryBucket = await Amplify.Storage.list(
path: StoragePath.fromString(uniquePrefix),
options: StorageListOptions(
bucket: secondaryBucket,
),
).result;
for (var pathIndex = 0;
pathIndex < uploadedPaths.length ~/ 2;
pathIndex++) {
expect(
listResultMainBucket.items
.any((item) => item.path == uploadedPaths[pathIndex]),
isTrue,
);
}
for (var pathIndex = uploadedPaths.length ~/ 2;
pathIndex < uploadedPaths.length;
pathIndex++) {
expect(
listResult.items.any((item) => item.path == uploadedPath),
listResultSecondaryBucket.items
.any((item) => item.path == uploadedPaths[pathIndex]),
isTrue,
);
}
Expand Down Expand Up @@ -101,6 +142,17 @@ void main() {
),
).result as S3ListResult;

final listResultSecondaryBucket = await Amplify.Storage.list(
path: StoragePath.fromString('$uniquePrefix/'),
options: StorageListOptions(
pluginOptions: const S3ListPluginOptions(
excludeSubPaths: true,
delimiter: '#',
),
bucket: secondaryBucket,
),
).result as S3ListResult;

expect(listResult.items.length, 3);
expect(listResult.items.first.path, contains('file1.txt'));

Expand All @@ -110,6 +162,19 @@ void main() {
'$uniquePrefix/subdir2#',
);
expect(listResult.metadata.delimiter, '#');

expect(listResultSecondaryBucket.items.length, 3);
expect(
listResultSecondaryBucket.items.first.path,
contains('file5.txt'),
);

expect(listResultSecondaryBucket.metadata.subPaths.length, 1);
expect(
listResultSecondaryBucket.metadata.subPaths.first,
'$uniquePrefix/subdir4#',
);
expect(listResultSecondaryBucket.metadata.delimiter, '#');
});
});

Expand All @@ -123,6 +188,20 @@ void main() {

expect(listResult.items.length, 2);
expect(listResult.items.first.path, contains('file1.txt'));

final listResultSecondaryBucket = await Amplify.Storage.list(
path: StoragePath.fromString(uniquePrefix),
options: StorageListOptions(
pageSize: 2,
bucket: secondaryBucket,
),
).result;

expect(listResultSecondaryBucket.items.length, 2);
expect(
listResultSecondaryBucket.items.first.path,
contains('file5.txt'),
);
});

testWidgets('should list files with pagination', (_) async {
Expand Down Expand Up @@ -157,8 +236,22 @@ void main() {
),
).result;

expect(listResult.items.length, uploadedPaths.length);
expect(listResult.items.length, uploadedPaths.length ~/ 2);
expect(listResult.nextToken, isNull);

final listResultSecondaryBucket = await Amplify.Storage.list(
path: StoragePath.fromString(uniquePrefix),
options: StorageListOptions(
pluginOptions: const S3ListPluginOptions.listAll(),
bucket: secondaryBucket,
),
).result;

expect(
listResultSecondaryBucket.items.length,
uploadedPaths.length ~/ 2,
);
expect(listResultSecondaryBucket.nextToken, isNull);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class AmplifyStorageS3Dart extends StoragePluginInterface
final s3Options = StorageListOptions(
pluginOptions: s3PluginOptions,
nextToken: options?.nextToken,
bucket: options?.bucket,
pageSize: options?.pageSize ?? 1000,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,12 @@ class StorageS3Service {
const S3ListPluginOptions();

final resolvedPath = await _pathResolver.resolvePath(path: path);
final s3ClientInfo = getS3ClientInfo(storageBucket: options.bucket);

if (!s3PluginOptions.listAll) {
final request = s3.ListObjectsV2Request.build((builder) {
builder
..bucket = _storageOutputs.bucketName
..bucket = s3ClientInfo.bucketName
..prefix = resolvedPath
..maxKeys = options.pageSize
..continuationToken = options.nextToken
Expand All @@ -140,7 +141,7 @@ class StorageS3Service {

try {
return S3ListResult.fromPaginatedResult(
await _defaultS3Client.listObjectsV2(request).result,
await s3ClientInfo.client.listObjectsV2(request).result,
);
} on smithy.UnknownSmithyHttpException catch (error) {
// S3Client.headObject may return 403 error
Expand All @@ -156,14 +157,14 @@ class StorageS3Service {
try {
final request = s3.ListObjectsV2Request.build((builder) {
builder
..bucket = _storageOutputs.bucketName
..bucket = s3ClientInfo.bucketName
..prefix = resolvedPath
..delimiter = s3PluginOptions.excludeSubPaths
? s3PluginOptions.delimiter
: null;
});

listResult = await _defaultS3Client.listObjectsV2(request).result;
listResult = await s3ClientInfo.client.listObjectsV2(request).result;
recursiveResult = S3ListResult.fromPaginatedResult(
listResult,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ void main() {
const testOptions = StorageListOptions(
pluginOptions: S3ListPluginOptions(excludeSubPaths: true),
nextToken: 'next-token-123',
bucket: StorageBucket.fromBucketInfo(
BucketInfo(bucketName: 'unit-test-bucket', region: 'us-east-2'),
),
pageSize: 2,
);

Expand Down
Loading