- * For example, the creation of a {@code ResettableInputStream} would entail physically opening a file. If the opened file is
- * meant to be closed only (in a finally block) by the very same code block that created it, then it is necessary that the release
- * method must not be called while the execution is made in other stack frames.
- *
- * In such case, as other stack frames may inadvertently or indirectly call the close method of the stream, the creator of the
- * stream would need to explicitly disable the accidental closing via {@code ResettableInputStream#disableClose()}, so that the
- * release method becomes the only way to truly close the opened file.
- */
-@SdkInternalApi
-public interface Releasable {
- /**
- * Releases the given {@link Closeable} especially if it was an instance of {@link Releasable}.
- *
- * For example, the creation of a {@code ResettableInputStream} would entail physically opening a file. If the opened file is
- * meant to be closed only (in a finally block) by the very same code block that created it, then it is necessary that the
- * release method must not be called while the execution is made in other stack frames.
- *
- * In such case, as other stack frames may inadvertently or indirectly call the close method of the stream, the creator of the
- * stream would need to explicitly disable the accidental closing via {@code ResettableInputStream#disableClose()}, so that
- * the release method becomes the only way to truly close the opened file.
- */
- static void release(Closeable is, Logger log) {
- closeQuietly(is, log);
- if (is instanceof Releasable) {
- Releasable r = (Releasable) is;
- r.release();
- }
- }
-
- /**
- * Releases the allocated resource. This method should not be called except by the caller who allocated the resource at the
- * very top of the call stack. This allows, typically, a {@link Closeable} resource to be not unintentionally released owing
- * to the calling of the {@link Closeable#close()} methods by implementation deep down in the call stack.
- *
- * For example, the creation of a {@code ResettableInputStream} would entail physically opening a file. If the opened file is
- * meant to be closed only (in a finally block) by the very same code block that created it, then it is necessary that the
- * release method must not be called while the execution is made in other stack frames.
- *
- * In such case, as other stack frames may inadvertently or indirectly call the close method of the stream, the creator of the
- * stream would need to explicitly disable the accidental closing via {@code ResettableInputStream#disableClose()}, so that
- * the release method becomes the only way to truly close the opened file.
- */
- void release();
-}
diff --git a/core/http-auth-aws/src/main/java/software/amazon/awssdk/http/auth/aws/internal/signer/io/SdkLengthAwareInputStream.java b/core/http-auth-aws/src/main/java/software/amazon/awssdk/http/auth/aws/internal/signer/io/SdkLengthAwareInputStream.java
deleted file mode 100644
index b7ec9ad4442b..000000000000
--- a/core/http-auth-aws/src/main/java/software/amazon/awssdk/http/auth/aws/internal/signer/io/SdkLengthAwareInputStream.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package software.amazon.awssdk.http.auth.aws.internal.signer.io;
-
-import static software.amazon.awssdk.utils.NumericUtils.saturatedCast;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import software.amazon.awssdk.annotations.SdkInternalApi;
-import software.amazon.awssdk.utils.Logger;
-import software.amazon.awssdk.utils.Validate;
-
-/**
- * An {@code InputStream} that is aware of its length. The main purpose of this class is to support truncating streams to a length
- * that is shorter than the total length of the stream.
- */
-@SdkInternalApi
-public class SdkLengthAwareInputStream extends FilterInputStream {
- private static final Logger LOG = Logger.loggerFor(SdkLengthAwareInputStream.class);
- private long length;
- private long remaining;
-
- public SdkLengthAwareInputStream(InputStream in, long length) {
- super(in);
- this.length = Validate.isNotNegative(length, "length");
- this.remaining = this.length;
- }
-
- @Override
- public int read() throws IOException {
- if (!hasMoreBytes()) {
- LOG.debug(() -> String.format("Specified InputStream length of %d has been reached. Returning EOF.", length));
- return -1;
- }
-
- int read = super.read();
- if (read != -1) {
- remaining--;
- }
- return read;
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- if (!hasMoreBytes()) {
- LOG.debug(() -> String.format("Specified InputStream length of %d has been reached. Returning EOF.", length));
- return -1;
- }
-
- len = Math.min(len, saturatedCast(remaining));
- int read = super.read(b, off, len);
- if (read > 0) {
- remaining -= read;
- }
-
- return read;
- }
-
- @Override
- public long skip(long requestedBytesToSkip) throws IOException {
- requestedBytesToSkip = Math.min(requestedBytesToSkip, remaining);
- long skippedActual = super.skip(requestedBytesToSkip);
- remaining -= skippedActual;
- return skippedActual;
- }
-
- @Override
- public int available() throws IOException {
- int streamAvailable = super.available();
- return Math.min(streamAvailable, saturatedCast(remaining));
- }
-
- @Override
- public void mark(int readlimit) {
- super.mark(readlimit);
- // mark() causes reset() to change the stream's position back to the current position. Therefore, when reset() is called,
- // the new length of the stream will be equal to the current value of 'remaining'.
- length = remaining;
- }
-
- @Override
- public void reset() throws IOException {
- super.reset();
- remaining = length;
- }
-
- public long remaining() {
- return remaining;
- }
-
- private boolean hasMoreBytes() {
- return remaining > 0;
- }
-}
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.java
index deb354d276dd..edf8a3fcae37 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.java
@@ -25,11 +25,11 @@
import org.reactivestreams.Subscriber;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.core.exception.NonRetryableException;
-import software.amazon.awssdk.core.internal.io.SdkLengthAwareInputStream;
import software.amazon.awssdk.core.internal.util.Mimetype;
import software.amazon.awssdk.core.internal.util.NoopSubscription;
import software.amazon.awssdk.utils.Validate;
import software.amazon.awssdk.utils.async.InputStreamConsumingPublisher;
+import software.amazon.awssdk.utils.io.SdkLengthAwareInputStream;
/**
* An implementation of {@link AsyncRequestBody} that allows performing a blocking write of an input stream to a downstream
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java
index 521155a0cd0c..0a7c4df51a02 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java
@@ -37,7 +37,6 @@
import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute;
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
import software.amazon.awssdk.core.internal.InternalCoreExecutionAttribute;
-import software.amazon.awssdk.core.internal.io.SdkLengthAwareInputStream;
import software.amazon.awssdk.core.internal.util.MetricUtils;
import software.amazon.awssdk.core.metrics.CoreMetric;
import software.amazon.awssdk.core.signer.Signer;
@@ -49,6 +48,7 @@
import software.amazon.awssdk.metrics.MetricCollector;
import software.amazon.awssdk.utils.Pair;
import software.amazon.awssdk.utils.StringUtils;
+import software.amazon.awssdk.utils.io.SdkLengthAwareInputStream;
@SdkInternalApi
public abstract class BaseClientHandler {
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStage.java
index 0655d62d3f27..7618657e2a5c 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStage.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStage.java
@@ -26,7 +26,6 @@
import software.amazon.awssdk.core.internal.http.InterruptMonitor;
import software.amazon.awssdk.core.internal.http.RequestExecutionContext;
import software.amazon.awssdk.core.internal.http.pipeline.RequestPipeline;
-import software.amazon.awssdk.core.internal.io.SdkLengthAwareInputStream;
import software.amazon.awssdk.core.internal.util.MetricUtils;
import software.amazon.awssdk.core.metrics.CoreMetric;
import software.amazon.awssdk.http.ContentStreamProvider;
@@ -39,6 +38,7 @@
import software.amazon.awssdk.metrics.MetricCollector;
import software.amazon.awssdk.utils.Logger;
import software.amazon.awssdk.utils.Pair;
+import software.amazon.awssdk.utils.io.SdkLengthAwareInputStream;
/**
* Delegate to the HTTP implementation to make an HTTP request and receive the response.
diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStageTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStageTest.java
index 7e0391389bcf..11ef4b034732 100644
--- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStageTest.java
+++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStageTest.java
@@ -40,7 +40,7 @@
import software.amazon.awssdk.core.internal.http.HttpClientDependencies;
import software.amazon.awssdk.core.internal.http.RequestExecutionContext;
import software.amazon.awssdk.core.internal.http.timers.TimeoutTracker;
-import software.amazon.awssdk.core.internal.io.SdkLengthAwareInputStream;
+import software.amazon.awssdk.utils.io.SdkLengthAwareInputStream;
import software.amazon.awssdk.http.ContentStreamProvider;
import software.amazon.awssdk.http.HttpExecuteRequest;
import software.amazon.awssdk.http.SdkHttpClient;
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/io/SdkLengthAwareInputStream.java b/utils/src/main/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStream.java
similarity index 97%
rename from core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/io/SdkLengthAwareInputStream.java
rename to utils/src/main/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStream.java
index f4ecdd2d7d23..210ced2e7afe 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/io/SdkLengthAwareInputStream.java
+++ b/utils/src/main/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStream.java
@@ -13,14 +13,14 @@
* permissions and limitations under the License.
*/
-package software.amazon.awssdk.core.internal.io;
+package software.amazon.awssdk.utils.io;
import static software.amazon.awssdk.utils.NumericUtils.saturatedCast;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
-import software.amazon.awssdk.annotations.SdkInternalApi;
+import software.amazon.awssdk.annotations.SdkProtectedApi;
import software.amazon.awssdk.utils.Logger;
import software.amazon.awssdk.utils.Validate;
@@ -29,7 +29,7 @@
* the input length. If the wrapped stream has more bytes than the expected length, it will be truncated to length. If the stream
* has less bytes (i.e. reaches EOF) before the expected length is reached, it will throw {@code IOException}.
*/
-@SdkInternalApi
+@SdkProtectedApi
public class SdkLengthAwareInputStream extends FilterInputStream {
private static final Logger LOG = Logger.loggerFor(SdkLengthAwareInputStream.class);
private final long length;
diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/io/SdkLengthAwareInputStreamTest.java b/utils/src/test/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStreamTest.java
similarity index 98%
rename from core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/io/SdkLengthAwareInputStreamTest.java
rename to utils/src/test/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStreamTest.java
index 8f76213e54fc..634a3d48f43d 100644
--- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/io/SdkLengthAwareInputStreamTest.java
+++ b/utils/src/test/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStreamTest.java
@@ -13,10 +13,9 @@
* permissions and limitations under the License.
*/
-package software.amazon.awssdk.core.internal.io;
+package software.amazon.awssdk.utils.io;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
@@ -28,7 +27,6 @@
import java.io.InputStream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import software.amazon.awssdk.utils.IoUtils;
class SdkLengthAwareInputStreamTest {
private InputStream delegateStream;
From 801380687263ec236dd578e3e0a7d7a847d9de1c Mon Sep 17 00:00:00 2001
From: Zoe Wang <33073555+zoewangg@users.noreply.github.com>
Date: Thu, 23 Oct 2025 15:51:21 -0700
Subject: [PATCH 4/5] Rename SdkLengthAwareInputStream to
LengthAwareInputStream (#6504)
---
.../chunkedencoding/ChunkInputStream.java | 4 +-
.../BlockingInputStreamAsyncRequestBody.java | 4 +-
.../internal/handler/BaseClientHandler.java | 4 +-
.../pipeline/stages/MakeHttpRequestStage.java | 6 +--
.../stages/MakeHttpRequestStageTest.java | 6 +--
...tream.java => LengthAwareInputStream.java} | 20 +++++-----
...t.java => LengthAwareInputStreamTest.java} | 38 +++++++++----------
7 files changed, 41 insertions(+), 41 deletions(-)
rename utils/src/main/java/software/amazon/awssdk/utils/io/{SdkLengthAwareInputStream.java => LengthAwareInputStream.java} (86%)
rename utils/src/test/java/software/amazon/awssdk/utils/io/{SdkLengthAwareInputStreamTest.java => LengthAwareInputStreamTest.java} (84%)
diff --git a/core/http-auth-aws/src/main/java/software/amazon/awssdk/http/auth/aws/internal/signer/chunkedencoding/ChunkInputStream.java b/core/http-auth-aws/src/main/java/software/amazon/awssdk/http/auth/aws/internal/signer/chunkedencoding/ChunkInputStream.java
index bfb062f22cf2..4b555ef31fcf 100644
--- a/core/http-auth-aws/src/main/java/software/amazon/awssdk/http/auth/aws/internal/signer/chunkedencoding/ChunkInputStream.java
+++ b/core/http-auth-aws/src/main/java/software/amazon/awssdk/http/auth/aws/internal/signer/chunkedencoding/ChunkInputStream.java
@@ -18,13 +18,13 @@
import java.io.IOException;
import java.io.InputStream;
import software.amazon.awssdk.annotations.SdkInternalApi;
-import software.amazon.awssdk.utils.io.SdkLengthAwareInputStream;
+import software.amazon.awssdk.utils.io.LengthAwareInputStream;
/**
* A wrapped stream to represent a "chunk" of data
*/
@SdkInternalApi
-public final class ChunkInputStream extends SdkLengthAwareInputStream {
+public final class ChunkInputStream extends LengthAwareInputStream {
public ChunkInputStream(InputStream inputStream, long length) {
super(inputStream, length);
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.java
index edf8a3fcae37..8826613659b5 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.java
@@ -29,7 +29,7 @@
import software.amazon.awssdk.core.internal.util.NoopSubscription;
import software.amazon.awssdk.utils.Validate;
import software.amazon.awssdk.utils.async.InputStreamConsumingPublisher;
-import software.amazon.awssdk.utils.io.SdkLengthAwareInputStream;
+import software.amazon.awssdk.utils.io.LengthAwareInputStream;
/**
* An implementation of {@link AsyncRequestBody} that allows performing a blocking write of an input stream to a downstream
@@ -89,7 +89,7 @@ public long writeInputStream(InputStream inputStream) {
try {
waitForSubscriptionIfNeeded();
if (contentLength != null) {
- return delegate.doBlockingWrite(new SdkLengthAwareInputStream(inputStream, contentLength));
+ return delegate.doBlockingWrite(new LengthAwareInputStream(inputStream, contentLength));
}
return delegate.doBlockingWrite(inputStream);
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java
index 0a7c4df51a02..9aea1f328993 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/handler/BaseClientHandler.java
@@ -48,7 +48,7 @@
import software.amazon.awssdk.metrics.MetricCollector;
import software.amazon.awssdk.utils.Pair;
import software.amazon.awssdk.utils.StringUtils;
-import software.amazon.awssdk.utils.io.SdkLengthAwareInputStream;
+import software.amazon.awssdk.utils.io.LengthAwareInputStream;
@SdkInternalApi
public abstract class BaseClientHandler {
@@ -136,7 +136,7 @@ private static RequestBody getBody(SdkHttpFullRequest request) {
ContentStreamProvider streamProvider = contentStreamProviderOptional.get();
if (contentLengthOptional.isPresent()) {
ContentStreamProvider toWrap = contentStreamProviderOptional.get();
- streamProvider = () -> new SdkLengthAwareInputStream(toWrap.newStream(), contentLength);
+ streamProvider = () -> new LengthAwareInputStream(toWrap.newStream(), contentLength);
}
return new SdkInternalOnlyRequestBody(streamProvider,
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStage.java
index 7618657e2a5c..34183a8bae1e 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStage.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStage.java
@@ -38,7 +38,7 @@
import software.amazon.awssdk.metrics.MetricCollector;
import software.amazon.awssdk.utils.Logger;
import software.amazon.awssdk.utils.Pair;
-import software.amazon.awssdk.utils.io.SdkLengthAwareInputStream;
+import software.amazon.awssdk.utils.io.LengthAwareInputStream;
/**
* Delegate to the HTTP implementation to make an HTTP request and receive the response.
@@ -119,8 +119,8 @@ private static SdkHttpFullRequest enforceContentLengthIfPresent(SdkHttpFullReque
}
ContentStreamProvider requestContentProvider = requestContentStreamProviderOptional.get();
- ContentStreamProvider lengthVerifyingProvider = () -> new SdkLengthAwareInputStream(requestContentProvider.newStream(),
- contentLength.get());
+ ContentStreamProvider lengthVerifyingProvider = () -> new LengthAwareInputStream(requestContentProvider.newStream(),
+ contentLength.get());
return request.toBuilder()
.contentStreamProvider(lengthVerifyingProvider)
.build();
diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStageTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStageTest.java
index 11ef4b034732..710b6853d0ed 100644
--- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStageTest.java
+++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/MakeHttpRequestStageTest.java
@@ -40,7 +40,7 @@
import software.amazon.awssdk.core.internal.http.HttpClientDependencies;
import software.amazon.awssdk.core.internal.http.RequestExecutionContext;
import software.amazon.awssdk.core.internal.http.timers.TimeoutTracker;
-import software.amazon.awssdk.utils.io.SdkLengthAwareInputStream;
+import software.amazon.awssdk.utils.io.LengthAwareInputStream;
import software.amazon.awssdk.http.ContentStreamProvider;
import software.amazon.awssdk.http.HttpExecuteRequest;
import software.amazon.awssdk.http.SdkHttpClient;
@@ -135,9 +135,9 @@ public void execute_testLengthChecking(String description,
InputStream requestContentStream = capturedRequest.contentStreamProvider().get().newStream();
if (expectLengthAware) {
- assertThat(requestContentStream).isInstanceOf(SdkLengthAwareInputStream.class);
+ assertThat(requestContentStream).isInstanceOf(LengthAwareInputStream.class);
} else {
- assertThat(requestContentStream).isNotInstanceOf(SdkLengthAwareInputStream.class);
+ assertThat(requestContentStream).isNotInstanceOf(LengthAwareInputStream.class);
}
} else {
assertThat(capturedRequest.contentStreamProvider()).isEmpty();
diff --git a/utils/src/main/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStream.java b/utils/src/main/java/software/amazon/awssdk/utils/io/LengthAwareInputStream.java
similarity index 86%
rename from utils/src/main/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStream.java
rename to utils/src/main/java/software/amazon/awssdk/utils/io/LengthAwareInputStream.java
index 210ced2e7afe..4c16ebd059cd 100644
--- a/utils/src/main/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStream.java
+++ b/utils/src/main/java/software/amazon/awssdk/utils/io/LengthAwareInputStream.java
@@ -30,13 +30,13 @@
* has less bytes (i.e. reaches EOF) before the expected length is reached, it will throw {@code IOException}.
*/
@SdkProtectedApi
-public class SdkLengthAwareInputStream extends FilterInputStream {
- private static final Logger LOG = Logger.loggerFor(SdkLengthAwareInputStream.class);
+public class LengthAwareInputStream extends FilterInputStream {
+ private static final Logger LOG = Logger.loggerFor(LengthAwareInputStream.class);
private final long length;
private long remaining;
private long markedRemaining;
- public SdkLengthAwareInputStream(InputStream in, long length) {
+ public LengthAwareInputStream(InputStream in, long length) {
super(in);
this.length = Validate.isNotNegative(length, "length");
this.remaining = this.length;
@@ -44,7 +44,7 @@ public SdkLengthAwareInputStream(InputStream in, long length) {
}
@Override
- public int read() throws IOException {
+ public final int read() throws IOException {
if (!hasMoreBytes()) {
LOG.debug(() -> String.format("Specified InputStream length of %d has been reached. Returning EOF.", length));
return -1;
@@ -66,7 +66,7 @@ public int read() throws IOException {
}
@Override
- public int read(byte[] b, int off, int len) throws IOException {
+ public final int read(byte[] b, int off, int len) throws IOException {
if (!hasMoreBytes()) {
LOG.debug(() -> String.format("Specified InputStream length of %d has been reached. Returning EOF.", length));
return -1;
@@ -90,7 +90,7 @@ public int read(byte[] b, int off, int len) throws IOException {
}
@Override
- public long skip(long requestedBytesToSkip) throws IOException {
+ public final long skip(long requestedBytesToSkip) throws IOException {
requestedBytesToSkip = Math.min(requestedBytesToSkip, remaining);
long skippedActual = super.skip(requestedBytesToSkip);
remaining -= skippedActual;
@@ -98,25 +98,25 @@ public long skip(long requestedBytesToSkip) throws IOException {
}
@Override
- public int available() throws IOException {
+ public final int available() throws IOException {
int streamAvailable = super.available();
return Math.min(streamAvailable, saturatedCast(remaining));
}
@Override
- public void mark(int readlimit) {
+ public final void mark(int readlimit) {
super.mark(readlimit);
// Store the current remaining bytes to restore on reset()
markedRemaining = remaining;
}
@Override
- public void reset() throws IOException {
+ public final void reset() throws IOException {
super.reset();
remaining = markedRemaining;
}
- public long remaining() {
+ public final long remaining() {
return remaining;
}
diff --git a/utils/src/test/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStreamTest.java b/utils/src/test/java/software/amazon/awssdk/utils/io/LengthAwareInputStreamTest.java
similarity index 84%
rename from utils/src/test/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStreamTest.java
rename to utils/src/test/java/software/amazon/awssdk/utils/io/LengthAwareInputStreamTest.java
index 634a3d48f43d..714a60223138 100644
--- a/utils/src/test/java/software/amazon/awssdk/utils/io/SdkLengthAwareInputStreamTest.java
+++ b/utils/src/test/java/software/amazon/awssdk/utils/io/LengthAwareInputStreamTest.java
@@ -28,7 +28,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-class SdkLengthAwareInputStreamTest {
+class LengthAwareInputStreamTest {
private InputStream delegateStream;
@BeforeEach
@@ -40,7 +40,7 @@ void setup() {
void read_lengthIs0_returnsEof() throws IOException {
when(delegateStream.available()).thenReturn(Integer.MAX_VALUE);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegateStream, 0);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegateStream, 0);
assertThat(is.read()).isEqualTo(-1);
assertThat(is.read(new byte[16], 0, 16)).isEqualTo(-1);
@@ -51,7 +51,7 @@ void read_lengthNonZero_delegateEof_returnsEof() throws IOException {
when(delegateStream.read()).thenReturn(-1);
when(delegateStream.read(any(byte[].class), any(int.class), any(int.class))).thenReturn(-1);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegateStream, 0);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegateStream, 0);
assertThat(is.read()).isEqualTo(-1);
assertThat(is.read(new byte[16], 0, 16)).isEqualTo(-1);
@@ -61,7 +61,7 @@ void read_lengthNonZero_delegateEof_returnsEof() throws IOException {
void readByte_lengthNonZero_delegateHasAvailable_returnsDelegateData() throws IOException {
when(delegateStream.read()).thenReturn(42);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegateStream, 16);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegateStream, 16);
assertThat(is.read()).isEqualTo(42);
}
@@ -70,7 +70,7 @@ void readByte_lengthNonZero_delegateHasAvailable_returnsDelegateData() throws IO
void readArray_lengthNonZero_delegateHasAvailable_returnsDelegateData() throws IOException {
when(delegateStream.read(any(byte[].class), any(int.class), any(int.class))).thenReturn(8);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegateStream, 16);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegateStream, 16);
assertThat(is.read(new byte[16], 0, 16)).isEqualTo(8);
}
@@ -79,7 +79,7 @@ void readArray_lengthNonZero_delegateHasAvailable_returnsDelegateData() throws I
void readArray_lengthNonZero_propagatesCallToDelegate() throws IOException {
when(delegateStream.read(any(byte[].class), any(int.class), any(int.class))).thenReturn(8);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegateStream, 16);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegateStream, 16);
byte[] buff = new byte[16];
is.read(buff, 0, 16);
@@ -90,7 +90,7 @@ void readArray_lengthNonZero_propagatesCallToDelegate() throws IOException {
void read_markAndReset_availableReflectsNewLength() throws IOException {
delegateStream = new ByteArrayInputStream(new byte[32]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegateStream, 16);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegateStream, 16);
for (int i = 0; i < 4; ++i) {
is.read();
@@ -113,7 +113,7 @@ void read_markAndReset_availableReflectsNewLength() throws IOException {
void skip_markAndReset_availableReflectsNewLength() throws IOException {
delegateStream = new ByteArrayInputStream(new byte[32]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegateStream, 16);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegateStream, 16);
is.skip(4);
@@ -141,7 +141,7 @@ void skip_delegateSkipsLessThanRequested_availableUpdatedCorrectly() throws IOEx
when(delegateStream.read(any(byte[].class), any(int.class), any(int.class))).thenReturn(1);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegateStream, 16);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegateStream, 16);
long skipped = is.skip(4);
@@ -156,7 +156,7 @@ void readArray_delegateReadsLessThanRequested_availableUpdatedCorrectly() throws
return n / 2;
});
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegateStream, 16);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegateStream, 16);
long read = is.read(new byte[16], 0, 8);
@@ -169,7 +169,7 @@ void readArray_delegateShorterThanExpected_throws() {
int delegateLength = 16;
ByteArrayInputStream delegate = new ByteArrayInputStream(new byte[delegateLength]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegate, delegateLength + 1);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegate, delegateLength + 1);
assertThatThrownBy(() -> {
int read;
@@ -186,7 +186,7 @@ void readArray_readExactLength_doesNotThrow() throws IOException {
int delegateLength = 16;
ByteArrayInputStream delegate = new ByteArrayInputStream(new byte[delegateLength]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegate, delegateLength);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegate, delegateLength);
int total = 0;
int read;
@@ -204,7 +204,7 @@ void readArray_delegateLongerThanRequired_truncated() throws IOException {
int length = 16;
ByteArrayInputStream delegate = new ByteArrayInputStream(new byte[delegateLength]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegate, length);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegate, length);
int total = 0;
int read;
@@ -221,7 +221,7 @@ void readByte_delegateShorterThanExpected_throws() {
int delegateLength = 16;
ByteArrayInputStream delegate = new ByteArrayInputStream(new byte[delegateLength]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegate, delegateLength + 1);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegate, delegateLength + 1);
assertThatThrownBy(() -> {
int read;
@@ -237,7 +237,7 @@ void readByte_readExactLength_doesNotThrow() throws IOException {
int delegateLength = 16;
ByteArrayInputStream delegate = new ByteArrayInputStream(new byte[delegateLength]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegate, delegateLength);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegate, delegateLength);
int total = 0;
while (total != delegateLength && is.read() != -1) {
@@ -253,7 +253,7 @@ void readBytePartialThenMark_doesNotResetContentLength() throws IOException {
int expectedContentLength = delegateLength + 1;
ByteArrayInputStream delegate = new ByteArrayInputStream(new byte[delegateLength]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegate, expectedContentLength);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegate, expectedContentLength);
is.read(); // read one byte
is.mark(1024);
// read another byte and reset, the length should not be reset based on the byte that was already read
@@ -274,7 +274,7 @@ void readByte_delegateLongerThanRequired_truncated() throws IOException {
int length = 16;
ByteArrayInputStream delegate = new ByteArrayInputStream(new byte[delegateLength]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegate, length);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegate, length);
int total = 0;
while (total != delegateLength && is.read() != -1) {
@@ -290,7 +290,7 @@ public void skip_thenReadByteUntilEof_doesNotThrowLengthMismatch() throws IOExce
ByteArrayInputStream delegate = new ByteArrayInputStream(new byte[delegateLength]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegate, delegateLength);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegate, delegateLength);
int bytesToSkip = 8;
int skippedBytes = 0;
@@ -315,7 +315,7 @@ public void skip_thenReadArrayUntilEof_doesNotThrowLengthMismatch() throws IOExc
ByteArrayInputStream delegate = new ByteArrayInputStream(new byte[delegateLength]);
- SdkLengthAwareInputStream is = new SdkLengthAwareInputStream(delegate, delegateLength);
+ LengthAwareInputStream is = new LengthAwareInputStream(delegate, delegateLength);
int bytesToSkip = 8;
int skippedBytes = 0;
From 1679633e3c6bf29b0d9280bb7ec1cae032b813f2 Mon Sep 17 00:00:00 2001
From: Zoe Wang <33073555+zoewangg@users.noreply.github.com>
Date: Thu, 23 Oct 2025 15:51:52 -0700
Subject: [PATCH 5/5] Remove unused test and methods (#6497)
---
.../internal/signer/util/FifoCacheTest.java | 77 -------------------
.../amazon/awssdk/utils/cache/FifoCache.java | 13 +---
.../awssdk/utils/cache/FifoCacheTest.java | 40 +++++-----
3 files changed, 24 insertions(+), 106 deletions(-)
delete mode 100644 core/http-auth-aws/src/test/java/software/amazon/awssdk/http/auth/aws/internal/signer/util/FifoCacheTest.java
diff --git a/core/http-auth-aws/src/test/java/software/amazon/awssdk/http/auth/aws/internal/signer/util/FifoCacheTest.java b/core/http-auth-aws/src/test/java/software/amazon/awssdk/http/auth/aws/internal/signer/util/FifoCacheTest.java
deleted file mode 100644
index dacbed9b952e..000000000000
--- a/core/http-auth-aws/src/test/java/software/amazon/awssdk/http/auth/aws/internal/signer/util/FifoCacheTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package software.amazon.awssdk.http.auth.aws.internal.signer.util;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import org.junit.jupiter.api.Test;
-import software.amazon.awssdk.utils.cache.FifoCache;
-
-public class FifoCacheTest {
-
- @Test
- public void test() {
- FifoCache cache = new FifoCache<>(3);
- assertEquals(0, cache.size());
- cache.add("k1", "v1");
- assertEquals(1, cache.size());
- cache.add("k1", "v11");
- assertEquals(1, cache.size());
- cache.add("k2", "v2");
- assertEquals(2, cache.size());
- cache.add("k3", "v3");
- assertEquals(3, cache.size());
- assertEquals("v11", cache.get("k1"));
- assertEquals("v2", cache.get("k2"));
- assertEquals("v3", cache.get("k3"));
- cache.add("k4", "v4");
- assertEquals(3, cache.size());
- assertNull(cache.get("k1"));
- }
-
- @Test
- public void testZeroSize() {
- assertThrows(IllegalArgumentException.class, () -> new FifoCache<>(0));
- }
-
- @Test
- public void testIllegalArgument() {
- assertThrows(IllegalArgumentException.class, () -> new FifoCache<>(0));
- }
-
- @Test
- public void testSingleEntry() {
- FifoCache cache = new FifoCache(1);
- assertEquals(0, cache.size());
- cache.add("k1", "v1");
- assertEquals(1, cache.size());
- cache.add("k1", "v11");
- assertEquals(1, cache.size());
- assertEquals("v11", cache.get("k1"));
-
- cache.add("k2", "v2");
- assertEquals(1, cache.size());
- assertEquals("v2", cache.get("k2"));
- assertNull(cache.get("k1"));
-
- cache.add("k3", "v3");
- assertEquals(1, cache.size());
- assertEquals("v3", cache.get("k3"));
- assertNull(cache.get("k2"));
- }
-}
diff --git a/utils/src/main/java/software/amazon/awssdk/utils/cache/FifoCache.java b/utils/src/main/java/software/amazon/awssdk/utils/cache/FifoCache.java
index ed52aa3f260f..e0e6bb6587af 100644
--- a/utils/src/main/java/software/amazon/awssdk/utils/cache/FifoCache.java
+++ b/utils/src/main/java/software/amazon/awssdk/utils/cache/FifoCache.java
@@ -19,6 +19,7 @@
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import software.amazon.awssdk.annotations.SdkProtectedApi;
+import software.amazon.awssdk.annotations.SdkTestInternalApi;
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.utils.internal.BoundedLinkedHashMap;
@@ -75,7 +76,8 @@ public T get(String key) {
/**
* Returns the current size of the cache.
*/
- public int size() {
+ @SdkTestInternalApi
+ int size() {
rlock.lock();
try {
return map.size();
@@ -84,18 +86,11 @@ public int size() {
}
}
- /**
- * Returns the maximum size of the cache.
- */
- public int getMaxSize() {
- return map.getMaxSize();
- }
-
@Override
public String toString() {
rlock.lock();
try {
- return map.toString();
+ return map.keySet().toString();
} finally {
rlock.unlock();
}
diff --git a/utils/src/test/java/software/amazon/awssdk/utils/cache/FifoCacheTest.java b/utils/src/test/java/software/amazon/awssdk/utils/cache/FifoCacheTest.java
index b9790777cf8a..b98be58240aa 100644
--- a/utils/src/test/java/software/amazon/awssdk/utils/cache/FifoCacheTest.java
+++ b/utils/src/test/java/software/amazon/awssdk/utils/cache/FifoCacheTest.java
@@ -15,61 +15,61 @@
package software.amazon.awssdk.utils.cache;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
public class FifoCacheTest {
@Test
public void test() {
- FifoCache cache = new FifoCache(3);
- assertTrue(cache.size() == 0);
+ FifoCache cache = new FifoCache<>(3);
+ assertEquals(0, cache.size());
cache.add("k1", "v1");
- assertTrue(cache.size() == 1);
+ assertEquals(1, cache.size());
cache.add("k1", "v11");
- assertTrue(cache.size() == 1);
+ assertEquals(1, cache.size());
cache.add("k2", "v2");
- assertTrue(cache.size() == 2);
+ assertEquals(2, cache.size());
cache.add("k3", "v3");
- assertTrue(cache.size() == 3);
+ assertEquals(3, cache.size());
assertEquals("v11", cache.get("k1"));
assertEquals("v2", cache.get("k2"));
assertEquals("v3", cache.get("k3"));
cache.add("k4", "v4");
- assertTrue(cache.size() == 3);
+ assertEquals(3, cache.size());
assertNull(cache.get("k1"));
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void testZeroSize() {
- new FifoCache