Skip to content

Commit 035a42c

Browse files
committed
Migrate Go v2 S3 examples from deprecated feature/s3/manager to feature/s3/transfermanager
Replace the deprecated feature/s3/manager package with the new feature/s3/transfermanager package across Go v2 S3 examples: - gov2/s3: Migrate UploadLargeObject and DownloadLargeObject to use transfermanager.New(), UploadObject(), and DownloadObject() APIs - gov2/workflows/s3_object_lock: Migrate S3Actions.S3Manager from *manager.Uploader to *transfermanager.Client, update UploadObject() - Update go.mod dependencies in both modules - Update comments and documentation references The feature/s3/manager package was deprecated in February 2026 in favor of feature/s3/transfermanager, which provides a unified Client for both uploads and downloads with improved performance.
1 parent 5aaca39 commit 035a42c

9 files changed

Lines changed: 64 additions & 30 deletions

File tree

gov2/s3/actions/bucket_basics.go

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ import (
1414
"io"
1515
"log"
1616
"os"
17+
"sync"
1718
"time"
1819

1920
"github.com/aws/aws-sdk-go-v2/aws"
20-
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
21+
"github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager"
2122
"github.com/aws/aws-sdk-go-v2/service/s3"
2223
"github.com/aws/aws-sdk-go-v2/service/s3/types"
2324
"github.com/aws/smithy-go"
@@ -162,15 +163,15 @@ func (basics BucketBasics) UploadFile(ctx context.Context, bucketName string, ob
162163

163164
// snippet-start:[gov2.s3.Upload]
164165

165-
// UploadLargeObject uses an upload manager to upload data to an object in a bucket.
166-
// The upload manager breaks large data into parts and uploads the parts concurrently.
166+
// UploadLargeObject uses the S3 transfer manager to upload data to an object in a bucket.
167+
// The transfer manager breaks large data into parts and uploads the parts concurrently.
167168
func (basics BucketBasics) UploadLargeObject(ctx context.Context, bucketName string, objectKey string, largeObject []byte) error {
168169
largeBuffer := bytes.NewReader(largeObject)
169170
var partMiBs int64 = 10
170-
uploader := manager.NewUploader(basics.S3Client, func(u *manager.Uploader) {
171-
u.PartSize = partMiBs * 1024 * 1024
171+
tm := transfermanager.New(basics.S3Client, func(o *transfermanager.Options) {
172+
o.PartSizeBytes = partMiBs * 1024 * 1024
172173
})
173-
_, err := uploader.Upload(ctx, &s3.PutObjectInput{
174+
_, err := tm.UploadObject(ctx, &transfermanager.UploadObjectInput{
174175
Bucket: aws.String(bucketName),
175176
Key: aws.String(objectKey),
176177
Body: largeBuffer,
@@ -234,18 +235,19 @@ func (basics BucketBasics) DownloadFile(ctx context.Context, bucketName string,
234235

235236
// snippet-start:[gov2.s3.Download]
236237

237-
// DownloadLargeObject uses a download manager to download an object from a bucket.
238-
// The download manager gets the data in parts and writes them to a buffer until all of
238+
// DownloadLargeObject uses the S3 transfer manager to download an object from a bucket.
239+
// The transfer manager gets the data in parts and writes them to a buffer until all of
239240
// the data has been downloaded.
240241
func (basics BucketBasics) DownloadLargeObject(ctx context.Context, bucketName string, objectKey string) ([]byte, error) {
241242
var partMiBs int64 = 10
242-
downloader := manager.NewDownloader(basics.S3Client, func(d *manager.Downloader) {
243-
d.PartSize = partMiBs * 1024 * 1024
243+
tm := transfermanager.New(basics.S3Client, func(o *transfermanager.Options) {
244+
o.PartSizeBytes = partMiBs * 1024 * 1024
244245
})
245-
buffer := manager.NewWriteAtBuffer([]byte{})
246-
_, err := downloader.Download(ctx, buffer, &s3.GetObjectInput{
247-
Bucket: aws.String(bucketName),
248-
Key: aws.String(objectKey),
246+
buffer := NewWriteAtBuffer([]byte{})
247+
_, err := tm.DownloadObject(ctx, &transfermanager.DownloadObjectInput{
248+
Bucket: aws.String(bucketName),
249+
Key: aws.String(objectKey),
250+
WriterAt: buffer,
249251
})
250252
if err != nil {
251253
log.Printf("Couldn't download large object from %v:%v. Here's why: %v\n",
@@ -254,6 +256,38 @@ func (basics BucketBasics) DownloadLargeObject(ctx context.Context, bucketName s
254256
return buffer.Bytes(), err
255257
}
256258

259+
// WriteAtBuffer is a thread-safe in-memory io.WriterAt implementation.
260+
type WriteAtBuffer struct {
261+
buf []byte
262+
m sync.Mutex
263+
}
264+
265+
// NewWriteAtBuffer creates a new WriteAtBuffer with an initial byte slice.
266+
func NewWriteAtBuffer(buf []byte) *WriteAtBuffer {
267+
return &WriteAtBuffer{buf: buf}
268+
}
269+
270+
// WriteAt writes len(p) bytes to the buffer starting at byte offset off.
271+
func (b *WriteAtBuffer) WriteAt(p []byte, off int64) (int, error) {
272+
b.m.Lock()
273+
defer b.m.Unlock()
274+
end := int(off) + len(p)
275+
if end > len(b.buf) {
276+
newBuf := make([]byte, end)
277+
copy(newBuf, b.buf)
278+
b.buf = newBuf
279+
}
280+
copy(b.buf[off:], p)
281+
return len(p), nil
282+
}
283+
284+
// Bytes returns the contents of the buffer.
285+
func (b *WriteAtBuffer) Bytes() []byte {
286+
b.m.Lock()
287+
defer b.m.Unlock()
288+
return b.buf
289+
}
290+
257291
// snippet-end:[gov2.s3.Download]
258292

259293
// snippet-start:[gov2.s3.CopyObject]

gov2/s3/cmd/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
// Amazon Simple Storage Service (Amazon S3) actions to work with
2525
// S3 buckets and objects.
2626
// - `largeobjects` - Runs the interactive large objects scenario that shows you how to upload
27-
// and download large objects by using a transfer manager.
27+
// and download large objects by using the S3 transfer manager.
2828
// - `presigning` - Runs the interactive presigning scenario that shows you how to
2929
// get presigned requests that contain temporary credentials
3030
// and can be used to make requests from any HTTP client.

gov2/s3/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.24
55
require (
66
github.com/aws/aws-sdk-go-v2 v1.41.5
77
github.com/aws/aws-sdk-go-v2/config v1.27.33
8-
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.18
8+
github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.1.18
99
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3
1010
github.com/aws/smithy-go v1.24.2
1111
github.com/awsdocs/aws-doc-sdk-examples/gov2/demotools v0.0.0-20240907001412-a9375541143b

gov2/s3/scenarios/scenario_large_objects.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import (
2121
// Simple Storage Service (Amazon S3) to upload and download large objects.
2222
//
2323
// 1. Create a bucket.
24-
// 3. Upload a large object to the bucket by using an upload manager.
25-
// 5. Download a large object by using a download manager.
24+
// 3. Upload a large object to the bucket by using the S3 transfer manager.
25+
// 5. Download a large object by using the S3 transfer manager.
2626
// 8. Delete all objects in the bucket.
2727
// 9. Delete the bucket.
2828
//

gov2/s3/scenarios/scenario_large_objects_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestRunLargeObjectScenario(t *testing.T) {
3030
testtools.RunScenarioTests(&scenTest, t)
3131
}
3232

33-
// httpErr is used to mock an HTTP error. This is required by the download manager,
33+
// httpErr is used to mock an HTTP error. This is required by the transfer manager,
3434
// which calls GetObject until it receives a 415 status code.
3535
type httpErr struct {
3636
statusCode int

gov2/workflows/s3_object_lock/actions/s3_actions.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
"time"
1616

1717
"github.com/aws/aws-sdk-go-v2/aws"
18-
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
18+
"github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager"
1919
"github.com/aws/aws-sdk-go-v2/service/s3"
2020
"github.com/aws/aws-sdk-go-v2/service/s3/types"
2121
"github.com/aws/smithy-go"
@@ -24,7 +24,7 @@ import (
2424
// S3Actions wraps S3 service actions.
2525
type S3Actions struct {
2626
S3Client *s3.Client
27-
S3Manager *manager.Uploader
27+
S3Manager *transfermanager.Client
2828
}
2929

3030
// snippet-end:[gov2.workflows.s3.ObjectLock.S3Actions.struct]
@@ -303,16 +303,16 @@ func (actor S3Actions) PutObjectRetention(ctx context.Context, bucket string, ke
303303

304304
// snippet-start:[gov2.workflows.s3.ObjectLock.UploadObject]
305305

306-
// UploadObject uses the S3 upload manager to upload an object to a bucket.
306+
// UploadObject uses the S3 transfer manager to upload an object to a bucket.
307307
func (actor S3Actions) UploadObject(ctx context.Context, bucket string, key string, contents string) (string, error) {
308308
var outKey string
309-
input := &s3.PutObjectInput{
309+
input := &transfermanager.UploadObjectInput{
310310
Bucket: aws.String(bucket),
311311
Key: aws.String(key),
312312
Body: bytes.NewReader([]byte(contents)),
313-
ChecksumAlgorithm: types.ChecksumAlgorithmSha256,
313+
ChecksumAlgorithm: "SHA256",
314314
}
315-
output, err := actor.S3Manager.Upload(ctx, input)
315+
output, err := actor.S3Manager.UploadObject(ctx, input)
316316
if err != nil {
317317
var noBucket *types.NoSuchBucket
318318
if errors.As(err, &noBucket) {

gov2/workflows/s3_object_lock/actions/s3_actions_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
"time"
1414

1515
"github.com/aws/aws-sdk-go-v2/aws"
16-
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
16+
"github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager"
1717
"github.com/aws/aws-sdk-go-v2/service/s3"
1818
"github.com/aws/aws-sdk-go-v2/service/s3/types"
1919
"github.com/aws/smithy-go"
@@ -142,7 +142,7 @@ func TestUploadObject(t *testing.T) {
142142
ctx, stubber, actor := enterTest()
143143
defer testtools.ExitTest(stubber, t)
144144

145-
actor.S3Manager = manager.NewUploader(actor.S3Client)
145+
actor.S3Manager = transfermanager.New(actor.S3Client)
146146
expectedErr, stubErr := wrapErr(&types.NoSuchBucket{})
147147
checksum := types.ChecksumAlgorithmSha256
148148
stubber.Add(stubs.StubPutObject("amzn-s3-demo-bucket", "test-key", &checksum, stubErr))

gov2/workflows/s3_object_lock/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.24
55
require (
66
github.com/aws/aws-sdk-go-v2 v1.41.5
77
github.com/aws/aws-sdk-go-v2/config v1.27.33
8-
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.18
8+
github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.1.18
99
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3
1010
github.com/aws/smithy-go v1.24.2
1111
github.com/awsdocs/aws-doc-sdk-examples/gov2/demotools v0.0.0-20240907001412-a9375541143b

gov2/workflows/s3_object_lock/workflows/s3_object_lock.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
"s3_object_lock/actions"
1515

1616
"github.com/aws/aws-sdk-go-v2/aws"
17-
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
17+
"github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager"
1818
"github.com/aws/aws-sdk-go-v2/service/s3"
1919
"github.com/aws/aws-sdk-go-v2/service/s3/types"
2020
"github.com/awsdocs/aws-doc-sdk-examples/gov2/demotools"
@@ -36,7 +36,7 @@ func NewObjectLockScenario(sdkConfig aws.Config, questioner demotools.IQuestione
3636
s3Actions: &actions.S3Actions{S3Client: s3.NewFromConfig(sdkConfig)},
3737
sdkConfig: sdkConfig,
3838
}
39-
scenario.s3Actions.S3Manager = manager.NewUploader(scenario.s3Actions.S3Client)
39+
scenario.s3Actions.S3Manager = transfermanager.New(scenario.s3Actions.S3Client)
4040
scenario.resources.init(scenario.s3Actions, questioner)
4141
return scenario
4242
}

0 commit comments

Comments
 (0)