

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Migrasikan Manajer Transfer dari versi 1 ke versi 2 AWS SDK untuk Java
<a name="migration-s3-transfer-manager"></a>

Panduan migrasi ini mencakup perbedaan utama antara Transfer Manager v1 dan S3 Transfer Manager v2, termasuk perubahan konstruktor, pemetaan metode, dan contoh kode untuk operasi umum. Setelah meninjau perbedaan ini, Anda dapat berhasil memigrasikan kode Transfer Manager yang ada untuk memanfaatkan peningkatan kinerja dan operasi asinkron di v2.

**Tentang alat migrasi AWS SDK**  
 AWS SDK untuk Java Ini menyediakan [alat migrasi](migration-tool.md) otomatis yang dapat memigrasikan sebagian besar API Manajer Transfer v1 ke v2. Namun, alat migrasi tidak mendukung beberapa fitur Manajer Transfer v1. Untuk kasus ini, Anda perlu memigrasikan kode Transfer Manager secara manual menggunakan panduan dalam topik ini.  
Sepanjang panduan ini, **Status Migrasi** menunjukkan apakah alat migrasi dapat secara otomatis memigrasikan konstruktor, metode, atau fitur:  
**Didukung**: Alat migrasi dapat secara otomatis mengubah kode ini
**Tidak Didukung**: Anda perlu memigrasi kode secara manual
Bahkan untuk item yang ditandai sebagai “Didukung,” tinjau hasil migrasi dan uji secara menyeluruh. Migrasi Transfer Manager melibatkan perubahan arsitektur yang signifikan dari operasi sinkron ke asinkron.

## Ikhtisar
<a name="s3-tm-migration-overview"></a>

S3 Transfer Manager v2 memperkenalkan perubahan signifikan pada Transfer Manager API. S3 Transfer Manager v2 dibangun di atas operasi asinkron dan memberikan kinerja yang lebih baik, terutama ketika Anda menggunakan klien Amazon S3 berbasis CRT AWS .

### Perbedaan utama
<a name="s3-tm-migration-key-differences"></a>
+ **Package**: `com.amazonaws.services.s3.transfer` → `software.amazon.awssdk.transfer.s3`
+ **Nama kelas**: `TransferManager` → `S3TransferManager`
+ **Ketergantungan klien**: Klien Amazon S3 sinkron → Klien Amazon S3 asinkron () `S3AsyncClient`
+ **Arsitektur**: Operasi sinkron → Operasi asinkron dengan `CompletableFuture`
+ **Kinerja**: Ditingkatkan dengan dukungan AWS klien berbasis CRT

## Perubahan tingkat tinggi
<a name="s3-tm-migration-high-level-changes"></a>


| Aspek | V1 | V2 | 
| --- | --- | --- | 
| Ketergantungan Maven | aws-java-sdk-s3 | s3-transfer-manager | 
| Package | com.amazonaws.services.s3.transfer | software.amazon.awssdk.transfer.s3 | 
| Kelas utama | TransferManager | S3TransferManager | 
| Klien Amazon S3 | AmazonS3(sinkronisasi) | S3AsyncClient(asinkron) | 
| Jenis pengembalian | Operasi pemblokiran | CompletableFuture<T> | 

## Ketergantungan Maven
<a name="s3-tm-migration-dependencies"></a>


| V1 | V2 | 
| --- | --- | 
|  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>com.amazonaws</groupId><br />            <artifactId>aws-java-sdk-bom</artifactId><br />            <version>>1.12.7871</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-java-sdk-s3</artifactId><br />    </dependency><br /></dependencies></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.31.682</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>s3-transfer-manager</artifactId><br />    </dependency><br />    <!-- Optional: For enhanced performance with AWS CRT --><br />    <dependency><br />        <groupId>software.amazon.awssdk.crt</groupId><br />        <artifactId>aws-crt</artifactId><br />        <version>0.38.53</version><br />    </dependency><br /></dependencies></pre>  | 

