Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
553f62a
Adding pre-signed URL operation core API and Get Object Request Pojo …
jencymaryjoseph Jul 2, 2025
451a70b
Add custom marshaller for pre-signed URL GET operations (#6231)
jencymaryjoseph Jul 4, 2025
563237b
Add DefaultPresignedUrlManager getObject implementation for S3 pre-si…
jencymaryjoseph Jul 10, 2025
ba96aaa
Add AsyncPresignedUrlManager for S3 GetObject operations with presign…
jencymaryjoseph Jul 16, 2025
9baca16
Removed presignedurl api and implementation for sync client (#6270)
jencymaryjoseph Jul 17, 2025
1994b7f
Add PresignedUrlManager support to code generated S3AsyncClient (#6269)
jencymaryjoseph Jul 17, 2025
2b23126
Modify Operation Name for Presigned URL, add Null Check for Resolve…
jencymaryjoseph Jul 18, 2025
a2177ef
Rename PresignedUrlManager to PresignedUrlExtension following API rev…
jencymaryjoseph Jul 23, 2025
365eaef
Add AsyncPresignedUrlManager integration tests (#6290)
jencymaryjoseph Jul 29, 2025
96a06bf
Add multipart presigned URL download support to MultipartS3AsyncClien…
jencymaryjoseph Aug 12, 2025
438322a
Add S3 Transfer Manager presigned URL download request models (#6356)
jencymaryjoseph Aug 21, 2025
6e31588
Add Range-based Multipart download Subscriber for Pre-signed URLs (#6…
jencymaryjoseph Aug 21, 2025
1500392
Fix multipart presigned URL download: parallel support and error prop…
jencymaryjoseph May 5, 2026
b508bf0
Fix CodeBuild failure: update codegen file for EndpointResolverInterc…
jencymaryjoseph May 5, 2026
10e45b1
Address PR Comments
jencymaryjoseph May 8, 2026
7e1c3a0
Fix check-then-act race condition in parallel subscriber (#6956)
jencymaryjoseph May 13, 2026
4b75eef
Add presigned URL download support to S3 Transfer Manager (#6951)
jencymaryjoseph May 18, 2026
a7fdaa4
Fix presigned url multipart download for empty objects (#6952)
jencymaryjoseph May 18, 2026
faa6210
Merge remote-tracking branch 'origin/master' into feature/master/pre-…
jencymaryjoseph May 18, 2026
12af83d
Add retry tests and onError cancel fix for presigned URL multipart do…
jencymaryjoseph May 20, 2026
63d4561
Fix presigned URL download progress tracking for range requests and a…
jencymaryjoseph May 22, 2026
9a2ae15
Merge remote-tracking branch 'origin/master' into feature/master/pre-…
jencymaryjoseph May 28, 2026
4f8e02b
Merge branch 'feature/master/pre-signed-url-getobject' of github.com:…
jencymaryjoseph May 28, 2026
e126cb2
Add PresignedFileDownload return type for presigned URL downloads (#7…
jencymaryjoseph Jun 1, 2026
d63b528
Merge remote-tracking branch 'origin/master' into feature/master/pre-…
jencymaryjoseph Jun 1, 2026
a72df5e
Merge branch 'feature/master/pre-signed-url-getobject' of github.com:…
jencymaryjoseph Jun 1, 2026
fdad8ba
Merge branch 'master' into feature/master/pre-signed-url-getobject
jencymaryjoseph Jun 9, 2026
ba66c7b
Fix first part response validation in parallel presigned URL multipar…
jencymaryjoseph Jun 9, 2026
bfaea56
Fix issues in parts calculation (#7026)
jencymaryjoseph Jun 15, 2026
014ea4b
Enable checksum validation for presigned URL downloads (#7035)
jencymaryjoseph Jun 17, 2026
2a01cd8
Merge remote-tracking branch 'origin/master' into feature/master/pre-…
jencymaryjoseph Jun 17, 2026
7ff04b1
Merge remote-tracking branch 'origin/master' into feature/master/pre-…
jencymaryjoseph Jun 20, 2026
237a2e4
Deprecate IS_DISCOVERED_ENDPOINT, add SKIP_ENDPOINT_RESOLUTION attrib…
jencymaryjoseph Jun 23, 2026
8cd9f8c
Fix multipart download response metadata for presigned URL and normal…
jencymaryjoseph Jun 30, 2026
4c621ca
Merge branch 'master' into feature/master/pre-signed-url-getobject
jencymaryjoseph Jul 1, 2026
f820638
Merge branch 'master' into feature/master/pre-signed-url-getobject
jencymaryjoseph Jul 7, 2026
2255143
Merge branch 'master' into feature/master/pre-signed-url-getobject
jencymaryjoseph Jul 7, 2026
b68da75
Merge remote-tracking branch 'origin/master' into feature/master/pre-…
jencymaryjoseph Jul 8, 2026
6ccab72
Add changelog entry for presigned URL download feature
jencymaryjoseph Jul 8, 2026
45c92bf
Remove contributor name
jencymaryjoseph Jul 8, 2026
5312d63
Merge remote-tracking branch 'origin/master' into feature/master/pre-…
jencymaryjoseph Jul 10, 2026
8aede75
Merge branch 'master' into feature/master/pre-signed-url-getobject
jencymaryjoseph Jul 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/next-release/feature-AmazonS3-a6f238d.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "feature",
"category": "Amazon S3",
"description": "Add presigned URL download support to S3AsyncClient and S3 Transfer Manager. Customers can now download S3 objects using pre-signed URLs through the SDK's async client pipeline without needing AWS credentials configured.",
"contributor": ""
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public static Metadata constructMetadata(ServiceModel serviceModel,
.withDocumentation(serviceModel.getDocumentation())
.withServiceAbbreviation(serviceMetadata.getServiceAbbreviation())
.withBatchmanagerPackageName(namingStrategy.getBatchManagerPackageName(serviceName))
.withPresignedUrlPackageName(namingStrategy.getPresignedUrlPackageName(serviceName))
.withServiceFullName(serviceMetadata.getServiceFullName())
.withServiceName(serviceName)
.withSyncClient(String.format(Constant.SYNC_CLIENT_CLASS_NAME_PATTERN, serviceName))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public final class Constant {

public static final String PACKAGE_NAME_BATCHMANAGER_PATTERN = "%s.batchmanager";

public static final String PACKAGE_NAME_PRESIGNEDURL_PATTERN = "%s.presignedurl";

public static final String PACKAGE_NAME_CUSTOM_AUTH_PATTERN = "%s.auth";

public static final String AUTH_POLICY_ENUM_CLASS_DIR = "software/amazon/awssdk/auth/policy/actions";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ public class CustomizationConfig {
*/
private boolean batchManagerSupported;

/**
* A boolean flag to indicate if Presigned URL Extension is supported.
*/
private boolean presignedUrlExtensionSupported;

/**
* A boolean flag to indicate if the fast unmarshaller code path is enabled.
*/
Expand Down Expand Up @@ -951,6 +956,14 @@ public void setBatchManagerSupported(boolean batchManagerSupported) {
this.batchManagerSupported = batchManagerSupported;
}

public boolean getPresignedUrlExtensionSupported() {
return presignedUrlExtensionSupported;
}

public void setPresignedUrlExtensionSupported(boolean presignedUrlExtensionSupported) {
this.presignedUrlExtensionSupported = presignedUrlExtensionSupported;
}

public boolean getEnableFastUnmarshaller() {
return enableFastUnmarshaller;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ public class Metadata {

private String batchManagerPackageName;

private String presignedUrlPackageName;

private String endpointRulesPackageName;

private String authSchemePackageName;
Expand Down Expand Up @@ -815,4 +817,20 @@ public String getFullBatchManagerPackageName() {
return joinPackageNames(rootPackageName, getBatchManagerPackageName());
}

public Metadata withPresignedUrlPackageName(String presignedUrlPackageName) {
setPresignedUrlPackageName(presignedUrlPackageName);
return this;
}

public String getPresignedUrlPackageName() {
return presignedUrlPackageName;
}

public void setPresignedUrlPackageName(String presignedUrlPackageName) {
this.presignedUrlPackageName = presignedUrlPackageName;
}

public String getFullPresignedUrlPackageName() {
return joinPackageNames(rootPackageName, getPresignedUrlPackageName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ public String getJmesPathPackageName(String serviceName) {
public String getBatchManagerPackageName(String serviceName) {
return getCustomizedPackageName(concatServiceNameIfShareModel(serviceName), Constant.PACKAGE_NAME_BATCHMANAGER_PATTERN);
}

@Override
public String getPresignedUrlPackageName(String serviceName) {
return getCustomizedPackageName(concatServiceNameIfShareModel(serviceName), Constant.PACKAGE_NAME_PRESIGNEDURL_PATTERN);
}

@Override
public String getSmokeTestPackageName(String serviceName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ public interface NamingStrategy {
* Retrieve the batchManager package name that should be used based on the service name.
*/
String getBatchManagerPackageName(String serviceName);

/**
* Retrieve the presignedUrl package name that should be used based on the service name.
*/
String getPresignedUrlPackageName(String serviceName);

/**
* Retrieve the smote test package name that should be used based on the service name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,8 @@ public ClassName getBatchManagerAsyncInterface() {
return ClassName.get(model.getMetadata().getFullBatchManagerPackageName(),
model.getMetadata().getServiceName() + "AsyncBatchManager");
}

public ClassName getPresignedUrlExtensionAsyncInterface() {
return ClassName.get(model.getMetadata().getFullPresignedUrlPackageName(), "AsyncPresignedUrlExtension");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,26 @@ protected void addBatchManagerMethod(Builder type) {

type.addMethod(batchManager);
}

@Override
protected void addPresignedUrlExtensionMethod(Builder type) {
ClassName returnType = poetExtensions.getPresignedUrlExtensionAsyncInterface();
String internalPresignedUrlPackage = model.getMetadata().getFullInternalPackageName() + ".presignedurl";
ClassName implClass = ClassName.get(internalPresignedUrlPackage, "DefaultAsyncPresignedUrlExtension");

MethodSpec presignedUrlExtension = MethodSpec.methodBuilder("presignedUrlExtension")
.addModifiers(PUBLIC)
.addAnnotation(Override.class)
.returns(returnType)
.addStatement("return new $T(clientHandler,"
+ " protocolFactory, "
+ "clientConfiguration,"
+ " protocolMetadata)",
implClass)
.build();

type.addMethod(presignedUrlExtension);
}

private MethodSpec resolveMetricPublishersMethod() {
String clientConfigName = "clientConfiguration";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ public TypeSpec poetSpec() {
if (model.getCustomizationConfig().getBatchManagerSupported()) {
addBatchManagerMethod(result);
}
if (model.getCustomizationConfig().getPresignedUrlExtensionSupported()) {
addPresignedUrlExtensionMethod(result);
}
result.addMethod(serviceClientConfigMethod());
addAdditionalMethods(result);
addCloseMethod(result);
Expand Down Expand Up @@ -174,6 +177,16 @@ protected void addBatchManagerMethod(TypeSpec.Builder type) {
+ "configuration set on this client.", returnType);
type.addMethod(batchManagerOperationBody(builder).build());
}

protected void addPresignedUrlExtensionMethod(TypeSpec.Builder type) {
ClassName returnType = poetExtensions.getPresignedUrlExtensionAsyncInterface();
MethodSpec.Builder builder = MethodSpec.methodBuilder("presignedUrlExtension")
.addModifiers(PUBLIC)
.returns(returnType)
.addJavadoc("Creates an instance of {@link $T} object with the "
+ "configuration set on this client.", returnType);
type.addMethod(presignedUrlExtensionOperationBody(builder).build());
}

@Override
public ClassName className() {
Expand Down Expand Up @@ -550,5 +563,10 @@ protected MethodSpec.Builder batchManagerOperationBody(MethodSpec.Builder builde
return builder.addModifiers(DEFAULT, PUBLIC)
.addStatement("throw new $T()", UnsupportedOperationException.class);
}

protected MethodSpec.Builder presignedUrlExtensionOperationBody(MethodSpec.Builder builder) {
return builder.addModifiers(DEFAULT, PUBLIC)
.addStatement("throw new $T()", UnsupportedOperationException.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,9 @@ protected MethodSpec.Builder waiterOperationBody(MethodSpec.Builder builder) {
protected MethodSpec.Builder batchManagerOperationBody(MethodSpec.Builder builder) {
return builder.addAnnotation(Override.class).addStatement("return delegate.batchManager()");
}

@Override
protected MethodSpec.Builder presignedUrlExtensionOperationBody(MethodSpec.Builder builder) {
return builder.addAnnotation(Override.class).addStatement("return delegate.presignedUrlExtension()");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,18 @@ public static IntermediateModel batchManagerModels() {

return new IntermediateModelBuilder(models).build();
}

public static IntermediateModel presignedUrlExtensionModels() {
File serviceModel = new File(ClientTestModels.class.getResource("client/c2j/presignedurl/service-2.json").getFile());
File customizationModel = new File(ClientTestModels.class.getResource("client/c2j/presignedurl/customization.config").getFile());

C2jModels models = C2jModels.builder()
.serviceModel(getServiceModel(serviceModel))
.customizationConfig(getCustomizationConfig(customizationModel))
.build();

return new IntermediateModelBuilder(models).build();
}

private static ServiceModel getServiceModel(File file) {
return ModelLoaderUtils.loadModel(ServiceModel.class, file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import static software.amazon.awssdk.codegen.poet.ClientTestModels.customPackageModels;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.endpointDiscoveryModels;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.opsWithSigv4a;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.presignedUrlExtensionModels;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.serviceWithCustomContextParamsModels;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.queryServiceModels;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.restJsonServiceModels;
Expand Down Expand Up @@ -102,6 +103,12 @@ public void asyncClientBatchManager() {
ClassSpec aSyncClientBatchManager = createAsyncClientClass(batchManagerModels());
assertThat(aSyncClientBatchManager, generatesTo("test-batchmanager-async.java"));
}

@Test
public void asyncClientPresignedUrlExtension() {
ClassSpec asyncClientPresignedUrlExtension = createAsyncClientClass(presignedUrlExtensionModels());
assertThat(asyncClientPresignedUrlExtension, generatesTo("test-presignedurl-async.java"));
}

@Test
public void asyncClientWithStreamingUnsignedPayload() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.batchManagerModels;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.presignedUrlExtensionModels;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.restJsonServiceModels;
import static software.amazon.awssdk.codegen.poet.PoetMatchers.generatesTo;

Expand All @@ -35,4 +36,10 @@ public void asyncClientInterfaceWithBatchManager() {
ClassSpec asyncClientInterface = new AsyncClientInterface(batchManagerModels());
assertThat(asyncClientInterface, generatesTo("test-json-async-client-interface-batchmanager.java"));
}

@Test
public void asyncClientInterfaceWithPresignedUrlExtension() {
ClassSpec asyncClientInterface = new AsyncClientInterface(presignedUrlExtensionModels());
assertThat(asyncClientInterface, generatesTo("test-json-async-client-interface-presignedurl.java"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package software.amazon.awssdk.codegen.poet.client;

import static org.hamcrest.MatcherAssert.assertThat;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.presignedUrlExtensionModels;
import static software.amazon.awssdk.codegen.poet.ClientTestModels.restJsonServiceModels;
import static software.amazon.awssdk.codegen.poet.PoetMatchers.generatesTo;

Expand All @@ -28,4 +29,11 @@ public void delegatingAsyncClientClass() {
new DelegatingAsyncClientClass(restJsonServiceModels());
assertThat(asyncClientDecoratorAbstractClass, generatesTo("test-abstract-async-client-class.java"));
}

@Test
public void delegatingAsyncClientClassWithPresignedUrlExtension() {
DelegatingAsyncClientClass asyncClientDecoratorAbstractClass =
new DelegatingAsyncClientClass(presignedUrlExtensionModels());
assertThat(asyncClientDecoratorAbstractClass, generatesTo("test-abstract-async-client-class-presignedurl.java"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presignedUrlExtensionSupported": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"version": "2.0",
"metadata": {
"apiVersion": "2010-05-08",
"endpointPrefix": "json-service-endpoint",
"globalEndpoint": "json-service.amazonaws.com",
"protocol": "json",
"serviceAbbreviation": "Json Service",
"serviceFullName": "Some Service That Uses AWS Json Protocol",
"serviceId": "Json Service",
"signingName": "json-service",
"signatureVersion": "v4",
"uid": "json-service-2010-05-08",
"xmlNamespace": "https://json-service.amazonaws.com/doc/2010-05-08/"
},
"operations": {
"APostOperation": {
"name": "APostOperation",
"http": {
"method": "POST",
"requestUri": "/"
},
"input": {
"shape": "APostOperationRequest"
},
"errors": [
{
"shape": "InvalidInputException"
}
],
"documentation": "<p>Performs a post operation to the query service and has no output</p>"
}
},
"shapes": {
"APostOperationRequest": {
"type": "structure",
"required": [
"StringMember"
],
"members": {
"StringMember": {
"shape": "String",
"documentation": "<p>String member</p>"
}
}
},
"InvalidInputException": {
"type": "structure",
"members": {
"message": {
"shape": "String"
}
},
"documentation": "<p>The request was rejected because an invalid or out-of-range value was supplied for an input parameter.</p>",
"exception": true
},
"String": {
"type": "string"
}
},
"documentation": "A service that is implemented using the json protocol"
}
Loading
Loading