Skip to content

Commit 86dfdbe

Browse files
authored
feat(storage): Add support for S3 acceleration mode (#2304)
1 parent 48e294b commit 86dfdbe

File tree

45 files changed

+787
-363
lines changed

Some content is hidden

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

45 files changed

+787
-363
lines changed

aws-api/src/main/java/com/amplifyframework/api/aws/auth/IamRequestDecorator.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,20 @@
1818
import com.amplifyframework.api.ApiException.ApiAuthException;
1919
import com.amplifyframework.api.aws.sigv4.AWS4Signer;
2020

21+
import aws.smithy.kotlin.runtime.net.Url;
22+
2123
import java.io.ByteArrayOutputStream;
2224
import java.io.IOException;
2325
import java.util.List;
2426
import java.util.Map;
2527

2628
import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider;
29+
import aws.smithy.kotlin.runtime.http.DeferredHeaders;
2730
import aws.smithy.kotlin.runtime.http.Headers;
2831
import aws.smithy.kotlin.runtime.http.HttpMethod;
29-
import aws.smithy.kotlin.runtime.http.Url;
3032
import aws.smithy.kotlin.runtime.http.content.ByteArrayContent;
3133
import aws.smithy.kotlin.runtime.http.request.HttpRequest;
34+
import aws.smithy.kotlin.runtime.http.request.HttpRequestKt;
3235
import okhttp3.MediaType;
3336
import okhttp3.RequestBody;
3437
import okio.Buffer;
@@ -79,7 +82,7 @@ public final okhttp3.Request decorate(okhttp3.Request req) throws ApiAuthExcepti
7982
return null;
8083
});
8184

82-
HttpRequest req2 = new HttpRequest(method, url, headers, body2);
85+
HttpRequest req2 = HttpRequestKt.HttpRequest(method, url, headers, body2, DeferredHeaders.Companion.getEmpty());
8386

8487
HttpRequest request = v4Signer.signBlocking(req2, credentialsProvider, serviceName).getOutput();
8588

@@ -124,8 +127,8 @@ private byte[] getBytes(RequestBody body) throws ApiAuthException {
124127
return output.toByteArray();
125128
} catch (IOException exception) {
126129
throw new ApiAuthException("Unable to calculate SigV4 signature for the request",
127-
exception,
128-
"Check your application logs for details.");
130+
exception,
131+
"Check your application logs for details.");
129132
}
130133
}
131134
}

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/AWSCognitoAuthService.kt

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ package com.amplifyframework.auth.cognito
1717

1818
import aws.sdk.kotlin.services.cognitoidentity.CognitoIdentityClient
1919
import aws.sdk.kotlin.services.cognitoidentityprovider.CognitoIdentityProviderClient
20-
import aws.smithy.kotlin.runtime.http.endpoints.Endpoint
20+
import aws.smithy.kotlin.runtime.client.endpoints.Endpoint
21+
import aws.smithy.kotlin.runtime.client.endpoints.EndpointProvider
2122
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
2223

