Skip to content

Commit 5b7b82e

Browse files
authored
feat(storage): add multi-bucket feature support (#5681)
1 parent 7bdb860 commit 5b7b82e

File tree

53 files changed

+1826
-153
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1826
-153
lines changed

infra-gen2/backends/storage/main/amplify/backend.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,52 @@
11
import { defineBackend } from "@aws-amplify/backend";
22
import * as s3 from "aws-cdk-lib/aws-s3";
33
import { auth } from "./auth/resource";
4-
import { storage } from "./storage/resource";
4+
import { firstBucket, secondBucket } from "./storage/resource";
55

66
/**
77
* @see https://docs.amplify.aws/react/build-a-backend/ to add storage, functions, and more
88
*/
99
const backend = defineBackend({
1010
auth,
11-
storage,
11+
firstBucket,
12+
secondBucket,
1213
});
1314

1415
// custom storage configurations
15-
const s3Bucket = backend.storage.resources.bucket;
16+
const s3Bucket = backend.firstBucket.resources.bucket;
1617
const cfnBucket = s3Bucket.node.defaultChild as s3.CfnBucket;
18+
const s3SecondaryBucket = backend.secondBucket.resources.bucket;
19+
const cfnSecondaryBucket = s3SecondaryBucket.node.defaultChild as s3.CfnBucket;
1720

1821
cfnBucket.accelerateConfiguration = {
1922
accelerationStatus: "Enabled",
2023
};
2124

25+
cfnSecondaryBucket.accelerateConfiguration = {
26+
accelerationStatus: "Enabled",
27+
};
28+
29+
// required to add the metadata header, which amplify-backend does not support
30+
backend.firstBucket.resources.cfnResources.cfnBucket.corsConfiguration = {
31+
corsRules: [
32+
{
33+
allowedHeaders: ["*"],
34+
allowedMethods: ["GET", "HEAD", "PUT", "POST", "DELETE"],
35+
allowedOrigins: ["*"],
36+
exposedHeaders: [
37+
"x-amz-server-side-encryption",
38+
"x-amz-request-id",
39+
"x-amz-id-2",
40+
"ETag",
41+
"x-amz-meta-description",
42+
],
43+
maxAge: 3000,
44+
},
45+
],
46+
};
47+
2248
// required to add the metadata header, which amplify-backend does not support
23-
backend.storage.resources.cfnResources.cfnBucket.corsConfiguration = {
49+
backend.secondBucket.resources.cfnResources.cfnBucket.corsConfiguration = {
2450
corsRules: [
2551
{
2652
allowedHeaders: ["*"],

infra-gen2/backends/storage/main/amplify/storage/resource.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
11
import { defineStorage } from "@aws-amplify/backend";
22

3-
export const storage = defineStorage({
4-
name: "Storage Integ Test main",
3+
export const firstBucket = defineStorage({
4+
name: "Storage Integ Test main bucket",
5+
isDefault: true,
6+
access: (allow) => ({
7+
"public/*": [
8+
allow.guest.to(["read", "write", "delete"]),
9+
allow.authenticated.to(["read", "delete", "write"]),
10+
],
11+
"protected/{entity_id}/*": [
12+
allow.authenticated.to(["read"]),
13+
allow.entity("identity").to(["read", "write", "delete"]),
14+
],
15+
"private/{entity_id}/*": [
16+
allow.entity("identity").to(["read", "write", "delete"]),
17+
],
18+
}),
19+
});
20+
21+
export const secondBucket = defineStorage({
22+
name: "Storage Integ Test secondary bucket",
523
access: (allow) => ({
624
"public/*": [
725
allow.guest.to(["read", "write", "delete"]),
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import 'package:amplify_core/amplify_core.dart';
5+
6+
part 'bucket_outputs.g.dart';
7+
8+
/// {@template amplify_core.amplify_outputs.bucket_outputs}
9+
/// The Amplify Gen 2 outputs for Buckets in the Storage category.
10+
/// {@endtemplate}
11+
@zAmplifyOutputsSerializable
12+
class BucketOutputs
13+
with AWSEquatable<BucketOutputs>, AWSSerializable, AWSDebuggable {
14+
/// {@macro amplify_core.amplify_outputs.bucket_outputs}
15+
const BucketOutputs({
16+
required this.name,
17+
required this.bucketName,
18+
required this.awsRegion,
19+
});
20+
21+
factory BucketOutputs.fromJson(Map<String, Object?> json) =>
22+
_$BucketOutputsFromJson(json);
23+
24+
/// The user friendly name of the bucket
25+
final String name;
26+
27+
/// The Amazon S3 bucket name.
28+
final String bucketName;
29+
30+
/// The AWS region of Amazon S3 resources.
31+
final String awsRegion;
32+
33+
@override
34+
List<Object?> get props => [
35+
name,
36+
bucketName,
37+
awsRegion,
38+
];
39+
40+
@override
41+
String get runtimeTypeName => 'BucketOutputs';
42+
43+
@override
44+
Object? toJson() {
45+
return _$BucketOutputsToJson(this);
46+
}
47+
}

packages/amplify_core/lib/src/config/amplify_outputs/storage/bucket_outputs.g.dart

Lines changed: 34 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/amplify_core/lib/src/config/amplify_outputs/storage/storage_outputs.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
import 'package:amplify_core/amplify_core.dart';
5+
import 'package:amplify_core/src/config/amplify_outputs/storage/bucket_outputs.dart';
56

67
part 'storage_outputs.g.dart';
78

@@ -12,7 +13,11 @@ part 'storage_outputs.g.dart';
1213
class StorageOutputs
1314
with AWSEquatable<StorageOutputs>, AWSSerializable, AWSDebuggable {
1415
/// {@macro amplify_core.amplify_outputs.storage_outputs}
15-
const StorageOutputs({required this.awsRegion, required this.bucketName});
16+
const StorageOutputs({
17+
required this.awsRegion,
18+
required this.bucketName,
19+
this.buckets,
20+
});
1621

1722
factory StorageOutputs.fromJson(Map<String, Object?> json) =>
1823
_$StorageOutputsFromJson(json);
@@ -23,8 +28,11 @@ class StorageOutputs
2328
/// The Amazon S3 bucket name.
2429
final String bucketName;
2530

31+
/// The list of buckets if there are multiple buckets for the project
32+
final List<BucketOutputs>? buckets;
33+
2634
@override
27-
List<Object?> get props => [awsRegion, bucketName];
35+
List<Object?> get props => [awsRegion, bucketName, buckets];
2836

2937
@override
3038
String get runtimeTypeName => 'StorageOutputs';

packages/amplify_core/lib/src/config/amplify_outputs/storage/storage_outputs.g.dart

Lines changed: 21 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/amplify_core/lib/src/types/exception/amplify_exception.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ part 'network_exception.dart';
2121
part 'push/push_notification_exception.dart';
2222
part 'storage/access_denied_exception.dart';
2323
part 'storage/http_status_exception.dart';
24+
part 'storage/invalid_storage_bucket_exception.dart';
2425
part 'storage/local_file_not_found_exception.dart';
2526
part 'storage/not_found_exception.dart';
2627
part 'storage/operation_canceled_exception.dart';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
part of '../amplify_exception.dart';
2+
3+
/// {@template amplify_core.storage.invalid_storage_bucket_exception}
4+
/// Exception thrown when the [StorageBucket] is invalid.
5+
/// {@endtemplate}
6+
class InvalidStorageBucketException extends StorageException {
7+
const InvalidStorageBucketException(
8+
super.message, {
9+
super.recoverySuggestion,
10+
super.underlyingException,
11+
});
12+
13+
@override
14+
String get runtimeTypeName => 'InvalidStorageBucketException';
15+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import 'package:amplify_core/amplify_core.dart';
2+
3+
/// {@template amplify_core.storage.bucket_info}
4+
/// Presents a storage bucket information.
5+
/// {@endtemplate}
6+
class BucketInfo
7+
with AWSEquatable<BucketInfo>, AWSSerializable<Map<String, Object?>> {
8+
/// {@macro amplify_core.storage.bucket_info}
9+
const BucketInfo({required this.bucketName, required this.region});
10+
final String bucketName;
11+
final String region;
12+
13+
@override
14+
List<Object?> get props => [
15+
bucketName,
16+
region,
17+
];
18+
19+
@override
20+
Map<String, Object?> toJson() => {
21+
'bucketName': bucketName,
22+
'region': region,
23+
};
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import 'package:amplify_core/amplify_core.dart';
2+
3+
/// Presents storage buckets for a copy operation.
4+
class CopyBuckets with AWSSerializable<Map<String, Object?>> {
5+
/// Creates a [CopyBuckets] with [source] and [destination] buckets.
6+
const CopyBuckets({
7+
required this.source,
8+
required this.destination,
9+
});
10+
11+
/// Creates a [CopyBuckets] with the same [bucket] for the [source] and [destination].
12+
CopyBuckets.sameBucket(StorageBucket bucket)
13+
: source = bucket,
14+
destination = bucket;
15+
16+
final StorageBucket source;
17+
final StorageBucket destination;
18+
19+
@override
20+
Map<String, Object?> toJson() => {
21+
'source': source.toJson(),
22+
'destination': destination.toJson(),
23+
};
24+
}

packages/amplify_core/lib/src/types/storage/copy_options.dart

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
import 'package:aws_common/aws_common.dart';
4+
import 'package:amplify_core/amplify_core.dart';
55

66
/// {@template amplify_core.storage.copy_options}
77
/// Configurable options for `Amplify.Storage.copy`.
@@ -12,20 +12,27 @@ class StorageCopyOptions
1212
AWSSerializable<Map<String, Object?>>,
1313
AWSDebuggable {
1414
/// {@macro amplify_core.storage.copy_options}
15-
const StorageCopyOptions({this.pluginOptions});
15+
const StorageCopyOptions({
16+
this.pluginOptions,
17+
this.buckets,
18+
});
1619

1720
/// plugin specific options for `Amplify.Storage.copy`.
1821
final StorageCopyPluginOptions? pluginOptions;
1922

23+
/// Optionally specify which buckets to target
24+
final CopyBuckets? buckets;
25+
2026
@override
21-
List<Object?> get props => [pluginOptions];
27+
List<Object?> get props => [pluginOptions, buckets];
2228

2329
@override
2430
String get runtimeTypeName => 'StorageCopyOptions';
2531

2632
@override
2733
Map<String, Object?> toJson() => {
2834
'pluginOptions': pluginOptions?.toJson(),
35+
'buckets': buckets?.toJson(),
2936
};
3037
}
3138

packages/amplify_core/lib/src/types/storage/download_data_options.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
import 'package:aws_common/aws_common.dart';
4+
import 'package:amplify_core/amplify_core.dart';
55

66
/// {@template amplify_core.storage.download_data_options}
77
/// Configurable options for `Amplify.Storage.downloadData`.
@@ -14,20 +14,25 @@ class StorageDownloadDataOptions
1414
/// {@macro amplify_core.storage.download_data_options}
1515
const StorageDownloadDataOptions({
1616
this.pluginOptions,
17+
this.bucket,
1718
});
1819

1920
/// {@macro amplify_core.storage.download_data_plugin_options}
2021
final StorageDownloadDataPluginOptions? pluginOptions;
2122

23+
/// Optionally specify which bucket to target
24+
final StorageBucket? bucket;
25+
2226
@override
23-
List<Object?> get props => [pluginOptions];
27+
List<Object?> get props => [pluginOptions, bucket];
2428

2529
@override
2630
String get runtimeTypeName => 'StorageDownloadDataOptions';
2731

2832
@override
2933
Map<String, Object?> toJson() => {
3034
'pluginOptions': pluginOptions?.toJson(),
35+
'bucket': bucket?.toJson(),
3136
};
3237
}
3338

0 commit comments

Comments
 (0)