Skip to content

Commit 1b901b3

Browse files
authored
Make crt dependency optional in transfer manager module (#3613)
* Make aws-crt an optional dependency in s3-transfer-manager module. * Update README
1 parent 3e64224 commit 1b901b3

File tree

7 files changed

+52
-8
lines changed

7 files changed

+52
-8
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "removal",
3+
"category": "S3 Transfer Manager",
4+
"contributor": "",
5+
"description": "Make `aws-crt` an optional dependency in `s3-transfer-manager` module. Customers need to explicitly add `aws-crt` dependency if they want to use CRT-based Transfer Manager"
6+
}

services-custom/s3-transfer-manager/README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,23 @@ as well as pause the transfer for execution at a later time.
99

1010
### Add a dependency for the S3 Transfer Manager
1111

12-
First, you need to include the dependency in your project.
12+
First, you need to include `s3-transfer-manager` and `aws-crt` in your project.
1313

1414
```xml
1515
<dependency>
1616
<groupId>software.amazon.awssdk</groupId>
1717
<artifactId>s3-transfer-manager</artifactId>
1818
<version>${awsjavasdk.version}-PREVIEW</version>
1919
</dependency>
20+
<dependency>
21+
<groupId>software.amazon.awssdk.crt</groupId>
22+
<artifactId>aws-crt</artifactId>
23+
<version>${awscrt.version}</version>
24+
</dependency>
2025
```
2126

22-
Note that you need to replace `${awsjavasdk.version}` with the latest
23-
SDK version.
27+
Note that you need to replace `${awsjavasdk.version}` and `${awscrt.version}` with the latest
28+
version.
2429

2530
### Instantiate the S3 Transfer Manager
2631

services-custom/s3-transfer-manager/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
<groupId>software.amazon.awssdk.crt</groupId>
8181
<artifactId>aws-crt</artifactId>
8282
<version>${awscrt.version}</version>
83+
<!-- Only required for CRT-based TM -->
84+
<optional>true</optional>
8385
</dependency>
8486
<dependency>
8587
<groupId>software.amazon.awssdk</groupId>

services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/S3TransferManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,11 @@ default Copy copy(Consumer<CopyRequest.Builder> copyRequestBuilder) {
678678

679679
/**
680680
* Create an {@code S3TransferManager} using the default values.
681+
* <p>
682+
* The type of {@link S3AsyncClient} used depends on if AWS Common Runtime (CRT) library
683+
* {@code software.amazon.awssdk.crt:crt} is on the classpath. If CRT is available, a CRT-based S3 client will be created
684+
* ({@link S3AsyncClient#crtCreate()}). Otherwise, a standard S3 client({@link S3AsyncClient#create()}) will be created. Note
685+
* that only CRT-based S3 client supports parallel transfer for now, so it's recommended to add CRT as a dependency.
681686
*/
682687
static S3TransferManager create() {
683688
return builder().build();

services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/DefaultS3TransferManager.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.concurrent.CompletionException;
2727
import java.util.concurrent.Executor;
2828
import java.util.function.Consumer;
29+
import java.util.function.Supplier;
2930
import software.amazon.awssdk.annotations.SdkInternalApi;
3031
import software.amazon.awssdk.annotations.SdkTestInternalApi;
3132
import software.amazon.awssdk.arns.Arn;
@@ -36,6 +37,7 @@
3637
import software.amazon.awssdk.core.exception.SdkClientException;
3738
import software.amazon.awssdk.core.exception.SdkException;
3839
import software.amazon.awssdk.core.internal.async.FileAsyncRequestBody;
40+
import software.amazon.awssdk.core.internal.util.ClassLoaderHelper;
3941
import software.amazon.awssdk.crt.s3.ResumeToken;
4042
import software.amazon.awssdk.http.SdkHttpExecutionAttributes;
4143
import software.amazon.awssdk.services.s3.S3AsyncClient;
@@ -102,8 +104,14 @@ public final class DefaultS3TransferManager implements S3TransferManager {
102104

103105
public DefaultS3TransferManager(DefaultBuilder tmBuilder) {
104106
transferConfiguration = resolveTransferManagerConfiguration(tmBuilder);
105-
isDefaultS3AsyncClient = tmBuilder.s3AsyncClient == null;
106-
s3AsyncClient = isDefaultS3AsyncClient ? S3AsyncClient.crtCreate() : tmBuilder.s3AsyncClient;
107+
if (tmBuilder.s3AsyncClient == null) {
108+
isDefaultS3AsyncClient = true;
109+
s3AsyncClient = defaultS3AsyncClient().get();
110+
} else {
111+
isDefaultS3AsyncClient = false;
112+
s3AsyncClient = tmBuilder.s3AsyncClient;
113+
}
114+
107115
uploadDirectoryHelper = new UploadDirectoryHelper(transferConfiguration, this::uploadFile);
108116
ListObjectsHelper listObjectsHelper = new ListObjectsHelper(s3AsyncClient::listObjectsV2);
109117
downloadDirectoryHelper = new DownloadDirectoryHelper(transferConfiguration,
@@ -134,6 +142,22 @@ public DefaultS3TransferManager(DefaultBuilder tmBuilder) {
134142
s3ClientType = s3CrtAsyncClient instanceof S3CrtAsyncClient ? S3ClientType.CRT_BASED : S3ClientType.JAVA_BASED;
135143
}
136144

145+
private static Supplier<S3AsyncClient> defaultS3AsyncClient() {
146+
if (crtInClasspath()) {
147+
return S3AsyncClient::crtCreate;
148+
}
149+
return S3AsyncClient::create;
150+
}
151+
152+
private static boolean crtInClasspath() {
153+
try {
154+
ClassLoaderHelper.loadClass("software.amazon.awssdk.crt.s3.S3Client", false);
155+
} catch (ClassNotFoundException e) {
156+
return false;
157+
}
158+
return true;
159+
}
160+
137161
private static TransferManagerConfiguration resolveTransferManagerConfiguration(DefaultBuilder tmBuilder) {
138162
TransferManagerConfiguration.Builder transferConfigBuilder = TransferManagerConfiguration.builder();
139163
transferConfigBuilder.uploadDirectoryFollowSymbolicLinks(tmBuilder.uploadDirectoryFollowSymbolicLinks);

services-custom/s3-transfer-manager/src/test/java/software/amazon/awssdk/transfer/s3/internal/S3TransferManagerTest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,6 @@ class S3TransferManagerTest {
5858
private DownloadDirectoryHelper downloadDirectoryHelper;
5959
private TransferManagerConfiguration configuration;
6060

61-
62-
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
63-
6461
@BeforeEach
6562
public void methodSetup() {
6663
mockS3Crt = mock(S3CrtAsyncClient.class);

test/s3-benchmarks/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@
5656
<artifactId>s3-transfer-manager</artifactId>
5757
<version>${awsjavasdk.version}-PREVIEW</version>
5858
</dependency>
59+
<dependency>
60+
<groupId>software.amazon.awssdk.crt</groupId>
61+
<artifactId>aws-crt</artifactId>
62+
<version>${awscrt.version}</version>
63+
</dependency>
5964
<dependency>
6065
<groupId>com.amazonaws</groupId>
6166
<artifactId>aws-java-sdk-s3</artifactId>

0 commit comments

Comments
 (0)