25
25
import software .amazon .awssdk .annotations .SdkInternalApi ;
26
26
import software .amazon .awssdk .core .async .AsyncRequestBody ;
27
27
import software .amazon .awssdk .core .async .SdkPublisher ;
28
+ import software .amazon .awssdk .core .exception .NonRetryableException ;
29
+ import software .amazon .awssdk .core .internal .util .NoopSubscription ;
28
30
import software .amazon .awssdk .utils .Logger ;
29
31
import software .amazon .awssdk .utils .Validate ;
30
32
import software .amazon .awssdk .utils .async .SimplePublisher ;
@@ -48,8 +50,8 @@ public class SplittingPublisher implements SdkPublisher<AsyncRequestBody> {
48
50
private final long bufferSizeInBytes ;
49
51
50
52
private SplittingPublisher (Builder builder ) {
51
- this .upstreamPublisher = Validate .paramNotNull (builder .asyncRequestBody , "asyncRequestBody" );
52
- this .chunkSizeInBytes = builder .chunkSizeInBytes == null ? DEFAULT_CHUNK_SIZE : builder .chunkSizeInBytes ;
53
+ this .upstreamPublisher = Validate .paramNotNull (builder .asyncRequestBody , "asyncRequestBody" );
54
+ this .chunkSizeInBytes = builder .chunkSizeInBytes == null ? DEFAULT_CHUNK_SIZE : builder .chunkSizeInBytes ;
53
55
this .bufferSizeInBytes = builder .bufferSizeInBytes == null ? DEFAULT_BUFFER_SIZE : builder .bufferSizeInBytes ;
54
56
this .splittingSubscriber = new SplittingSubscriber (upstreamPublisher .contentLength ().orElse (null ));
55
57
@@ -234,13 +236,14 @@ private Long totalDataRemaining() {
234
236
private final class DownstreamBody implements AsyncRequestBody {
235
237
236
238
/**
237
- * The maximum length of the content this AsyncRequestBody can hold.
238
- * If the upstream content length is known, this is the same as totalLength
239
+ * The maximum length of the content this AsyncRequestBody can hold. If the upstream content length is known, this is
240
+ * the same as totalLength
239
241
*/
240
242
private final long maxLength ;
241
243
private final Long totalLength ;
242
244
private final SimplePublisher <ByteBuffer > delegate = new SimplePublisher <>();
243
245
private final int chunkNumber ;
246
+ private final AtomicBoolean subscribeCalled = new AtomicBoolean (false );
244
247
private volatile long transferredLength = 0 ;
245
248
246
249
private DownstreamBody (boolean contentLengthKnown , long maxLength , int chunkNumber ) {
@@ -282,7 +285,14 @@ public void error(Throwable error) {
282
285
283
286
@ Override
284
287
public void subscribe (Subscriber <? super ByteBuffer > s ) {
285
- delegate .subscribe (s );
288
+ if (subscribeCalled .compareAndSet (false , true )) {
289
+ delegate .subscribe (s );
290
+ } else {
291
+ s .onSubscribe (new NoopSubscription (s ));
292
+ s .onError (NonRetryableException .create (
293
+ "A retry was attempted, but AsyncRequestBody.split does not "
294
+ + "support retries." ));
295
+ }
286
296
}
287
297
288
298
private void addDataBuffered (int length ) {
@@ -293,7 +303,7 @@ private void addDataBuffered(int length) {
293
303
}
294
304
}
295
305
}
296
-
306
+
297
307
public static final class Builder {
298
308
private AsyncRequestBody asyncRequestBody ;
299
309
private Long chunkSizeInBytes ;
0 commit comments