Skip to content

Commit b2d5bcb

Browse files
authored
Fix S3/Control dualstack config resolution (#5579)
Fix an issue in S3 and S3 Control client's dualstack config resolution where the default value in S3Configuration and S3ControlConfiguration prevents the client from correctly falling back to the environment variable/system property value when the dualstack configuration is not set on the client or on configuration object.
1 parent f28042d commit b2d5bcb

File tree

10 files changed

+1734
-84
lines changed

10 files changed

+1734
-84
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/BaseClientBuilderClass.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,11 @@ private MethodSpec finalizeServiceConfigurationMethod() {
406406
builder.addStatement("builder.option($1T.EXECUTION_INTERCEPTORS, interceptors)", SdkClientOption.class);
407407

408408
if (model.getCustomizationConfig().getServiceConfig().hasDualstackProperty()) {
409-
builder.addStatement("builder.option($T.DUALSTACK_ENDPOINT_ENABLED, finalServiceConfig.dualstackEnabled())",
409+
// NOTE: usage of serviceConfigBuilder and not finalServiceConfig is intentional. We need the nullable boolean here
410+
// to ensure fallback resolution of the dualstack configuration if dualstack was not explicitly configured on
411+
// serviceConfigBuilder; the service configuration classes (e.g. S3Configuration) return primitive booleans that
412+
// have a default when not present.
413+
builder.addStatement("builder.option($T.DUALSTACK_ENDPOINT_ENABLED, serviceConfigBuilder.dualstackEnabled())",
410414
AwsClientOption.class);
411415
}
412416

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/sra/test-client-builder-class.java

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ protected final String serviceName() {
6464
@Override
6565
protected final SdkClientConfiguration mergeServiceDefaults(SdkClientConfiguration config) {
6666
return config.merge(c -> c
67-
.option(SdkClientOption.ENDPOINT_PROVIDER, defaultEndpointProvider())
68-
.option(SdkClientOption.AUTH_SCHEME_PROVIDER, defaultAuthSchemeProvider())
69-
.option(SdkClientOption.AUTH_SCHEMES, authSchemes())
70-
.option(SdkClientOption.CRC32_FROM_COMPRESSED_DATA_ENABLED, false)
71-
.option(SdkClientOption.SERVICE_CONFIGURATION, ServiceConfiguration.builder().build())
72-
.lazyOption(AwsClientOption.TOKEN_PROVIDER,
67+
.option(SdkClientOption.ENDPOINT_PROVIDER, defaultEndpointProvider())
68+
.option(SdkClientOption.AUTH_SCHEME_PROVIDER, defaultAuthSchemeProvider())
69+
.option(SdkClientOption.AUTH_SCHEMES, authSchemes())
70+
.option(SdkClientOption.CRC32_FROM_COMPRESSED_DATA_ENABLED, false)
71+
.option(SdkClientOption.SERVICE_CONFIGURATION, ServiceConfiguration.builder().build())
72+
.lazyOption(AwsClientOption.TOKEN_PROVIDER,
7373
p -> TokenUtils.toSdkTokenProvider(p.get(AwsClientOption.TOKEN_IDENTITY_PROVIDER)))
74-
.option(AwsClientOption.TOKEN_IDENTITY_PROVIDER, defaultTokenProvider()));
74+
.option(AwsClientOption.TOKEN_IDENTITY_PROVIDER, defaultTokenProvider()));
7575
}
7676

7777
@Override
@@ -82,64 +82,64 @@ protected final SdkClientConfiguration finalizeServiceConfiguration(SdkClientCon
8282
endpointInterceptors.add(new JsonRequestSetEndpointInterceptor());
8383
ClasspathInterceptorChainFactory interceptorFactory = new ClasspathInterceptorChainFactory();
8484
List<ExecutionInterceptor> interceptors = interceptorFactory
85-
.getInterceptors("software/amazon/awssdk/services/json/execution.interceptors");
85+
.getInterceptors("software/amazon/awssdk/services/json/execution.interceptors");
8686
List<ExecutionInterceptor> additionalInterceptors = new ArrayList<>();
8787
interceptors = CollectionUtils.mergeLists(endpointInterceptors, interceptors);
8888
interceptors = CollectionUtils.mergeLists(interceptors, additionalInterceptors);
8989
interceptors = CollectionUtils.mergeLists(interceptors, config.option(SdkClientOption.EXECUTION_INTERCEPTORS));
9090
ServiceConfiguration.Builder serviceConfigBuilder = ((ServiceConfiguration) config
91-
.option(SdkClientOption.SERVICE_CONFIGURATION)).toBuilder();
91+
.option(SdkClientOption.SERVICE_CONFIGURATION)).toBuilder();
9292
serviceConfigBuilder.profileFile(serviceConfigBuilder.profileFileSupplier() != null ? serviceConfigBuilder
93-
.profileFileSupplier() : config.option(SdkClientOption.PROFILE_FILE_SUPPLIER));
93+
.profileFileSupplier() : config.option(SdkClientOption.PROFILE_FILE_SUPPLIER));
9494
serviceConfigBuilder.profileName(serviceConfigBuilder.profileName() != null ? serviceConfigBuilder.profileName() : config
95-
.option(SdkClientOption.PROFILE_NAME));
95+
.option(SdkClientOption.PROFILE_NAME));
9696
if (serviceConfigBuilder.dualstackEnabled() != null) {
9797
Validate.validState(
98-
config.option(AwsClientOption.DUALSTACK_ENDPOINT_ENABLED) == null,
99-
"Dualstack has been configured on both ServiceConfiguration and the client/global level. Please limit dualstack configuration to one location.");
98+
config.option(AwsClientOption.DUALSTACK_ENDPOINT_ENABLED) == null,
99+
"Dualstack has been configured on both ServiceConfiguration and the client/global level. Please limit dualstack configuration to one location.");
100100
} else {
101101
serviceConfigBuilder.dualstackEnabled(config.option(AwsClientOption.DUALSTACK_ENDPOINT_ENABLED));
102102
}
103103
if (serviceConfigBuilder.fipsModeEnabled() != null) {
104104
Validate.validState(
105-
config.option(AwsClientOption.FIPS_ENDPOINT_ENABLED) == null,
106-
"Fips has been configured on both ServiceConfiguration and the client/global level. Please limit fips configuration to one location.");
105+
config.option(AwsClientOption.FIPS_ENDPOINT_ENABLED) == null,
106+
"Fips has been configured on both ServiceConfiguration and the client/global level. Please limit fips configuration to one location.");
107107
} else {
108108
serviceConfigBuilder.fipsModeEnabled(config.option(AwsClientOption.FIPS_ENDPOINT_ENABLED));
109109
}
110110
if (serviceConfigBuilder.useArnRegionEnabled() != null) {
111111
Validate.validState(
112-
clientContextParams.get(JsonClientContextParams.USE_ARN_REGION) == null,
113-
"UseArnRegion has been configured on both ServiceConfiguration and the client/global level. Please limit UseArnRegion configuration to one location.");
112+
clientContextParams.get(JsonClientContextParams.USE_ARN_REGION) == null,
113+
"UseArnRegion has been configured on both ServiceConfiguration and the client/global level. Please limit UseArnRegion configuration to one location.");
114114
} else {
115115
serviceConfigBuilder.useArnRegionEnabled(clientContextParams.get(JsonClientContextParams.USE_ARN_REGION));
116116
}
117117
if (serviceConfigBuilder.multiRegionEnabled() != null) {
118118
Validate.validState(
119-
clientContextParams.get(JsonClientContextParams.DISABLE_MULTI_REGION_ACCESS_POINTS) == null,
120-
"DisableMultiRegionAccessPoints has been configured on both ServiceConfiguration and the client/global level. Please limit DisableMultiRegionAccessPoints configuration to one location.");
119+
clientContextParams.get(JsonClientContextParams.DISABLE_MULTI_REGION_ACCESS_POINTS) == null,
120+
"DisableMultiRegionAccessPoints has been configured on both ServiceConfiguration and the client/global level. Please limit DisableMultiRegionAccessPoints configuration to one location.");
121121
} else if (clientContextParams.get(JsonClientContextParams.DISABLE_MULTI_REGION_ACCESS_POINTS) != null) {
122122
serviceConfigBuilder.multiRegionEnabled(!clientContextParams
123-
.get(JsonClientContextParams.DISABLE_MULTI_REGION_ACCESS_POINTS));
123+
.get(JsonClientContextParams.DISABLE_MULTI_REGION_ACCESS_POINTS));
124124
}
125125
if (serviceConfigBuilder.pathStyleAccessEnabled() != null) {
126126
Validate.validState(
127-
clientContextParams.get(JsonClientContextParams.FORCE_PATH_STYLE) == null,
128-
"ForcePathStyle has been configured on both ServiceConfiguration and the client/global level. Please limit ForcePathStyle configuration to one location.");
127+
clientContextParams.get(JsonClientContextParams.FORCE_PATH_STYLE) == null,
128+
"ForcePathStyle has been configured on both ServiceConfiguration and the client/global level. Please limit ForcePathStyle configuration to one location.");
129129
} else {
130130
serviceConfigBuilder.pathStyleAccessEnabled(clientContextParams.get(JsonClientContextParams.FORCE_PATH_STYLE));
131131
}
132132
if (serviceConfigBuilder.accelerateModeEnabled() != null) {
133133
Validate.validState(
134-
clientContextParams.get(JsonClientContextParams.ACCELERATE) == null,
135-
"Accelerate has been configured on both ServiceConfiguration and the client/global level. Please limit Accelerate configuration to one location.");
134+
clientContextParams.get(JsonClientContextParams.ACCELERATE) == null,
135+
"Accelerate has been configured on both ServiceConfiguration and the client/global level. Please limit Accelerate configuration to one location.");
136136
} else {
137137
serviceConfigBuilder.accelerateModeEnabled(clientContextParams.get(JsonClientContextParams.ACCELERATE));
138138
}
139139
ServiceConfiguration finalServiceConfig = serviceConfigBuilder.build();
140140
clientContextParams.put(JsonClientContextParams.USE_ARN_REGION, finalServiceConfig.useArnRegionEnabled());
141141
clientContextParams.put(JsonClientContextParams.DISABLE_MULTI_REGION_ACCESS_POINTS,
142-
!finalServiceConfig.multiRegionEnabled());
142+
!finalServiceConfig.multiRegionEnabled());
143143
clientContextParams.put(JsonClientContextParams.FORCE_PATH_STYLE, finalServiceConfig.pathStyleAccessEnabled());
144144
clientContextParams.put(JsonClientContextParams.ACCELERATE, finalServiceConfig.accelerateModeEnabled());
145145
SdkClientConfiguration.Builder builder = config.toBuilder();
@@ -156,7 +156,7 @@ protected final SdkClientConfiguration finalizeServiceConfiguration(SdkClientCon
156156
return result.build();
157157
});
158158
builder.option(SdkClientOption.EXECUTION_INTERCEPTORS, interceptors);
159-
builder.option(AwsClientOption.DUALSTACK_ENDPOINT_ENABLED, finalServiceConfig.dualstackEnabled());
159+
builder.option(AwsClientOption.DUALSTACK_ENDPOINT_ENABLED, serviceConfigBuilder.dualstackEnabled());
160160
builder.option(AwsClientOption.FIPS_ENDPOINT_ENABLED, finalServiceConfig.fipsModeEnabled());
161161
builder.option(SdkClientOption.RETRY_STRATEGY, MyServiceRetryStrategy.resolveRetryStrategy(config));
162162
if (builder.option(SdkClientOption.RETRY_STRATEGY) == null) {
@@ -270,6 +270,6 @@ private List<SdkPlugin> internalPlugins(SdkClientConfiguration config) {
270270

271271
protected static void validateClientOptions(SdkClientConfiguration c) {
272272
Validate.notNull(c.option(AwsClientOption.TOKEN_IDENTITY_PROVIDER),
273-
"The 'tokenProvider' must be configured in the client builder.");
273+
"The 'tokenProvider' must be configured in the client builder.");
274274
}
275275
}

0 commit comments

Comments
 (0)