1 [Versi terbaru](https://central.sonatype.com/artifact/com.amazonaws/aws-java-sdk-bom). 2 [Versi terbaru](https://central.sonatype.com/artifact/software.amazon.awssdk/bom). 3 [Versi terbaru](https://central.sonatype.com/artifact/software.amazon.awssdk.crt/aws-crt).

## Migrasi konstruktor klien
<a name="s3-tm-migration-client-constructor"></a>

### Konstruktor yang didukung (migrasi otomatis)
<a name="s3-tm-migration-supported-constructors"></a>


| V1 konstruktor | V2 setara | Status migrasi | 
| --- | --- | --- | 
| new TransferManager() | S3TransferManager.create() | Didukung | 
| TransferManagerBuilder. defaultTransferManager() | S3TransferManager.create() | Didukung | 
| TransferManagerBuilder. standard().build() | S3TransferManager.builder().build() | Didukung | 
| new TransferManager(AWSCredentials) | S3TransferManager.builder() .s3Client(S3AsyncClient.builder() .credentialsProvider(...).build()) .build() | Didukung | 
| new TransferManager( AWSCredentialsProvider) | S3TransferManager.builder() .s3Client(S3AsyncClient.builder() .credentialsProvider(...).build()) .build() | Didukung | 

### Konstruktor yang tidak didukung (diperlukan migrasi manual)
<a name="s3-tm-migration-unsupported-constructors"></a>


| V1 konstruktor | V2 setara | Catatan migrasi | 
| --- | --- | --- | 
| new TransferManager(AmazonS3) | Migrasi manual diperlukan | Buat secara S3AsyncClient terpisah | 
| new TransferManager(AmazonS3, ExecutorService) | Migrasi manual diperlukan | Buat S3AsyncClient dan konfigurasikan eksekutor | 
| new TransferManager(AmazonS3, ExecutorService, boolean) | Migrasi manual diperlukan | shutDownThreadPoolsparameter tidak didukung | 

### Contoh migrasi manual
<a name="s3-tm-migration-manual-examples"></a>

**Kode V1:**

```
AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();
TransferManager transferManager = new TransferManager(s3Client);
```

**Kode V2:**

```
// Create an `S3AsyncClient` with similar configuration
S3AsyncClient s3AsyncClient = S3AsyncClient.builder()
    .credentialsProvider(DefaultCredentialsProvider.create())
    .build();

// Provide the configured `S3AsyncClient` to the S3 transfer manager builder.
S3TransferManager transferManager = S3TransferManager.builder()
    .s3Client(s3AsyncClient)
    .build();
```

## Migrasi metode klien
<a name="s3-tm-migration-client-methods"></a>

Saat ini, alat migrasi mendukung dasar `copy``download`,`upload`,`uploadDirectory`,`downloadDirectory`,`resumeDownload`, dan `resumeUpload` metode.

### Metode transfer inti
<a name="s3-tm-migration-core-transfer-methods"></a>


| Metode V1 | Metode V2 | Kembalikan perubahan tipe | Status migrasi | 
| --- | --- | --- | --- | 
| upload(String, String, File) | uploadFile(UploadFileRequest) | Upload → FileUpload | Didukung | 
| upload(PutObjectRequest) | upload(UploadRequest) | Upload → Upload | Didukung | 
| download(String, String, File) | downloadFile(DownloadFileRequest) | Download → FileDownload | Didukung | 
| download(GetObjectRequest, File) | downloadFile(DownloadFileRequest) | Download → FileDownload | Didukung | 
| copy(String, String, String, String) | copy(CopyRequest) | Copy → Copy | Didukung | 
| copy(CopyObjectRequest) | copy(CopyRequest) | Copy → Copy | Didukung | 
| uploadDirectory(String, String, File, boolean) | uploadDirectory( UploadDirectoryRequest) | MultipleFileUpload → DirectoryUpload | Didukung | 
| downloadDirectory(String, String, File) | downloadDirectory( DownloadDirectoryRequest) | MultipleFileDownload → DirectoryDownload | Didukung | 

### Metode transfer yang dapat dilanjutkan
<a name="s3-tm-migration-resumable-methods"></a>


| Metode V1 | Metode V2 | Status migrasi | 
| --- | --- | --- | 
| resumeUpload(PersistableUpload) | resumeUploadFile(ResumableFileUpload) | Didukung | 
| resumeDownload(PersistableDownload) | resumeDownloadFile(ResumableFileDownload) | Didukung | 

### Metode siklus hidup
<a name="s3-tm-migration-lifecycle-methods"></a>


| Metode V1 | Metode V2 | Status migrasi | 
| --- | --- | --- | 
| shutdownNow() | close() | Didukung | 
| shutdownNow(boolean) | Sesuaikan kode secara manual menggunakan close() metode | Tidak Didukung | 

### Metode klien V1 yang tidak didukung
<a name="s3-tm-migration-unsupported-methods"></a>


| Metode V1 | V2 alternatif | Catatan | 
| --- | --- | --- | 
| abortMultipartUploads(String, Date) | Gunakan klien Amazon S3 tingkat rendah | Tidak Didukung | 
| getAmazonS3Client() | Simpan referensi secara terpisah | Tidak Didukung; tidak ada pengambil di v2 | 
| getConfiguration() | Simpan referensi secara terpisah | Tidak Didukung; tidak ada pengambil di v2 | 
| uploadFileList(...) | Lakukan beberapa uploadFile() panggilan | Tidak Didukung | 
| copymetode dengan TransferStateChangeListener parameter | Gunakan TransferListener | [Lihat contoh migrasi manual](#tm-unsupported-client-methods-copy) | 
| downloadmetode dengan S3ProgressListener parameter | Gunakan [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/progress/TransferListener.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/progress/TransferListener.html) | [Lihat contoh migrasi manual](#tm-unsupported-client-methods-download) | 
|  `downloadDirectory`metode dengan 4 atau lebih parameter  |  | [Lihat contoh migrasi manual](#tm-unsupported-client-methods-download-dir) | 
| uploadmetode dengan ObjectMetadataProvider parameter | Tetapkan metadata dalam permintaan | [Lihat contoh migrasi manual](#tm-unsupported-client-methods-upload) | 
| uploadDirectorymetode dengan \$1Provider parameter | Tetapkan tag dalam permintaan | [Lihat contoh migrasi manual](#tm-unsupported-client-methods-uploadDirectory) | 

#### `copy`metode dengan `TransferStateChangeListener` parameter
<a name="tm-unsupported-client-methods-copy"></a>
+ `copy(CopyObjectRequest copyObjectRequest, AmazonS3 srcS3, TransferStateChangeListener stateChangeListener)`
+ `copy(CopyObjectRequest copyObjectRequest, TransferStateChangeListener stateChangeListener)`

```
// V1 ----------------------------------------------------------------------------------------------
// Initialize source S3 client
AmazonS3 s3client = AmazonS3ClientBuilder.standard()
                .withRegion("us-west-2")
                .build();
                
// Initialize Transfer Manager
TransferManager tm = TransferManagerBuilder.standard()
                .withS3Client(srcS3)
                .build();

CopyObjectRequest copyObjectRequest = new CopyObjectRequest(
                "amzn-s3-demo-source-bucket",
                "source-key",         
                "amzn-s3-demo-destination-bucket", 
                "destination-key"    
        );

TransferStateChangeListener stateChangeListener = new TransferStateChangeListener() {
            @Override
            public void transferStateChanged(Transfer transfer, TransferState state) {
              //Implementation of the TransferStateChangeListener
            }
        };

Copy copy = tm.copy(copyObjectRequest, srcS3, stateChangeListener);


// V2 ----------------------------------------------------------------------------------------------
S3AsyncClient s3AsyncClient = S3AsyncClient.builder()
                .region(Region.US_WEST_2)          
                .build();

S3TransferManager transferManager = S3TransferManager.builder()
                .s3Client(s3AsyncClient)
                .build();

// Create transfer listener (equivalent to TransferStateChangeListener in v1)                                
TransferListener transferListener = new TransferListener() {
            @Override
            public void transferInitiated(Context.TransferInitiated context) {
               //Implementation
               System.out.println("Transfer initiated");
            }

            @Override
            public void bytesTransferred(Context.BytesTransferred context) {
                //Implementation
                System.out.println("Bytes transferred");
            }

            @Override
            public void transferComplete(Context.TransferComplete context) {
                //Implementation
                System.out.println("Transfer completed!");
            }

            @Override
            public void transferFailed(Context.TransferFailed context) {
                //Implementation
                System.out.println("Transfer failed");
            }
        };

CopyRequest copyRequest = CopyRequest.builder()
                              .copyObjectRequest(req -> req
                                  .sourceBucket("amzn-s3-demo-source-bucket")
                                  .sourceKey("source-key")
                                  .destinationBucket("amzn-s3-demo-destination-bucket")
                                  .destinationKey("destination-key")
                               )
                                .addTransferListener(transferListener) // Configure the transferListener into the request
                                .build();
  
Copy copy = transferManager.copy(copyRequest);
```

#### `download`metode dengan `S3ProgressListener` parameter
<a name="tm-unsupported-client-methods-download"></a>
+ `download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener)`
+ `download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener, long timeoutMillis)`
+ `download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener, long timeoutMillis, boolean resumeOnRetry)`

```
// V1 ----------------------------------------------------------------------------------------------
S3ProgressListener progressListener = new S3ProgressListener() {
        @Override
        public void progressChanged(com.amazonaws.event.ProgressEvent progressEvent) {
            long bytes = progressEvent.getBytesTransferred();
            ProgressEventType eventType = progressEvent.getEventType();
            // Use bytes and eventType as needed
        }

        @Override
        public void onPersistableTransfer(PersistableTransfer persistableTransfer) {

        }
    };

Download download1 = tm.download(getObjectRequest, file, progressListener); 
Download download2 = tm.download(getObjectRequest, file, progressListener, timeoutMillis)
Download download3 = tm.download(getObjectRequest, file, progressListener, timeoutMillis, true)

// V2 ----------------------------------------------------------------------------------------------
TransferListener transferListener = new TransferListener() {
    @Override
    public void transferInitiated(Context.InitializedContext context) {
        // Equivalent to ProgressEventType.TRANSFER_STARTED_EVENT
        System.out.println("Transfer initiated");
    }

    @Override
    public void bytesTransferred(Context.BytesTransferred context) {
        // Equivalent to ProgressEventType.REQUEST_BYTE_TRANSFER_EVENT
        long bytes = context.bytesTransferred();
        System.out.println("Bytes transferred: " + bytes);
    }

    @Override
    public void transferComplete(Context.TransferComplete context) {
        // Equivalent to ProgressEventType.TRANSFER_COMPLETED_EVENT
        System.out.println("Transfer completed");
    }

    @Override
    public void transferFailed(Context.TransferFailed context) {
        // Equivalent to ProgressEventType.TRANSFER_FAILED_EVENT
        System.out.println("Transfer failed: " + context.exception().getMessage());
    }
};
DownloadFileRequest downloadFileRequest = 
                         DownloadFileRequest.builder()
                             .getObjectRequest(getObjectRequest)
                             .destination(file.toPath())
                             .addTransferListener(transferListener)
                             .build();

// For download1
FileDownload download = transferManager.downloadFile(downloadFileRequest);

// For download2
CompletedFileDownload completedFileDownload = download.completionFuture()
                                                  .get(timeoutMillis, TimeUnit.MILLISECONDS);

// For download3, the v2 SDK does not have a direct equiavalent to the `resumeOnRetry` method of v1.
// If a download is interrupted, you need to start a new download request.
```

#### `downloadDirectory`metode dengan 4 atau lebih parameter
<a name="tm-unsupported-client-methods-download-dir"></a>
+ `downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, boolean resumeOnRetry)`
+ `downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, boolean resumeOnRetry, KeyFilter filter)`
+ `downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, KeyFilter filter)`

```
// V1 ----------------------------------------------------------------------------------------------
KeyFilter filter = new KeyFilter() {
            @Override
            public boolean shouldInclude(S3ObjectSummary objectSummary) {
                //Filter implementation
            }
        };
MultipleFileDownload multipleFileDownload = tm.downloadDirectory(bucketName, keyPrefix, destinationDirectory, filter);

// V2 ----------------------------------------------------------------------------------------------
// The v2 SDK does not have a direct equiavalent to the `resumeOnRetry` method of v1.
// If a download is interrupted, you need to start a new download request.
DownloadFilter filter = new DownloadFilter() {
            @Override
            public boolean test(S3Object s3Object) {
                // Filter implementation.
            }
        };

DownloadDirectoryRequest downloadDirectoryRequest = 
                              DownloadDirectoryRequest.builder()
                                  .bucket(bucketName)
                                  .filter(filter)
                                  .listObjectsV2RequestTransformer(builder -> builder.prefix(keyPrefix))
                                  .destination(destinationDirectory.toPath())
                                  .build();
                                                                            
DirectoryDownload directoryDownload = transferManager.downloadDirectory(downloadDirectoryRequest);
```

#### `upload`metode dengan `ObjectMetadata` parameter
<a name="tm-unsupported-client-methods-upload"></a>
+ `upload(String bucketName, String key, InputStream input, ObjectMetadata objectMetadata)`

```
// V1 ----------------------------------------------------------------------------------------------ObjectMetadata metadata = new ObjectMetadata();
ObjectMetadata metadata = new ObjectMetadata();

metadata.setContentType("text/plain");        // System-defined metadata
metadata.setContentLength(22L);               // System-defined metadata
metadata.addUserMetadata("myKey", "myValue"); // User-defined metadata

PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, metadata);

Upload upload = transferManager.upload("amzn-s3-demo-bucket", "my-key", inputStream, metadata);

// V2 ----------------------------------------------------------------------------------------------
/* When you use an InputStream to upload in V2, you should specify the content length 
   and use `RequestBody.fromInputStream()`. 
   If you don't provide the content length, the entire stream will be buffered in memory. 
   If you can't determine the content length, we recommend using the CRT-based S3 client.
*/
Map<String, String> userMetadata = new HashMap<>();
userMetadata.put("x-amz-meta-myKey", "myValue");

PutObjectRequest putObjectRequest = 
                        PutObjectRequest.builder()
                            .bucket("amzn-s3-demo-bucket1")
                            .key("k")
                            .contentType("text/plain") //System-defined metadata usually has separate methods in the builder.
                            .contentLength(22L)
                            .metadata(userMetadata) //metadata() is only for user-defined metadata.
                            .build();

UploadRequest uploadRequest = 
                        UploadRequest.builder()
                            .putObjectRequest(putObjectRequest)
                            .requestBody(AsyncRequestBody.fromInputStream(stream, 22L, executor))
                            .build();
                                                   
transferManager.upload(uploadRequest).completionFuture().join();
```

#### `uploadDirectory`dengan `ObjectMetadataProvider` parameter
<a name="tm-unsupported-client-methods-uploadDirectory"></a>
+ `uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider)`
+ `uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider, ObjectTaggingProvider taggingProvider)`
+ `uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider, ObjectTaggingProvider taggingProvider, ObjectCannedAclProvider cannedAclProvider)`

```
// V1 ----------------------------------------------------------------------------------------------
tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider)
tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider, taggingProvider)
tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider, taggingProvider, cannedAclProvider)

// V2 ----------------------------------------------------------------------------------------------
UploadDirectoryRequest request = UploadDirectoryRequest.builder()
                                  .bucket(bucketName)
                                  .s3Prefix(virtualDirectoryKeyPrefix)
                                  .source(directory.toPath())
                                  .maxDepth(includeSubdirectories ? Integer.MAX_VALUE : 1)
                                  .uploadFileRequestTransformer(builder -> {
                                      // 1.Replace `ObjectMetadataProvider`, `ObjectTaggingProvider`, and `ObjectCannedAclProvider` with an
                                        // `UploadFileRequestTransformer` that can combine the functionality of all three *Provider implementations.
                                        // 2. Convert your v1 `ObjectMetadata` to v2 `PutObjectRequest` parameters.
                                        // 3. Convert your v1 `ObjectTagging` to v2 `Tagging`.
                                        // 4. Convert your v1 `CannedAccessControlList` to v2 `ObjectCannedACL`.
                                  })
                                  .build();
        
DirectoryUpload directoryUpload = transferManager.uploadDirectory(request);
```

## Migrasi objek model
<a name="s3-tm-migration-model-objects"></a>

Pada tahun AWS SDK for Java 2.x, banyak objek `TransferManager` model telah didesain ulang, dan beberapa metode pengambil dan penyetel yang tersedia di objek model v1 tidak lagi didukung. 

Di v2, Anda dapat menggunakan `CompletableFuture<T>` kelas untuk melakukan tindakan saat transfer selesai — baik berhasil atau dengan pengecualian. Anda dapat menggunakan `join()` metode ini untuk menunggu penyelesaian jika diperlukan. 

### Objek transfer inti
<a name="s3-tm-migration-core-transfer-objects"></a>


| Kelas V1 | Kelas V2 | Status migrasi | 
| --- | --- | --- | 
| TransferManager | S3TransferManager | Didukung | 
| TransferManagerBuilder | S3TransferManager.Builder | Didukung | 
| Transfer | Transfer | Didukung | 
| AbortableTransfer | Transfer | Didukung (tidak ada kelas terpisah) | 
| Copy | Copy | Didukung | 
| Download | FileDownload | Didukung | 
| Upload | Upload / FileUpload | Didukung | 
| MultipleFileDownload | DirectoryDownload | Didukung | 
| MultipleFileUpload | DirectoryUpload | Didukung | 

### Objek ketekunan
<a name="s3-tm-migration-persistence-objects"></a>


| Kelas V1 | Kelas V2 | Status migrasi | 
| --- | --- | --- | 
| PersistableDownload | ResumableFileDownload | Didukung | 
| PersistableUpload | ResumableFileUpload | Didukung | 
| PersistableTransfer | ResumableTransfer | Didukung | 
| PauseResult<T> | Objek langsung yang dapat dilanjutkan | Tidak Didukung | 

### Objek hasil
<a name="s3-tm-migration-result-objects"></a>


| Kelas V1 | Kelas V2 | Status migrasi | 
| --- | --- | --- | 
| CopyResult | CompletedCopy | Didukung | 
| UploadResult | CompletedUpload | Didukung | 

### Objek konfigurasi
<a name="s3-tm-migration-configuration-objects"></a>


| Kelas V1 | Kelas V2 | Status migrasi | 
| --- | --- | --- | 
| TransferManagerConfiguration | MultipartConfiguration(di klien Amazon S3) | Didukung | 
| TransferProgress | TransferProgress \$1 TransferProgressSnapshot | Didukung | 
| KeyFilter | DownloadFilter | Didukung | 

### Objek yang tidak didukung
<a name="s3-tm-migration-unsupported-objects"></a>


| Kelas V1 | V2 alternatif | Status migrasi | 
| --- | --- | --- | 
| PauseStatus | Tidak didukung | Tidak Didukung | 
| UploadContext | Tidak didukung | Tidak Didukung | 
| ObjectCannedAclProvider | PutObjectRequest.builder().acl() | Tidak Didukung | 
| ObjectMetadataProvider | PutObjectRequest.builder().metadata() | Tidak Didukung | 
| ObjectTaggingProvider | PutObjectRequest.builder().tagging() | Tidak Didukung | 
| PresignedUrlDownload | Tidak didukung | Tidak Didukung | 

## TransferManagerBuilder migrasi konfigurasi
<a name="s3-tm-migration-builder-configuration"></a>

### Perubahan konfigurasi
<a name="migration-transfer-manager-config-changes"></a>

Perubahan konfigurasi yang perlu Anda atur untuk manajer transfer v2 bergantung pada klien S3 mana yang Anda gunakan. Anda memiliki pilihan klien S3 AWS berbasis CRT atau klien async S3 berbasis Java standar. Untuk informasi tentang perbedaan, lihat [Klien S3 di AWS SDK for Java 2.x](examples-s3.md#s3-clients) topiknya.

------
#### [ Use the AWS CRT-based S3 client ]


****  

| Pengaturan | v1 | v2 - Transfer Manager menggunakan klien AWS S3 berbasis CRT | 
| --- | --- | --- | 
|    (dapatkan pembangun)  |  <pre>TransferManagerBuilder tmBuilder = <br />   TransferManagerBuilder.standard();</pre>  |  <pre>S3TransferManager.Builder tmBuilder  = <br />  S3TransferManager.builder();</pre>  | 
|    Klien S3  |  <pre>tmBuilder.withS3Client(...);<br />tmBuilder.setS3Client(...);</pre>  |  <pre>tmBuilder.s3Client(...);</pre>  | 
|    Pelaksana  |  <pre>tmBuilder.withExecutorFactory(...);<br />tmBuilder.setExecutorFactory(...);</pre>  |  <pre>tmBuilder.executor(...);</pre>  | 
|    Shutdown thread pool  |  <pre>tmBuilder.withShutDownThreadPools(...);<br />tmBuilder.setShutdownThreadPools(...);</pre>  | Tidak didukung. Pelaksana yang disediakan tidak akan dimatikan saat S3TransferManager ditutup | 
|    Ukuran bagian unggahan minimum  |  <pre>tmBuilder.withMinimumUploadPartSize(...);<br />tmBuilder.setMinimumUploadPartSize(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.crtBuilder().<br />      minimumPartSizeInBytes(...).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    Ambang batas unggahan multipart  |  <pre>tmBuilder.withMultipartUploadThreshold(...);<br />tmBuilder.setMultipartUploadThreshold(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.crtBuilder().<br />      thresholdInBytes(...).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    Ukuran bagian salinan minimum  |  <pre>tmBuilder.withMultipartCopyPartSize(...);<br />tmBuilder.setMultipartCopyPartSize(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.crtBuilder().<br />      minimumPartSizeInBytes(...).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    Ambang batas salinan multipart  |  <pre>tmBuilder.withMultipartCopyThreshold(...);<br />tmBuilder.setMultipartCopyThreshold(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.crtBuilder().<br />      thresholdInBytes(...).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    Nonaktifkan unduhan paralel  |  <pre>tmBuilder.withDisableParallelDownloads(...);<br />tmBuilder.setDisableParallelDownloads(...);</pre>  | Nonaktifkan unduhan paralel dengan meneruskan klien S3 berbasis Java standar dengan multipart dinonaktifkan (default) ke manajer transfer.<pre>S3AsyncClient s3 =<br />   S3AsyncClient.builder().build();<br /><br />tmBuilder.s3Client(s3);</pre> | 
|    Selalu hitung multipart md5  |  <pre>tmBuilder.withAlwaysCalculateMultipartMd5(...);<br />tmBuilder.setAlwaysCalculateMultipartMd5(...);</pre>  | Tidak didukung. | 

------
#### [ Use Java-based S3 async client ]


****  

| Pengaturan | v1 | v2 - Transfer Manager menggunakan klien async S3 berbasis Java | 
| --- | --- | --- | 
|    (dapatkan pembangun)  |  <pre>TransferManagerBuilder tmBuilder = <br />   TransferManagerBuilder.standard();</pre>  |  <pre>S3TransferManager.Builder tmBuilder  = <br />  S3TransferManager.builder();</pre>  | 
|    Klien S3  |  <pre>tmBuilder.withS3Client(...);<br />tmBuilder.setS3Client(...);</pre>  |  <pre>tmBuilder.s3Client(...);</pre>  | 
|    Pelaksana  |  <pre>tmBuilder.withExecutorFactory(...);<br />tmBuilder.setExecutorFactory(...);</pre>  |  <pre>tmBuilder.executor(...);</pre>  | 
|    Shutdown thread pool  |  <pre>tmBuilder.withShutDownThreadPools(...);<br />tmBuilder.setShutdownThreadPools(...);</pre>  | Tidak didukung. Pelaksana yang disediakan tidak akan dimatikan saat S3TransferManager ditutup | 
|    Ukuran bagian unggahan minimum  |  <pre>tmBuilder.withMinimumUploadPartSize(...);<br />tmBuilder.setMinimumUploadPartSize(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.builder()<br />    .multipartConfiguration(cfg -><br />        cfg.minimumPartSizeInBytes(...)).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    Ambang batas unggahan multipart  |  <pre>tmBuilder.withMultipartUploadThreshold(...);<br />tmBuilder.setMultipartUploadThreshold(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.builder()<br />    .multipartConfiguration(cfg -><br />        cfg.thresholdInBytes(...)).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    Ukuran bagian salinan minimum  |  <pre>tmBuilder.withMultipartCopyPartSize(...);<br />tmBuilder.setMultipartCopyPartSize(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.builder()<br />    .multipartConfiguration(cfg -><br />        cfg.minimumPartSizeInBytes(...)).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    Ambang batas salinan multipart  |  <pre>tmBuilder.withMultipartCopyThreshold(...);<br />tmBuilder.setMultipartCopyThreshold(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.builder()<br />    .multipartConfiguration(cfg -><br />        cfg.thresholdInBytes(...)).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    Nonaktifkan unduhan paralel  |  <pre>tmBuilder.withDisableParallelDownloads(...);<br />tmBuilder.setDisableParallelDownloads(...);</pre>  | Nonaktifkan unduhan paralel dengan meneruskan klien S3 berbasis Java standar dengan multipart dinonaktifkan (default) ke manajer transfer.<pre>S3AsyncClient s3 =<br />   S3AsyncClient.builder().build();<br /><br />tmBuilder.s3Client(s3);</pre> | 
|    Selalu hitung multipart md5  |  <pre>tmBuilder.withAlwaysCalculateMultipartMd5(...);<br />tmBuilder.setAlwaysCalculateMultipartMd5(...);</pre>  | Tidak didukung. | 

------

## Perubahan perilaku
<a name="s3-tm-migration-behavior-changes"></a>

### Operasi asinkron
<a name="s3-tm-migration-async-operations"></a>

**V1 (pemblokiran):**

```
Upload upload = transferManager.upload("amzn-s3-demo-bucket", "key", file);
upload.waitForCompletion(); // Blocks until complete
```

**V2 (asinkron):**

```
FileUpload upload = transferManager.uploadFile(UploadFileRequest.builder()
    .putObjectRequest(PutObjectRequest.builder()
        .bucket("amzn-s3-demo-bucket")
        .key("key")
        .build())
    .source(file)
    .build());

CompletedFileUpload result = upload.completionFuture().join(); // Blocks until complete
// Or handle asynchronously:
upload.completionFuture().thenAccept(result -> {
    System.out.println("Upload completed: " + result.response().eTag());
});
```

### Penanganan kesalahan
<a name="s3-tm-migration-error-handling"></a>

**V1:** Transfer direktori gagal sepenuhnya jika ada sub-permintaan yang gagal.

**V2:** Transfer direktori berhasil diselesaikan bahkan jika beberapa sub-permintaan gagal. Periksa kesalahan secara eksplisit:

```
DirectoryUpload directoryUpload = transferManager.uploadDirectory(request);
CompletedDirectoryUpload result = directoryUpload.completionFuture().join();

// Check for failed transfers
if (!result.failedTransfers().isEmpty()) {
    System.out.println("Some uploads failed:");
    result.failedTransfers().forEach(failed -> 
        System.out.println("Failed: " + failed.exception().getMessage()));
}
```

### Unduhan paralel melalui pengambilan rentang byte
<a name="migration-transfer-manager-behavior-fetches"></a>

Ketika fitur transfer paralel otomatis diaktifkan di SDK v2, Manajer Transfer S3 menggunakan [pengambilan rentang byte untuk mengambil](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-guidelines.html#optimizing-performance-guidelines-get-range) bagian tertentu dari objek secara paralel (unduhan multibagian). Cara objek diunduh dengan v2 tidak tergantung pada bagaimana objek awalnya diunggah. Semua unduhan dapat memperoleh manfaat dari throughput dan konkurensi yang tinggi. 

Sebaliknya, dengan Transfer Manager v1, penting bagaimana objek awalnya diunggah. Manajer Transfer v1 mengambil bagian-bagian objek dengan cara yang sama seperti bagian-bagian yang diunggah. Jika objek awalnya diunggah sebagai objek tunggal, Manajer Transfer v1 tidak dapat mempercepat proses pengunduhan dengan menggunakan sub-permintaan.