• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.multipart;
17 
18 import java.util.function.Consumer;
19 import software.amazon.awssdk.annotations.SdkPublicApi;
20 import software.amazon.awssdk.core.async.AsyncRequestBody;
21 import software.amazon.awssdk.core.async.AsyncResponseTransformer;
22 import software.amazon.awssdk.services.s3.S3AsyncClient;
23 import software.amazon.awssdk.services.s3.S3AsyncClientBuilder;
24 import software.amazon.awssdk.services.s3.model.CopyObjectRequest;
25 import software.amazon.awssdk.services.s3.model.GetObjectRequest;
26 import software.amazon.awssdk.utils.builder.CopyableBuilder;
27 import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
28 
29 /**
30  * Class that hold configuration properties related to multipart operation for a {@link S3AsyncClient}. Passing this class to the
31  * {@link S3AsyncClientBuilder#multipartConfiguration(MultipartConfiguration)} will enable automatic conversion of
32  * {@link S3AsyncClient#putObject(Consumer, AsyncRequestBody)}, {@link S3AsyncClient#copyObject(CopyObjectRequest)} to their
33  * respective multipart operation.
34  * <p>
35  * <em>Note</em>: The multipart operation for {@link S3AsyncClient#getObject(GetObjectRequest, AsyncResponseTransformer)} is
36  * temporarily disabled and will result in throwing a {@link UnsupportedOperationException} if called when configured for
37  * multipart operation.
38  */
39 @SdkPublicApi
40 public final class MultipartConfiguration implements ToCopyableBuilder<MultipartConfiguration.Builder, MultipartConfiguration> {
41 
42     private final Long thresholdInBytes;
43     private final Long minimumPartSizeInBytes;
44     private final Long apiCallBufferSizeInBytes;
45 
MultipartConfiguration(DefaultMultipartConfigBuilder builder)46     private MultipartConfiguration(DefaultMultipartConfigBuilder builder) {
47         this.thresholdInBytes = builder.thresholdInBytes;
48         this.minimumPartSizeInBytes = builder.minimumPartSizeInBytes;
49         this.apiCallBufferSizeInBytes = builder.apiCallBufferSizeInBytes;
50     }
51 
builder()52     public static Builder builder() {
53         return new DefaultMultipartConfigBuilder();
54     }
55 
56     @Override
toBuilder()57     public Builder toBuilder() {
58         return builder()
59             .apiCallBufferSizeInBytes(apiCallBufferSizeInBytes)
60             .minimumPartSizeInBytes(minimumPartSizeInBytes)
61             .thresholdInBytes(thresholdInBytes);
62     }
63 
64     /**
65      * Indicates the value of the configured threshold, in bytes. Any request whose size is less than the configured value will
66      * not use multipart operation
67      * @return the value of the configured threshold.
68      */
thresholdInBytes()69     public Long thresholdInBytes() {
70         return this.thresholdInBytes;
71     }
72 
73     /**
74      * Indicated the size, in bytes, of each individual part of the part requests. The actual part size used might be bigger to
75      * conforms to the maximum number of parts allowed per multipart requests.
76      * @return the value of the configured part size.
77      */
minimumPartSizeInBytes()78     public Long minimumPartSizeInBytes() {
79         return this.minimumPartSizeInBytes;
80     }
81 
82     /**
83      * The maximum memory, in bytes, that the SDK will use to buffer requests content into memory.
84      * @return the value of the configured maximum memory usage.
85      */
apiCallBufferSizeInBytes()86     public Long apiCallBufferSizeInBytes() {
87         return this.apiCallBufferSizeInBytes;
88     }
89 
90     /**
91      * Builder for a {@link MultipartConfiguration}.
92      */
93     public interface Builder extends CopyableBuilder<Builder, MultipartConfiguration> {
94 
95         /**
96          * Configure the size threshold, in bytes, for when to use multipart upload. Uploads/copies over this size will
97          * automatically use a multipart upload strategy, while uploads/copies smaller than this threshold will use a single
98          * connection to upload/copy the whole object.
99          *
100          * <p>
101          * Multipart uploads are easier to recover from and also potentially faster than single part uploads, especially when the
102          * upload parts can be uploaded in parallel. Because there are additional network API calls, small objects are still
103          * recommended to use a single connection for the upload. See
104          * <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html">Uploading and copying objects using
105          * multipart upload</a>.
106          *
107          * <p>
108          * By default, it is the same as {@link #minimumPartSizeInBytes(Long)}.
109          *
110          * @param thresholdInBytes the value of the threshold to set.
111          * @return an instance of this builder.
112          */
thresholdInBytes(Long thresholdInBytes)113         Builder thresholdInBytes(Long thresholdInBytes);
114 
115         /**
116          * Indicates the value of the configured threshold.
117          * @return the value of the threshold.
118          */
thresholdInBytes()119         Long thresholdInBytes();
120 
121         /**
122          * Configures the part size, in bytes, to be used in each individual part requests.
123          * Only used for putObject and copyObject operations.
124          * <p>
125          * When uploading large payload, the size of the payload of each individual part requests might actually be
126          * bigger than
127          * the configured value since there is a limit to the maximum number of parts possible per multipart request. If the
128          * configured part size would lead to a number of parts higher than the maximum allowed, a larger part size will be
129          * calculated instead to allow fewer part to be uploaded, to avoid the limit imposed on the maximum number of parts.
130          * <p>
131          * In the case where the {@code minimumPartSizeInBytes} is set to a value higher than the {@code thresholdInBytes}, when
132          * the client receive a request with a size smaller than a single part multipart operation will <em>NOT</em> be performed
133          * even if the size of the request is larger than the threshold.
134          * <p>
135          * Default value: 8 Mib
136          *
137          * @param minimumPartSizeInBytes the value of the part size to set
138          * @return an instance of this builder.
139          */
minimumPartSizeInBytes(Long minimumPartSizeInBytes)140         Builder minimumPartSizeInBytes(Long minimumPartSizeInBytes);
141 
142         /**
143          * Indicated the value of the part configured size.
144          * @return the value of the part size
145          */
minimumPartSizeInBytes()146         Long minimumPartSizeInBytes();
147 
148         /**
149          * Configures the maximum amount of memory, in bytes, the SDK will use to buffer content of requests in memory.
150          * Increasing this value may lead to better performance at the cost of using more memory.
151          * <p>
152          * Default value: If not specified, the SDK will use the equivalent of four parts worth of memory, so 32 Mib by default.
153          *
154          * @param apiCallBufferSizeInBytes the value of the maximum memory usage.
155          * @return an instance of this builder.
156          */
apiCallBufferSizeInBytes(Long apiCallBufferSizeInBytes)157         Builder apiCallBufferSizeInBytes(Long apiCallBufferSizeInBytes);
158 
159         /**
160          * Indicates the value of the maximum memory usage that the SDK will use.
161          * @return the value of the maximum memory usage.
162          */
apiCallBufferSizeInBytes()163         Long apiCallBufferSizeInBytes();
164     }
165 
166     private static class DefaultMultipartConfigBuilder implements Builder {
167         private Long thresholdInBytes;
168         private Long minimumPartSizeInBytes;
169         private Long apiCallBufferSizeInBytes;
170 
thresholdInBytes(Long thresholdInBytes)171         public Builder thresholdInBytes(Long thresholdInBytes) {
172             this.thresholdInBytes = thresholdInBytes;
173             return this;
174         }
175 
thresholdInBytes()176         public Long thresholdInBytes() {
177             return this.thresholdInBytes;
178         }
179 
minimumPartSizeInBytes(Long minimumPartSizeInBytes)180         public Builder minimumPartSizeInBytes(Long minimumPartSizeInBytes) {
181             this.minimumPartSizeInBytes = minimumPartSizeInBytes;
182             return this;
183         }
184 
minimumPartSizeInBytes()185         public Long minimumPartSizeInBytes() {
186             return this.minimumPartSizeInBytes;
187         }
188 
189         @Override
apiCallBufferSizeInBytes(Long maximumMemoryUsageInBytes)190         public Builder apiCallBufferSizeInBytes(Long maximumMemoryUsageInBytes) {
191             this.apiCallBufferSizeInBytes = maximumMemoryUsageInBytes;
192             return this;
193         }
194 
195         @Override
apiCallBufferSizeInBytes()196         public Long apiCallBufferSizeInBytes() {
197             return apiCallBufferSizeInBytes;
198         }
199 
200         @Override
build()201         public MultipartConfiguration build() {
202             return new MultipartConfiguration(this);
203         }
204     }
205 }
206