2324
interface AWSCognitoAuthService {
@@ -30,8 +31,8 @@ interface AWSCognitoAuthService {
3031

3132
CognitoIdentityProviderClient {
3233
this.region = it.region
33-
this.endpointResolver = it.endpoint?.let { endpoint ->
34-
AWSEndpointResolver(Endpoint(endpoint))
34+
this.endpointProvider = it.endpoint?.let { endpoint ->
35+
EndpointProvider { Endpoint(endpoint) }
3536
}
3637
}
3738
}

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/AWSEndpointResolver.kt

-27
This file was deleted.

aws-predictions/src/main/java/com/amplifyframework/predictions/aws/service/AmazonPollyPresigningClient.kt

+3-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package com.amplifyframework.predictions.aws.service
1717
import androidx.annotation.WorkerThread
1818
import aws.sdk.kotlin.services.polly.PollyClient
1919
import aws.sdk.kotlin.services.polly.model.SynthesizeSpeechRequest
20-
import aws.sdk.kotlin.services.polly.presigners.PollyPresignConfig
2120
import aws.sdk.kotlin.services.polly.presigners.presign
2221
import java.net.URL
2322
import kotlin.time.Duration.Companion.seconds
@@ -51,12 +50,10 @@ class AmazonPollyPresigningClient(pollyClient: PollyClient) : PollyClient by pol
5150
options: PresignedSynthesizeSpeechUrlOptions
5251
): URL {
5352
val presignCredentialsProvider = options.credentialsProvider ?: this.config.credentialsProvider
54-
val presignConfig = PollyPresignConfig {
55-
region = this@AmazonPollyPresigningClient.config.region
56-
credentialsProvider = presignCredentialsProvider
57-
}
53+
val configBuilder = this@AmazonPollyPresigningClient.config.toBuilder()
54+
configBuilder.credentialsProvider = presignCredentialsProvider
5855
val presignedRequest = runBlocking {
59-
synthesizeSpeechRequest.presign(presignConfig, options.expires.seconds)
56+
synthesizeSpeechRequest.presign(configBuilder.build(), options.expires.seconds)
6057
}
6158
return URL(presignedRequest.url.toString())
6259
}

aws-storage-s3/src/androidTest/java/com/amplifyframework/storage/s3/AWSS3StorageDownloadTest.java

+18-5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.amplifyframework.storage.operation.StorageDownloadFileOperation;
3333
import com.amplifyframework.storage.options.StorageDownloadFileOptions;
3434
import com.amplifyframework.storage.options.StorageUploadFileOptions;
35+
import com.amplifyframework.storage.s3.options.AWSS3StorageDownloadFileOptions;
3536
import com.amplifyframework.storage.s3.test.R;
3637
import com.amplifyframework.storage.s3.util.WorkmanagerTestUtils;
3738
import com.amplifyframework.testutils.FileAssert;
@@ -96,8 +97,8 @@ public static void setUpOnce() throws Exception {
9697
// Upload to PUBLIC for consistency
9798
String key;
9899
StorageUploadFileOptions uploadOptions = StorageUploadFileOptions.builder()
99-
.accessLevel(TESTING_ACCESS_LEVEL)
100-
.build();
100+
.accessLevel(TESTING_ACCESS_LEVEL)
101+
.build();
101102

102103
// Upload large test file
103104
largeFile = new RandomTempFile(LARGE_FILE_NAME, LARGE_FILE_SIZE);
@@ -119,8 +120,8 @@ public static void setUpOnce() throws Exception {
119120
public void setUp() throws Exception {
120121
// Always interact with PUBLIC access for consistency
121122
options = StorageDownloadFileOptions.builder()
122-
.accessLevel(TESTING_ACCESS_LEVEL)
123-
.build();
123+
.accessLevel(TESTING_ACCESS_LEVEL)
124+
.build();
124125

125126
// Create a set to remember all the subscriptions
126127
subscriptions = new HashSet<>();
@@ -273,7 +274,7 @@ public void testGetTransferOnPause() throws Exception {
273274
final AtomicReference<StorageDownloadFileOperation<?>> opContainer = new AtomicReference<>();
274275
final AtomicReference<String> transferId = new AtomicReference<>();
275276
final AtomicReference<Throwable> errorContainer = new AtomicReference<>();
276-
// Listen to Hub events to resume when operation has been paused
277+
// Listen to Hub events to resume when operation has been paused
277278
SubscriptionToken resumeToken = Amplify.Hub.subscribe(HubChannel.STORAGE, hubEvent -> {
278279
if (StorageChannelEventName.DOWNLOAD_STATE.toString().equals(hubEvent.getName())) {
279280
HubEvent<String> stateEvent = (HubEvent<String>) hubEvent;
@@ -317,4 +318,16 @@ public void testGetTransferOnPause() throws Exception {
317318
assertNull(errorContainer.get());
318319
FileAssert.assertEquals(largeFile, downloadFile);
319320
}
321+
322+
/**
323+
* Tests download fails due to acceleration mode disabled.
324+
*
325+
* @throws Exception download fails because acceleration is not enabled on test bucket.
326+
*/
327+
@Test
328+
public void testDownloadLargeFileWithAccelerationEnabled() throws Exception {
329+
AWSS3StorageDownloadFileOptions awsS3Options =
330+
AWSS3StorageDownloadFileOptions.builder().setUseAccelerateEndpoint(true).build();
331+
synchronousStorage.downloadFile(LARGE_FILE_NAME, downloadFile, awsS3Options, EXTENDED_TIMEOUT_MS);
332+
}
320333
}

aws-storage-s3/src/androidTest/java/com/amplifyframework/storage/s3/AWSS3StorageUploadTest.java

+46-9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.amplifyframework.storage.operation.StorageUploadInputStreamOperation;
3434
import com.amplifyframework.storage.options.StorageUploadFileOptions;
3535
import com.amplifyframework.storage.options.StorageUploadInputStreamOptions;
36+
import com.amplifyframework.storage.s3.options.AWSS3StorageUploadFileOptions;
3637
import com.amplifyframework.storage.s3.test.R;
3738
import com.amplifyframework.storage.s3.util.WorkmanagerTestUtils;
3839
import com.amplifyframework.testutils.random.RandomTempFile;
@@ -74,6 +75,7 @@ public final class AWSS3StorageUploadTest {
7475

7576
/**
7677
* Initialize mobile client and configure the storage.
78+
*
7779
* @throws Exception if mobile client initialization fails
7880
*/
7981
@BeforeClass
@@ -95,8 +97,8 @@ public static void setUpOnce() throws Exception {
9597
public void setUp() {
9698
// Always interact with PUBLIC access for consistency
9799
options = StorageUploadFileOptions.builder()
98-
.accessLevel(TESTING_ACCESS_LEVEL)
99-
.build();
100+
.accessLevel(TESTING_ACCESS_LEVEL)
101+
.build();
100102

101103
// Create a set to remember all the subscriptions
102104
subscriptions = new HashSet<>();
@@ -132,7 +134,7 @@ public void testUploadSmallFile() throws Exception {
132134
*/
133135
@Test
134136
public void testUploadSmallFileStream() throws Exception {
135-
File uploadFile = new RandomTempFile(4 * 1024 * 1024);
137+
File uploadFile = new RandomTempFile(SMALL_FILE_SIZE);
136138
String fileName = uploadFile.getName();
137139
StorageUploadInputStreamOptions options = StorageUploadInputStreamOptions.builder()
138140
.accessLevel(TESTING_ACCESS_LEVEL)
@@ -149,6 +151,8 @@ public void testUploadSmallFileStream() throws Exception {
149151
public void testUploadLargeFile() throws Exception {
150152
File uploadFile = new RandomTempFile(LARGE_FILE_SIZE);
151153
String fileName = uploadFile.getName();
154+
AWSS3StorageUploadFileOptions options =
155+
AWSS3StorageUploadFileOptions.builder().setUseAccelerateEndpoint(true).build();
152156
synchronousStorage.uploadFile(fileName, uploadFile, options, EXTENDED_TIMEOUT_MS);
153157
}
154158

@@ -157,7 +161,7 @@ public void testUploadLargeFile() throws Exception {
157161
* transfer hasn't completed yet.
158162
*
159163
* @throws Exception if upload is not canceled successfully
160-
* before timeout
164+
* before timeout
161165
*/
162166
@SuppressWarnings("unchecked")
163167
@Test
@@ -206,7 +210,7 @@ public void testUploadFileIsCancelable() throws Exception {
206210
* while the transfer hasn't completed yet.
207211
*
208212
* @throws Exception if upload is not paused, resumed, and
209-
* completed successfully before timeout
213+
* completed successfully before timeout
210214
*/
211215
@SuppressWarnings("unchecked")
212216
@Test
@@ -258,7 +262,7 @@ public void testUploadFileIsResumable() throws Exception {
258262
* using getTransfer API.
259263
*
260264
* @throws Exception if upload is not paused, resumed, and
261-
* completed successfully before timeout
265+
* completed successfully before timeout
262266
*/
263267
@SuppressWarnings("unchecked")
264268
@Test
@@ -303,7 +307,8 @@ public void testUploadFileGetTransferOnPause() throws Exception {
303307
opContainer.get().pause();
304308
}
305309
},
306-
result -> { },
310+
result -> {
311+
},
307312
errorContainer::set
308313
);
309314
opContainer.set(op);
@@ -320,7 +325,7 @@ public void testUploadFileGetTransferOnPause() throws Exception {
320325
* using getTransfer API.
321326
*
322327
* @throws Exception if upload is not paused, resumed, and
323-
* completed successfully before timeout
328+
* completed successfully before timeout
324329
*/
325330
@SuppressWarnings("unchecked")
326331
@Test
@@ -367,7 +372,8 @@ public void testUploadInputStreamGetTransferOnPause() throws Exception {
367372
opContainer.get().pause();
368373
}
369374
},
370-
result -> { },
375+
result -> {
376+
},
371377
errorContainer::set
372378
);
373379
opContainer.set(op);
@@ -378,4 +384,35 @@ public void testUploadInputStreamGetTransferOnPause() throws Exception {
378384
assertTrue(completed.await(EXTENDED_TIMEOUT_MS, TimeUnit.MILLISECONDS));
379385
assertNull(errorContainer.get());
380386
}
387+
388+
/**
389+
* Tests that small file (single-part) uploads successfully.
390+
*
391+
* @throws Exception if upload fails
392+
*/
393+
@Test
394+
public void testUploadSmallFileWithAccelerationEnabled() throws Exception {
395+
File uploadFile = new RandomTempFile(SMALL_FILE_SIZE);
396+
String fileName = uploadFile.getName();
397+
AWSS3StorageUploadFileOptions awss3StorageUploadFileOptions =
398+
AWSS3StorageUploadFileOptions.builder().setUseAccelerateEndpoint(true).build();
399+
synchronousStorage.uploadFile(fileName, uploadFile,
400+
awss3StorageUploadFileOptions);
401+
}
402+
403+
/**
404+
* Tests that large file (single-part) uploads successfully.
405+
*
406+
* @throws Exception if upload fails
407+
*/
408+
@Test
409+
public void testUploadLargeFileWithAccelerationEnabled() throws Exception {
410+
File uploadFile = new RandomTempFile(LARGE_FILE_SIZE);
411+
String fileName = uploadFile.getName();
412+
AWSS3StorageUploadFileOptions awss3StorageUploadFileOptions =
413+
AWSS3StorageUploadFileOptions.builder().setUseAccelerateEndpoint(true).build();
414+
synchronousStorage.uploadFile(fileName, uploadFile,
415+
awss3StorageUploadFileOptions);
416+
}
417+
381418
}

aws-storage-s3/src/androidTest/java/com/amplifyframework/storage/s3/transfer/TransferDBTest.kt

+8-4
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ open class TransferDBTest {
120120
ongoingRestore = false,
121121
restoreExpirationTime = restoreExpirationTime
122122
),
123-
null
123+
null,
124+
useAccelerateEndpoint = false
124125
)
125126
val uri = transferDB.bulkInsertTransferRecords(contentValues)
126127
transferDB.getTransferRecordById(uri).run {
@@ -144,7 +145,8 @@ open class TransferDBTest {
144145
1L,
145146
0,
146147
null,
147-
null
148+
null,
149+
false
148150
)
149151
contentValues[1] = transferDB.generateContentValuesForMultiPartUpload(
150152
key,
@@ -157,7 +159,8 @@ open class TransferDBTest {
157159
1L,
158160
0,
159161
null,
160-
null
162+
null,
163+
false
161164
)
162165
contentValues[2] = transferDB.generateContentValuesForMultiPartUpload(
163166
key,
@@ -170,7 +173,8 @@ open class TransferDBTest {
170173
1L,
171174
1,
172175
null,
173-
null
176+
null,
177+
false
174178
)
175179
val bulkInsertUri = transferDB.bulkInsertTransferRecords(contentValues)
176180
transferDB.getTransferRecordById(bulkInsertUri)

0 commit comments

Comments
 (0)