Skip to content

Commit a98af91

Browse files
authored
Surface area review (#4971)
* Surface are review comments - Guard for negative buffe size - interface for SplitAsyncResponseTransformer - do single part if byte range of part number is specified * chekstyle + spotbug * remove SplitAsyncResponseTransformer, moving it to AsyncResponseTransformer.SplitResult. Small refactor, moving some logic to DownloadObjectHelper * fix merge issues * prevent test memory heap error * add todo to remove manual test class
1 parent 730750e commit a98af91

File tree

12 files changed

+402
-157
lines changed

12 files changed

+402
-157
lines changed

core/sdk-core/src/main/java/software/amazon/awssdk/core/SplittingTransformerConfiguration.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@
3333
public final class SplittingTransformerConfiguration implements ToCopyableBuilder<SplittingTransformerConfiguration.Builder,
3434
SplittingTransformerConfiguration> {
3535

36-
private final Long bufferSize;
36+
private final Long bufferSizeInBytes;
3737

3838
private SplittingTransformerConfiguration(DefaultBuilder builder) {
39-
this.bufferSize = Validate.paramNotNull(builder.bufferSize, "bufferSize");
39+
this.bufferSizeInBytes = Validate.paramNotNull(builder.bufferSize, "bufferSize");
4040
}
4141

4242
/**
@@ -49,8 +49,8 @@ public static Builder builder() {
4949
/**
5050
* @return the buffer size
5151
*/
52-
public Long bufferSize() {
53-
return bufferSize;
52+
public Long bufferSizeInBytes() {
53+
return bufferSizeInBytes;
5454
}
5555

5656
@Override
@@ -64,12 +64,12 @@ public boolean equals(Object o) {
6464

6565
SplittingTransformerConfiguration that = (SplittingTransformerConfiguration) o;
6666

67-
return Objects.equals(bufferSize, that.bufferSize);
67+
return Objects.equals(bufferSizeInBytes, that.bufferSizeInBytes);
6868
}
6969

7070
@Override
7171
public int hashCode() {
72-
return bufferSize != null ? bufferSize.hashCode() : 0;
72+
return bufferSizeInBytes != null ? bufferSizeInBytes.hashCode() : 0;
7373
}
7474

7575
@Override
@@ -80,26 +80,26 @@ public Builder toBuilder() {
8080
public interface Builder extends CopyableBuilder<Builder, SplittingTransformerConfiguration> {
8181

8282
/**
83-
* Configures the buffer size of the {@link SplittingTransformer}.
83+
* Configures the maximum amount of memory in bytes buffered by the {@link SplittingTransformer}.
8484
*
85-
* @param bufferSize the buffer size
85+
* @param bufferSize the buffer size in bytes
8686
* @return This object for method chaining.
8787
*/
88-
Builder bufferSize(Long bufferSize);
88+
Builder bufferSizeInBytes(Long bufferSize);
8989
}
9090

9191
private static final class DefaultBuilder implements Builder {
9292
private Long bufferSize;
9393

9494
private DefaultBuilder(SplittingTransformerConfiguration configuration) {
95-
this.bufferSize = configuration.bufferSize;
95+
this.bufferSize = configuration.bufferSizeInBytes;
9696
}
9797

9898
private DefaultBuilder() {
9999
}
100100

101101
@Override
102-
public Builder bufferSize(Long bufferSize) {
102+
public Builder bufferSizeInBytes(Long bufferSize) {
103103
this.bufferSize = bufferSize;
104104
return this;
105105
}

core/sdk-core/src/main/java/software/amazon/awssdk/core/async/AsyncResponseTransformer.java

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@
2828
import software.amazon.awssdk.core.SdkResponse;
2929
import software.amazon.awssdk.core.SplittingTransformerConfiguration;
3030
import software.amazon.awssdk.core.internal.async.ByteArrayAsyncResponseTransformer;
31+
import software.amazon.awssdk.core.internal.async.DefaultAsyncResponseTransformerSplitResult;
3132
import software.amazon.awssdk.core.internal.async.FileAsyncResponseTransformer;
3233
import software.amazon.awssdk.core.internal.async.InputStreamResponseTransformer;
3334
import software.amazon.awssdk.core.internal.async.PublisherAsyncResponseTransformer;
3435
import software.amazon.awssdk.core.internal.async.SplittingTransformer;
3536
import software.amazon.awssdk.utils.Validate;
37+
import software.amazon.awssdk.utils.builder.CopyableBuilder;
38+
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
3639

3740
/**
3841
* Callback interface to handle a streaming asynchronous response.
@@ -116,25 +119,26 @@ public interface AsyncResponseTransformer<ResponseT, ResultT> {
116119
void exceptionOccurred(Throwable error);
117120

118121
/**
119-
* Creates an {@link SplitAsyncResponseTransformer} which contains an {@link SplittingTransformer} that splits the
122+
* Creates an {@link SplitResult} which contains an {@link SplittingTransformer} that splits the
120123
* {@link AsyncResponseTransformer} into multiple ones, publishing them as a {@link SdkPublisher}.
121124
*
122125
* @param splitConfig configuration for the split transformer
123126
* @return SplitAsyncResponseTransformer instance.
124127
* @see SplittingTransformer
125-
* @see SplitAsyncResponseTransformer
128+
* @see SplitResult
126129
*/
127-
default SplitAsyncResponseTransformer<ResponseT, ResultT> split(SplittingTransformerConfiguration splitConfig) {
130+
default SplitResult<ResponseT, ResultT> split(SplittingTransformerConfiguration splitConfig) {
131+
Validate.notNull(splitConfig, "splitConfig must not be null");
128132
CompletableFuture<ResultT> future = new CompletableFuture<>();
129133
SdkPublisher<AsyncResponseTransformer<ResponseT, ResponseT>> transformer = SplittingTransformer
130134
.<ResponseT, ResultT>builder()
131135
.upstreamResponseTransformer(this)
132-
.maximumBufferSize(splitConfig.bufferSize())
133-
.returnFuture(future)
136+
.maximumBufferSizeInBytes(splitConfig.bufferSizeInBytes())
137+
.resultFuture(future)
134138
.build();
135-
return SplitAsyncResponseTransformer.<ResponseT, ResultT>builder()
136-
.asyncResponseTransformerPublisher(transformer)
137-
.future(future)
139+
return AsyncResponseTransformer.SplitResult.<ResponseT, ResultT>builder()
140+
.publisher(transformer)
141+
.resultFuture(future)
138142
.build();
139143
}
140144

@@ -285,4 +289,68 @@ static <ResponseT extends SdkResponse> AsyncResponseTransformer<ResponseT, Respo
285289
AsyncResponseTransformer<ResponseT, ResponseInputStream<ResponseT>> toBlockingInputStream() {
286290
return new InputStreamResponseTransformer<>();
287291
}
292+
293+
/**
294+
* Helper interface containing the result of {@link AsyncResponseTransformer#split(SplittingTransformerConfiguration)
295+
* splitting} an AsyncResponseTransformer. This class holds both the publisher of the individual
296+
* {@code AsyncResponseTransformer<ResponseT, ResponseT>} and the {@code CompletableFuture <ResultT>} which will
297+
* complete when the {@code AsyncResponseTransformer} that was split itself would complete.
298+
*
299+
* @param <ResponseT> ResponseT of the original AsyncResponseTransformer that was split.
300+
* @param <ResultT> ResultT of the original AsyncResponseTransformer that was split.
301+
* @see AsyncResponseTransformer#split(SplittingTransformerConfiguration)
302+
*/
303+
interface SplitResult<ResponseT, ResultT>
304+
extends ToCopyableBuilder<AsyncResponseTransformer.SplitResult.Builder<ResponseT, ResultT>,
305+
AsyncResponseTransformer.SplitResult<ResponseT, ResultT>> {
306+
307+
/**
308+
* The individual {@link AsyncResponseTransformer} will be available through the publisher returned by this method.
309+
*
310+
* @return the publisher which publishes the individual {@link AsyncResponseTransformer}
311+
*/
312+
SdkPublisher<AsyncResponseTransformer<ResponseT, ResponseT>> publisher();
313+
314+
/**
315+
* The future returned by this method will be completed when the future returned by calling the
316+
* {@link AsyncResponseTransformer#prepare()} method on the AsyncResponseTransformer which was split completes.
317+
*
318+
* @return The future
319+
*/
320+
CompletableFuture<ResultT> resultFuture();
321+
322+
static <ResponseT, ResultT> Builder<ResponseT, ResultT> builder() {
323+
return DefaultAsyncResponseTransformerSplitResult.builder();
324+
}
325+
326+
interface Builder<ResponseT, ResultT>
327+
extends CopyableBuilder<AsyncResponseTransformer.SplitResult.Builder<ResponseT, ResultT>,
328+
AsyncResponseTransformer.SplitResult<ResponseT, ResultT>> {
329+
330+
/**
331+
* @return the publisher which was configured on this Builder instance.
332+
*/
333+
SdkPublisher<AsyncResponseTransformer<ResponseT, ResponseT>> publisher();
334+
335+
/**
336+
* Sets the publisher publishing the individual {@link AsyncResponseTransformer}
337+
* @param publisher the publisher
338+
* @return an instance of this Builder
339+
*/
340+
Builder<ResponseT, ResultT> publisher(SdkPublisher<AsyncResponseTransformer<ResponseT, ResponseT>> publisher);
341+
342+
/**
343+
* @return The future which was configured an this Builder instance.
344+
*/
345+
CompletableFuture<ResultT> resultFuture();
346+
347+
/**
348+
* Sets the future that will be completed when the future returned by calling the
349+
* {@link AsyncResponseTransformer#prepare()} method on the AsyncResponseTransformer which was split completes.
350+
* @param future the future
351+
* @return an instance of this Builder
352+
*/
353+
Builder<ResponseT, ResultT> resultFuture(CompletableFuture<ResultT> future);
354+
}
355+
}
288356
}

core/sdk-core/src/main/java/software/amazon/awssdk/core/async/SplitAsyncResponseTransformer.java

Lines changed: 0 additions & 87 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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.core.internal.async;
17+
18+
import java.util.concurrent.CompletableFuture;
19+
import software.amazon.awssdk.annotations.SdkInternalApi;
20+
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
21+
import software.amazon.awssdk.core.async.SdkPublisher;
22+
import software.amazon.awssdk.utils.Validate;
23+
24+
@SdkInternalApi
25+
public final class DefaultAsyncResponseTransformerSplitResult<ResponseT, ResultT>
26+
implements AsyncResponseTransformer.SplitResult<ResponseT, ResultT> {
27+
28+
private final SdkPublisher<AsyncResponseTransformer<ResponseT, ResponseT>> publisher;
29+
private final CompletableFuture<ResultT> future;
30+
31+
private DefaultAsyncResponseTransformerSplitResult(Builder<ResponseT, ResultT> builder) {
32+
this.publisher = Validate.paramNotNull(
33+
builder.publisher(), "asyncResponseTransformerPublisher");
34+
this.future = Validate.paramNotNull(
35+
builder.resultFuture(), "future");
36+
}
37+
38+
/**
39+
* The individual {@link AsyncResponseTransformer} will be available through the publisher returned by this method.
40+
* @return the publisher which publishes the individual {@link AsyncResponseTransformer}
41+
*/
42+
public SdkPublisher<AsyncResponseTransformer<ResponseT, ResponseT>> publisher() {
43+
return this.publisher;
44+
}
45+
46+
/**
47+
* The future returned by this method will be completed when the future returned by calling the
48+
* {@link AsyncResponseTransformer#prepare()} method on the AsyncResponseTransformer which was split completes.
49+
* @return The future
50+
*/
51+
public CompletableFuture<ResultT> resultFuture() {
52+
return this.future;
53+
}
54+
55+
@Override
56+
public AsyncResponseTransformer.SplitResult.Builder<ResponseT, ResultT> toBuilder() {
57+
return new DefaultBuilder<>(this);
58+
}
59+
60+
public static <ResponseT, ResultT> DefaultBuilder<ResponseT, ResultT> builder() {
61+
return new DefaultBuilder<>();
62+
}
63+
64+
public static class DefaultBuilder<ResponseT, ResultT>
65+
implements AsyncResponseTransformer.SplitResult.Builder<ResponseT, ResultT> {
66+
private SdkPublisher<AsyncResponseTransformer<ResponseT, ResponseT>> publisher;
67+
private CompletableFuture<ResultT> future;
68+
69+
DefaultBuilder() {
70+
}
71+
72+
DefaultBuilder(DefaultAsyncResponseTransformerSplitResult<ResponseT, ResultT> split) {
73+
this.publisher = split.publisher;
74+
this.future = split.future;
75+
}
76+
77+
@Override
78+
public SdkPublisher<AsyncResponseTransformer<ResponseT, ResponseT>> publisher() {
79+
return this.publisher;
80+
}
81+
82+
@Override
83+
public AsyncResponseTransformer.SplitResult.Builder<ResponseT, ResultT> publisher(
84+
SdkPublisher<AsyncResponseTransformer<ResponseT, ResponseT>> publisher) {
85+
this.publisher = publisher;
86+
return this;
87+
}
88+
89+
@Override
90+
public CompletableFuture<ResultT> resultFuture() {
91+
return this.future;
92+
}
93+
94+
@Override
95+
public AsyncResponseTransformer.SplitResult.Builder<ResponseT, ResultT> resultFuture(CompletableFuture<ResultT> future) {
96+
this.future = future;
97+
return this;
98+
}
99+
100+
@Override
101+
public AsyncResponseTransformer.SplitResult<ResponseT, ResultT> build() {
102+
return new DefaultAsyncResponseTransformerSplitResult<>(this);
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)