1 /*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15
16 package software.amazon.awssdk.services.s3;
17
18 import software.amazon.awssdk.annotations.Immutable;
19 import software.amazon.awssdk.annotations.NotThreadSafe;
20 import software.amazon.awssdk.annotations.SdkPublicApi;
21 import software.amazon.awssdk.annotations.ThreadSafe;
22 import software.amazon.awssdk.core.ServiceConfiguration;
23 import software.amazon.awssdk.profiles.ProfileFile;
24 import software.amazon.awssdk.profiles.ProfileFileSystemSetting;
25 import software.amazon.awssdk.services.s3.internal.FieldWithDefault;
26 import software.amazon.awssdk.services.s3.internal.usearnregion.UseArnRegionProviderChain;
27 import software.amazon.awssdk.services.s3.model.PutBucketAccelerateConfigurationRequest;
28 import software.amazon.awssdk.utils.builder.CopyableBuilder;
29 import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
30
31 @SdkPublicApi
32 @Immutable
33 @ThreadSafe
34 public final class S3Configuration implements ServiceConfiguration, ToCopyableBuilder<S3Configuration.Builder, S3Configuration> {
35 /**
36 * The default setting for use of path style addressing.
37 */
38 private static final boolean DEFAULT_PATH_STYLE_ACCESS_ENABLED = false;
39
40 /**
41 * S3 accelerate is by default not enabled
42 */
43 private static final boolean DEFAULT_ACCELERATE_MODE_ENABLED = false;
44
45 /**
46 * S3 dualstack endpoint is by default not enabled
47 */
48 private static final boolean DEFAULT_DUALSTACK_ENABLED = false;
49
50 /**
51 * S3 payload checksum validation is by default enabled;
52 */
53 private static final boolean DEFAULT_CHECKSUM_VALIDATION_ENABLED = true;
54
55 /**
56 * S3 The default value for enabling chunked encoding for {@link
57 * software.amazon.awssdk.services.s3.model.PutObjectRequest} and {@link
58 * software.amazon.awssdk.services.s3.model.UploadPartRequest}.
59 */
60 private static final boolean DEFAULT_CHUNKED_ENCODING_ENABLED = true;
61
62 private final FieldWithDefault<Boolean> pathStyleAccessEnabled;
63 private final FieldWithDefault<Boolean> accelerateModeEnabled;
64 private final FieldWithDefault<Boolean> dualstackEnabled;
65 private final FieldWithDefault<Boolean> checksumValidationEnabled;
66 private final FieldWithDefault<Boolean> chunkedEncodingEnabled;
67 private final FieldWithDefault<Boolean> useArnRegionEnabled;
68 private final FieldWithDefault<ProfileFile> profileFile;
69 private final FieldWithDefault<String> profileName;
70
71 private S3Configuration(DefaultS3ServiceConfigurationBuilder builder) {
72 this.dualstackEnabled = FieldWithDefault.create(builder.dualstackEnabled, DEFAULT_DUALSTACK_ENABLED);
73 this.accelerateModeEnabled = FieldWithDefault.create(builder.accelerateModeEnabled, DEFAULT_ACCELERATE_MODE_ENABLED);
74 this.pathStyleAccessEnabled = FieldWithDefault.create(builder.pathStyleAccessEnabled, DEFAULT_PATH_STYLE_ACCESS_ENABLED);
75 this.checksumValidationEnabled = FieldWithDefault.create(builder.checksumValidationEnabled,
76 DEFAULT_CHECKSUM_VALIDATION_ENABLED);
77 this.chunkedEncodingEnabled = FieldWithDefault.create(builder.chunkedEncodingEnabled, DEFAULT_CHUNKED_ENCODING_ENABLED);
78 this.profileFile = FieldWithDefault.createLazy(builder.profileFile, ProfileFile::defaultProfileFile);
79 this.profileName = FieldWithDefault.create(builder.profileName,
80 ProfileFileSystemSetting.AWS_PROFILE.getStringValueOrThrow());
81 this.useArnRegionEnabled = FieldWithDefault.createLazy(builder.useArnRegionEnabled, this::resolveUserArnRegionEnabled);
82
83 if (accelerateModeEnabled() && pathStyleAccessEnabled()) {
84 throw new IllegalArgumentException("Accelerate mode cannot be used with path style addressing");
85 }
86 }
87
88 private boolean resolveUserArnRegionEnabled() {
89 return UseArnRegionProviderChain.create(this.profileFile.value(), this.profileName.value())
90 .resolveUseArnRegion()
91 .orElse(false);
92 }
93
94 /**
95 * Create a {@link Builder}, used to create a {@link S3Configuration}.
96 */
97 public static Builder builder() {
98 return new DefaultS3ServiceConfigurationBuilder();
99 }
100
101 /**
102 * <p>
103 * Returns whether the client uses path-style access for all requests.
104 * </p>
105 * <p>
106 * Amazon S3 supports virtual-hosted-style and path-style access in all
107 * Regions. The path-style syntax, however, requires that you use the
108 * region-specific endpoint when attempting to access a bucket.
109 * </p>
110 * <p>
111 * The default behaviour is to detect which access style to use based on
112 * the configured endpoint (an IP will result in path-style access) and
113 * the bucket being accessed (some buckets are not valid DNS names).
114 * Setting this flag will result in path-style access being used for all
115 * requests.
116 * </p>
117 *
118 * @return True is the client should always use path-style access
119 */
120 public boolean pathStyleAccessEnabled() {
121 return pathStyleAccessEnabled.value();
122 }
123
124 /**
125 * <p>
126 * Returns whether the client has enabled accelerate mode for getting and putting objects.
127 * </p>
128 * <p>
129 * The default behavior is to disable accelerate mode for any operations (GET, PUT, DELETE). You need to call
130 * {@link DefaultS3Client#putBucketAccelerateConfiguration(PutBucketAccelerateConfigurationRequest)}
131 * first to use this feature.
132 * </p>
133 *
134 * @return True if accelerate mode is enabled.
135 */
136 public boolean accelerateModeEnabled() {
137 return accelerateModeEnabled.value();
138 }
139
140 /**
141 * <p>
142 * Returns whether the client is configured to use dualstack mode for
143 * accessing S3. If you want to use IPv6 when accessing S3, dualstack
144 * must be enabled.
145 * </p>
146 *
147 * <p>
148 * Dualstack endpoints are disabled by default.
149 * </p>
150 *
151 * @return True if the client will use the dualstack endpoints
152 */
153 public boolean dualstackEnabled() {
154 return dualstackEnabled.value();
155 }
156
157 public boolean checksumValidationEnabled() {
158 return checksumValidationEnabled.value();
159 }
160
161 /**
162 * Returns whether the client should use chunked encoding when signing the
163 * payload body.
164 * <p>
165 * This option only currently applies to {@link
166 * software.amazon.awssdk.services.s3.model.PutObjectRequest} and {@link
167 * software.amazon.awssdk.services.s3.model.UploadPartRequest}.
168 *
169 * @return True if chunked encoding should be used.
170 */
171 public boolean chunkedEncodingEnabled() {
172 return chunkedEncodingEnabled.value();
173 }
174
175 /**
176 * Returns whether the client is allowed to make cross-region calls when an S3 Access Point ARN has a different
177 * region to the one configured on the client.
178 * <p>
179 * @return True if a different region in the ARN can be used.
180 */
181 public boolean useArnRegionEnabled() {
182 return useArnRegionEnabled.value();
183 }
184
185 @Override
186 public Builder toBuilder() {
187 return builder()
188 .dualstackEnabled(dualstackEnabled.valueOrNullIfDefault())
189 .accelerateModeEnabled(accelerateModeEnabled.valueOrNullIfDefault())
190 .pathStyleAccessEnabled(pathStyleAccessEnabled.valueOrNullIfDefault())
191 .checksumValidationEnabled(checksumValidationEnabled.valueOrNullIfDefault())
192 .chunkedEncodingEnabled(chunkedEncodingEnabled.valueOrNullIfDefault())
193 .useArnRegionEnabled(useArnRegionEnabled.valueOrNullIfDefault())
194 .profileFile(profileFile.valueOrNullIfDefault())
195 .profileName(profileName.valueOrNullIfDefault());
196 }
197
198 @NotThreadSafe
199 public interface Builder extends CopyableBuilder<Builder, S3Configuration> {
200 Boolean dualstackEnabled();
201
202 /**
203 * Option to enable using the dualstack endpoints when accessing S3. Dualstack
204 * should be enabled if you want to use IPv6.
205 *
206 * <p>
207 * Dualstack endpoints are disabled by default.
208 * </p>
209 *
210 * @see S3Configuration#dualstackEnabled().
211 */
212 Builder dualstackEnabled(Boolean dualstackEnabled);
213
214 Boolean accelerateModeEnabled();
215
216 /**
217 * Option to enable using the accelerate enedpoint when accessing S3. Accelerate
218 * endpoints allow faster transfer of objects by using Amazon CloudFront's
219 * globally distributed edge locations.
220 *
221 * <p>
222 * Accelerate mode is disabled by default.
223 * </p>
224 *
225 * @see S3Configuration#accelerateModeEnabled().
226 */
227 Builder accelerateModeEnabled(Boolean accelerateModeEnabled);
228
229 Boolean pathStyleAccessEnabled();
230
231 /**
232 * Option to enable using path style access for accessing S3 objects
233 * instead of DNS style access. DNS style access is preferred as it
234 * will result in better load balancing when accessing S3.
235 *
236 * <p>
237 * Path style access is disabled by default. Path style may still be used for legacy
238 * buckets that are not DNS compatible.
239 * </p>
240 *
241 * @see S3Configuration#pathStyleAccessEnabled().
242 */
243 Builder pathStyleAccessEnabled(Boolean pathStyleAccessEnabled);
244
245 Boolean checksumValidationEnabled();
246
247 /**
248 * Option to disable doing a validation of the checksum of an object stored in S3.
249 *
250 * <p>
251 * Checksum validation is enabled by default.
252 * </p>
253 *
254 * @see S3Configuration#checksumValidationEnabled().
255 */
256 Builder checksumValidationEnabled(Boolean checksumValidationEnabled);
257
258 Boolean chunkedEncodingEnabled();
259
260 /**
261 * Option to enable using chunked encoding when signing the request
262 * payload for {@link
263 * software.amazon.awssdk.services.s3.model.PutObjectRequest} and {@link
264 * software.amazon.awssdk.services.s3.model.UploadPartRequest}.
265 *
266 * @see S3Configuration#chunkedEncodingEnabled()
267 */
268 Builder chunkedEncodingEnabled(Boolean chunkedEncodingEnabled);
269
270 Boolean useArnRegionEnabled();
271
272 /**
273 * If an S3 resource ARN is passed in as the target of an S3 operation that has a different region to the one
274 * the client was configured with, this flag must be set to 'true' to permit the client to make a
275 * cross-region call to the region specified in the ARN otherwise an exception will be thrown.
276 *
277 * @see S3Configuration#useArnRegionEnabled()
278 */
279 Builder useArnRegionEnabled(Boolean useArnRegionEnabled);
280
281 ProfileFile profileFile();
282
283 /**
284 * The profile file that should be consulted to determine the default value of {@link #useArnRegionEnabled(Boolean)}.
285 * This is not used, if the {@link #useArnRegionEnabled(Boolean)} is configured.
286 *
287 * <p>
288 * By default, the {@link ProfileFile#defaultProfileFile()} is used.
289 * </p>
290 */
291 Builder profileFile(ProfileFile profileFile);
292
293 String profileName();
294
295 /**
296 * The profile name that should be consulted to determine the default value of {@link #useArnRegionEnabled(Boolean)}.
297 * This is not used, if the {@link #useArnRegionEnabled(Boolean)} is configured.
298 *
299 * <p>
300 * By default, the {@link ProfileFileSystemSetting#AWS_PROFILE} is used.
301 * </p>
302 */
303 Builder profileName(String profileName);
304 }
305
306 static final class DefaultS3ServiceConfigurationBuilder implements Builder {
307 private Boolean dualstackEnabled;
308 private Boolean accelerateModeEnabled;
309 private Boolean pathStyleAccessEnabled;
310 private Boolean checksumValidationEnabled;
311 private Boolean chunkedEncodingEnabled;
312 private Boolean useArnRegionEnabled;
313 private ProfileFile profileFile;
314 private String profileName;
315
316 @Override
317 public Boolean dualstackEnabled() {
318 return dualstackEnabled;
319 }
320
321 public Builder dualstackEnabled(Boolean dualstackEnabled) {
322 this.dualstackEnabled = dualstackEnabled;
323 return this;
324 }
325
326 @Override
327 public Boolean accelerateModeEnabled() {
328 return accelerateModeEnabled;
329 }
330
331 public void setDualstackEnabled(Boolean dualstackEnabled) {
332 dualstackEnabled(dualstackEnabled);
333 }
334
335 public Builder accelerateModeEnabled(Boolean accelerateModeEnabled) {
336 this.accelerateModeEnabled = accelerateModeEnabled;
337 return this;
338 }
339
340 @Override
341 public Boolean pathStyleAccessEnabled() {
342 return pathStyleAccessEnabled;
343 }
344
345 public void setAccelerateModeEnabled(Boolean accelerateModeEnabled) {
346 accelerateModeEnabled(accelerateModeEnabled);
347 }
348
349 public Builder pathStyleAccessEnabled(Boolean pathStyleAccessEnabled) {
350 this.pathStyleAccessEnabled = pathStyleAccessEnabled;
351 return this;
352 }
353
354 @Override
355 public Boolean checksumValidationEnabled() {
356 return checksumValidationEnabled;
357 }
358
359 public void setPathStyleAccessEnabled(Boolean pathStyleAccessEnabled) {
360 pathStyleAccessEnabled(pathStyleAccessEnabled);
361 }
362
363 public Builder checksumValidationEnabled(Boolean checksumValidationEnabled) {
364 this.checksumValidationEnabled = checksumValidationEnabled;
365 return this;
366 }
367
368 @Override
369 public Boolean chunkedEncodingEnabled() {
370 return chunkedEncodingEnabled;
371 }
372
373 public void setChecksumValidationEnabled(Boolean checksumValidationEnabled) {
374 checksumValidationEnabled(checksumValidationEnabled);
375 }
376
377 public Builder chunkedEncodingEnabled(Boolean chunkedEncodingEnabled) {
378 this.chunkedEncodingEnabled = chunkedEncodingEnabled;
379 return this;
380 }
381
382 @Override
383 public Boolean useArnRegionEnabled() {
384 return useArnRegionEnabled;
385 }
386
387 public void setChunkedEncodingEnabled(Boolean chunkedEncodingEnabled) {
388 chunkedEncodingEnabled(chunkedEncodingEnabled);
389 }
390
391 public Builder useArnRegionEnabled(Boolean useArnRegionEnabled) {
392 this.useArnRegionEnabled = useArnRegionEnabled;
393 return this;
394 }
395
396 @Override
397 public ProfileFile profileFile() {
398 return profileFile;
399 }
400
401 @Override
402 public Builder profileFile(ProfileFile profileFile) {
403 this.profileFile = profileFile;
404 return this;
405 }
406
407 @Override
408 public String profileName() {
409 return profileName;
410 }
411
412 @Override
413 public Builder profileName(String profileName) {
414 this.profileName = profileName;
415 return this;
416 }
417
418 public void setUseArnRegionEnabled(Boolean useArnRegionEnabled) {
419 useArnRegionEnabled(useArnRegionEnabled);
420 }
421
422 public S3Configuration build() {
423 return new S3Configuration(this);
424 }
425 }
426 }
427