From 13adc2269d4a0110a0d1145951b9f7ef16eda3d7 Mon Sep 17 00:00:00 2001
From: RanVaknin <50976344+RanVaknin@users.noreply.github.com>
Date: Tue, 2 Sep 2025 14:03:04 -0700
Subject: [PATCH 01/11] Adding thread context package
---
bom/pom.xml | 5 +++
pom.xml | 1 +
thread-context/pom.xml | 33 ++++++++++++++
.../awssdk/threadcontext/ThreadStorage.java | 45 +++++++++++++++++++
4 files changed, 84 insertions(+)
create mode 100644 thread-context/pom.xml
create mode 100644 thread-context/src/main/java/software/amazon/awssdk/threadcontext/ThreadStorage.java
diff --git a/bom/pom.xml b/bom/pom.xml
index ede5b925100..51494631af0 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -252,6 +252,11 @@
endpoints-spi
${awsjavasdk.version}
+
+ software.amazon.awssdk
+ thread-context
+ ${awsjavasdk.version}
+
software.amazon.awssdk
diff --git a/pom.xml b/pom.xml
index 42dbdbfc01b..fd1409a27f3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -95,6 +95,7 @@
test/crt-unavailable-tests
test/architecture-tests
test/s3-tests
+ thread-context
${scm.github.url}
diff --git a/thread-context/pom.xml b/thread-context/pom.xml
new file mode 100644
index 00000000000..e942f7e0a33
--- /dev/null
+++ b/thread-context/pom.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ 4.0.0
+
+ software.amazon.awssdk
+ aws-sdk-java-pom
+ 2.33.2-SNAPSHOT
+
+ thread-context
+ AWS Java SDK :: Thread Context
+
+ Provides thread-local context storage utilities for sharing data across components.
+
+ https://aws.amazon.com/sdkforjava
+
+
\ No newline at end of file
diff --git a/thread-context/src/main/java/software/amazon/awssdk/threadcontext/ThreadStorage.java b/thread-context/src/main/java/software/amazon/awssdk/threadcontext/ThreadStorage.java
new file mode 100644
index 00000000000..f7223a74f70
--- /dev/null
+++ b/thread-context/src/main/java/software/amazon/awssdk/threadcontext/ThreadStorage.java
@@ -0,0 +1,45 @@
+/*
+ * 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.threadcontext;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public final class ThreadStorage {
+ private static final ThreadLocal
+
+ software.amazon.awssdk
+ thread-context
+ ${awsjavasdk.version}
+
software.amazon.awssdk
textract
diff --git a/pom.xml b/pom.xml
index f5577c128f9..2e942d5f56e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -659,6 +659,7 @@
protocols
regions
sdk-core
+ thread-context
http-client-spi
apache-client
netty-nio-client
diff --git a/test/architecture-tests/pom.xml b/test/architecture-tests/pom.xml
index 7b255deff4d..ac97eb8cbc3 100644
--- a/test/architecture-tests/pom.xml
+++ b/test/architecture-tests/pom.xml
@@ -61,6 +61,11 @@
software.amazon.awssdk
${awsjavasdk.version}
+
+ thread-context
+ software.amazon.awssdk
+ ${awsjavasdk.version}
+
s3
software.amazon.awssdk
diff --git a/test/tests-coverage-reporting/pom.xml b/test/tests-coverage-reporting/pom.xml
index 39e84897ced..d730618895a 100644
--- a/test/tests-coverage-reporting/pom.xml
+++ b/test/tests-coverage-reporting/pom.xml
@@ -242,6 +242,11 @@
software.amazon.awssdk
${awsjavasdk.version}
+
+ thread-context
+ software.amazon.awssdk
+ ${awsjavasdk.version}
+
diff --git a/core/aws-core/pom.xml b/core/aws-core/pom.xml
index 4005eceaddc..82514e2c01c 100644
--- a/core/aws-core/pom.xml
+++ b/core/aws-core/pom.xml
@@ -115,7 +115,7 @@
software.amazon.awssdk
- thread-context
+ utils-lite
${awsjavasdk.version}
diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/interceptor/TraceIdExecutionInterceptor.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/interceptor/TraceIdExecutionInterceptor.java
index 08df1c5bfae..e5c866ec72f 100644
--- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/interceptor/TraceIdExecutionInterceptor.java
+++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/interceptor/TraceIdExecutionInterceptor.java
@@ -23,8 +23,8 @@
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
import software.amazon.awssdk.http.SdkHttpRequest;
-import software.amazon.awssdk.threadcontext.ThreadStorage;
import software.amazon.awssdk.utils.SystemSetting;
+import software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal;
/**
* The {@code TraceIdExecutionInterceptor} copies the trace details to the {@link #TRACE_ID_HEADER} header, assuming we seem to
@@ -39,7 +39,7 @@ public class TraceIdExecutionInterceptor implements ExecutionInterceptor {
@Override
public void beforeExecution(Context.BeforeExecution context, ExecutionAttributes executionAttributes) {
- String traceId = ThreadStorage.get(CONCURRENT_TRACE_ID_KEY);
+ String traceId = software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.get(CONCURRENT_TRACE_ID_KEY);
if (traceId != null) {
executionAttributes.putAttribute(TRACE_ID, traceId);
}
@@ -72,7 +72,7 @@ public void onExecutionFailure(Context.FailedExecution context, ExecutionAttribu
private static void saveTraceId(ExecutionAttributes executionAttributes) {
String traceId = executionAttributes.getAttribute(TRACE_ID);
if (traceId != null) {
- ThreadStorage.put(CONCURRENT_TRACE_ID_KEY, executionAttributes.getAttribute(TRACE_ID));
+ SdkInternalThreadLocal.put(CONCURRENT_TRACE_ID_KEY, executionAttributes.getAttribute(TRACE_ID));
}
}
diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/interceptor/TraceIdExecutionInterceptorTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/interceptor/TraceIdExecutionInterceptorTest.java
index d1b4688d440..8cddcd8f2c7 100644
--- a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/interceptor/TraceIdExecutionInterceptorTest.java
+++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/interceptor/TraceIdExecutionInterceptorTest.java
@@ -28,7 +28,7 @@
import software.amazon.awssdk.http.SdkHttpMethod;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.testutils.EnvironmentVariableHelper;
-import software.amazon.awssdk.threadcontext.ThreadStorage;
+import software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal;
public class TraceIdExecutionInterceptorTest {
@Test
@@ -113,11 +113,11 @@ public void headerNotAddedIfNoTraceIdEnvVar() {
}
@Test
- public void modifyHttpRequest_whenMultiConcurrencyModeWithThreadStorage_shouldAddTraceIdHeader() {
+ public void modifyHttpRequest_whenMultiConcurrencyModeWithInternalThreadLocal_shouldAddTraceIdHeader() {
EnvironmentVariableHelper.run(env -> {
resetRelevantEnvVars(env);
env.set("AWS_LAMBDA_FUNCTION_NAME", "foo");
- ThreadStorage.put("AWS_LAMBDA_X_TRACE_ID", "ThreadStorage-trace-123");
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.put("AWS_LAMBDA_X_TRACE_ID", "SdkInternalThreadLocal-trace-123");
try {
TraceIdExecutionInterceptor interceptor = new TraceIdExecutionInterceptor();
@@ -127,20 +127,20 @@ public void modifyHttpRequest_whenMultiConcurrencyModeWithThreadStorage_shouldAd
Context.ModifyHttpRequest context = context();
SdkHttpRequest request = interceptor.modifyHttpRequest(context, executionAttributes);
- assertThat(request.firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("ThreadStorage-trace-123");
+ assertThat(request.firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("SdkInternalThreadLocal-trace-123");
} finally {
- ThreadStorage.remove("AWS_LAMBDA_X_TRACE_ID");
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.remove("AWS_LAMBDA_X_TRACE_ID");
}
});
}
@Test
- public void modifyHttpRequest_whenMultiConcurrencyModeWithBothThreadStorageAndSystemProperty_shouldUseThreadStorageValue() {
+ public void modifyHttpRequest_whenMultiConcurrencyModeWithBothInternalThreadLocalAndSystemProperty_shouldUseInternalThreadLocalValue() {
EnvironmentVariableHelper.run(env -> {
resetRelevantEnvVars(env);
env.set("AWS_LAMBDA_FUNCTION_NAME", "foo");
- ThreadStorage.put("AWS_LAMBDA_X_TRACE_ID", "ThreadStorage-trace-123");
+ SdkInternalThreadLocal.put("AWS_LAMBDA_X_TRACE_ID", "SdkInternalThreadLocal-trace-123");
Properties props = System.getProperties();
props.setProperty("com.amazonaws.xray.traceHeader", "sys-prop-345");
@@ -153,20 +153,20 @@ public void modifyHttpRequest_whenMultiConcurrencyModeWithBothThreadStorageAndSy
Context.ModifyHttpRequest context = context();
SdkHttpRequest request = interceptor.modifyHttpRequest(context, executionAttributes);
- assertThat(request.firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("ThreadStorage-trace-123");
+ assertThat(request.firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("SdkInternalThreadLocal-trace-123");
} finally {
- ThreadStorage.remove("AWS_LAMBDA_X_TRACE_ID");
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.remove("AWS_LAMBDA_X_TRACE_ID");
props.remove("com.amazonaws.xray.traceHeader");
}
});
}
@Test
- public void modifyHttpRequest_whenNotInLambdaEnvironmentWithThreadStorage_shouldNotAddHeader() {
+ public void modifyHttpRequest_whenNotInLambdaEnvironmentWithInternalThreadLocal_shouldNotAddHeader() {
EnvironmentVariableHelper.run(env -> {
resetRelevantEnvVars(env);
- ThreadStorage.put("AWS_LAMBDA_X_TRACE_ID", "should-be-ignored");
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.put("AWS_LAMBDA_X_TRACE_ID", "should-be-ignored");
try {
TraceIdExecutionInterceptor interceptor = new TraceIdExecutionInterceptor();
@@ -179,7 +179,7 @@ public void modifyHttpRequest_whenNotInLambdaEnvironmentWithThreadStorage_should
assertThat(request.firstMatchingHeader("X-Amzn-Trace-Id")).isEmpty();
} finally {
- ThreadStorage.remove("AWS_LAMBDA_X_TRACE_ID");
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.remove("AWS_LAMBDA_X_TRACE_ID");
}
});
}
diff --git a/pom.xml b/pom.xml
index 2e942d5f56e..4ac0d06763e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -72,7 +72,7 @@
archetypes
third-party
v2-migration
- thread-context
+ utils-lite
test/http-client-tests
test/protocol-tests
test/protocol-tests-core
@@ -659,7 +659,7 @@
protocols
regions
sdk-core
- thread-context
+ utils-lite
http-client-spi
apache-client
netty-nio-client
diff --git a/test/architecture-tests/pom.xml b/test/architecture-tests/pom.xml
index ac97eb8cbc3..429b732c0f1 100644
--- a/test/architecture-tests/pom.xml
+++ b/test/architecture-tests/pom.xml
@@ -62,7 +62,7 @@
${awsjavasdk.version}
- thread-context
+ utils-lite
software.amazon.awssdk
${awsjavasdk.version}
diff --git a/test/architecture-tests/src/test/java/software/amazon/awssdk/archtests/UtilsLitePackageTest.java b/test/architecture-tests/src/test/java/software/amazon/awssdk/archtests/UtilsLitePackageTest.java
new file mode 100644
index 00000000000..b0f8dc5ad1e
--- /dev/null
+++ b/test/architecture-tests/src/test/java/software/amazon/awssdk/archtests/UtilsLitePackageTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.archtests;
+
+import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
+
+import com.tngtech.archunit.core.domain.JavaClasses;
+import com.tngtech.archunit.core.importer.ClassFileImporter;
+import com.tngtech.archunit.lang.ArchRule;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Architecture tests for the utils-lite package to ensure it only contains allowed classes.
+ */
+public class UtilsLitePackageTest {
+
+ private static final JavaClasses CLASSES = new ClassFileImporter()
+ .importPackages("software.amazon.awssdk.utilslite");
+
+ @Test
+ public void utilsLitePackage_shouldOnlyContainAllowedClasses() {
+ ArchRule rule = classes()
+ .that().resideInAPackage("software.amazon.awssdk.utilslite")
+ .should().haveNameMatching(".*\\.(SdkInternalThreadLocal|SdkInternalThreadLocalTest)")
+ .allowEmptyShould(true)
+ .because("utils-lite package should only contain SdkInternalThreadLocal and its test");
+
+ rule.check(CLASSES);
+ }
+}
diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/TraceIdTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/TraceIdTest.java
index 43c0dad6161..3940643de70 100644
--- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/TraceIdTest.java
+++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/TraceIdTest.java
@@ -35,7 +35,7 @@
import software.amazon.awssdk.testutils.service.http.MockAsyncHttpClient;
import software.amazon.awssdk.testutils.service.http.MockSyncHttpClient;
import software.amazon.awssdk.utils.StringInputStream;
-import software.amazon.awssdk.threadcontext.ThreadStorage;
+import software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal;
/**
* Verifies that the {@link TraceIdExecutionInterceptor} is actually wired up for AWS services.
@@ -69,7 +69,7 @@ public void traceIdInterceptorIsEnabled() {
public void traceIdInterceptorPreservesTraceIdAcrossRetries() {
EnvironmentVariableHelper.run(env -> {
env.set("AWS_LAMBDA_FUNCTION_NAME", "foo");
- ThreadStorage.put("AWS_LAMBDA_X_TRACE_ID", "ThreadStorage-trace-123");
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.put("AWS_LAMBDA_X_TRACE_ID", "SdkInternalThreadLocal-trace-123");
try (MockAsyncHttpClient mockHttpClient = new MockAsyncHttpClient();
ProtocolRestJsonAsyncClient client = ProtocolRestJsonAsyncClient.builder()
@@ -96,12 +96,12 @@ public void traceIdInterceptorPreservesTraceIdAcrossRetries() {
List requests = mockHttpClient.getRequests();
assertThat(requests).hasSize(3);
- assertThat(requests.get(0).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("ThreadStorage-trace-123");
- assertThat(requests.get(1).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("ThreadStorage-trace-123");
- assertThat(requests.get(2).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("ThreadStorage-trace-123");
+ assertThat(requests.get(0).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("SdkInternalThreadLocal-trace-123");
+ assertThat(requests.get(1).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("SdkInternalThreadLocal-trace-123");
+ assertThat(requests.get(2).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("SdkInternalThreadLocal-trace-123");
} finally {
- ThreadStorage.clear();
+ SdkInternalThreadLocal.clear();
}
});
}
@@ -110,7 +110,7 @@ public void traceIdInterceptorPreservesTraceIdAcrossRetries() {
public void traceIdInterceptorPreservesTraceIdAcrossChainedFutures() {
EnvironmentVariableHelper.run(env -> {
env.set("AWS_LAMBDA_FUNCTION_NAME", "foo");
- ThreadStorage.put("AWS_LAMBDA_X_TRACE_ID", "ThreadStorage-trace-123");
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.put("AWS_LAMBDA_X_TRACE_ID", "SdkInternalThreadLocal-trace-123");
try (MockAsyncHttpClient mockHttpClient = new MockAsyncHttpClient();
ProtocolRestJsonAsyncClient client = ProtocolRestJsonAsyncClient.builder()
@@ -140,11 +140,11 @@ public void traceIdInterceptorPreservesTraceIdAcrossChainedFutures() {
assertThat(requests).hasSize(2);
- assertThat(requests.get(0).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("ThreadStorage-trace-123");
- assertThat(requests.get(1).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("ThreadStorage-trace-123");
+ assertThat(requests.get(0).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("SdkInternalThreadLocal-trace-123");
+ assertThat(requests.get(1).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("SdkInternalThreadLocal-trace-123");
} finally {
- ThreadStorage.clear();
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.clear();
}
});
}
@@ -153,7 +153,7 @@ public void traceIdInterceptorPreservesTraceIdAcrossChainedFutures() {
public void traceIdInterceptorPreservesTraceIdAcrossExceptionallyCompletedFutures() {
EnvironmentVariableHelper.run(env -> {
env.set("AWS_LAMBDA_FUNCTION_NAME", "foo");
- ThreadStorage.put("AWS_LAMBDA_X_TRACE_ID", "ThreadStorage-trace-123");
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.put("AWS_LAMBDA_X_TRACE_ID", "SdkInternalThreadLocal-trace-123");
try (MockAsyncHttpClient mockHttpClient = new MockAsyncHttpClient();
ProtocolRestJsonAsyncClient client = ProtocolRestJsonAsyncClient.builder()
@@ -183,11 +183,11 @@ public void traceIdInterceptorPreservesTraceIdAcrossExceptionallyCompletedFuture
assertThat(requests).hasSize(2);
- assertThat(requests.get(0).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("ThreadStorage-trace-123");
- assertThat(requests.get(1).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("ThreadStorage-trace-123");
+ assertThat(requests.get(0).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("SdkInternalThreadLocal-trace-123");
+ assertThat(requests.get(1).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("SdkInternalThreadLocal-trace-123");
} finally {
- ThreadStorage.clear();
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.clear();
}
});
}
@@ -196,7 +196,7 @@ public void traceIdInterceptorPreservesTraceIdAcrossExceptionallyCompletedFuture
public void traceIdInterceptorPreservesTraceIdAcrossExceptionallyCompletedFuturesThrownInPreExecution() {
EnvironmentVariableHelper.run(env -> {
env.set("AWS_LAMBDA_FUNCTION_NAME", "foo");
- ThreadStorage.put("AWS_LAMBDA_X_TRACE_ID", "ThreadStorage-trace-123");
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.put("AWS_LAMBDA_X_TRACE_ID", "SdkInternalThreadLocal-trace-123");
ExecutionInterceptor throwingInterceptor = new ExecutionInterceptor() {
private boolean hasThrown = false;
@@ -234,10 +234,10 @@ public void beforeMarshalling(Context.BeforeMarshalling context, ExecutionAttrib
List requests = mockHttpClient.getRequests();
assertThat(requests).hasSize(1);
- assertThat(requests.get(0).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("ThreadStorage-trace-123");
+ assertThat(requests.get(0).firstMatchingHeader("X-Amzn-Trace-Id")).hasValue("SdkInternalThreadLocal-trace-123");
} finally {
- ThreadStorage.clear();
+ software.amazon.awssdk.utilslite.internal.SdkInternalThreadLocal.clear();
}
});
}
diff --git a/test/tests-coverage-reporting/pom.xml b/test/tests-coverage-reporting/pom.xml
index d730618895a..c38237517cd 100644
--- a/test/tests-coverage-reporting/pom.xml
+++ b/test/tests-coverage-reporting/pom.xml
@@ -243,7 +243,7 @@
${awsjavasdk.version}
- thread-context
+ utils-lite
software.amazon.awssdk
${awsjavasdk.version}
diff --git a/thread-context/pom.xml b/utils-lite/pom.xml
similarity index 91%
rename from thread-context/pom.xml
rename to utils-lite/pom.xml
index 56a1c81bded..02de38eac13 100644
--- a/thread-context/pom.xml
+++ b/utils-lite/pom.xml
@@ -23,10 +23,10 @@
aws-sdk-java-pom
2.33.2-SNAPSHOT
- thread-context
- AWS Java SDK :: Thread Context
+ utils-lite
+ AWS Java SDK :: Utils Lite
- Provides thread-local context storage utilities for sharing data across components.
+ A package providing minimal external utils.
https://aws.amazon.com/sdkforjava
@@ -68,7 +68,7 @@
- software.amazon.awssdk.threadcontext
+ software.amazon.awssdk.utilslite
diff --git a/thread-context/src/main/java/software/amazon/awssdk/threadcontext/ThreadStorage.java b/utils-lite/src/main/java/software/amazon/awssdk/utilslite/internal/SdkInternalThreadLocal.java
similarity index 77%
rename from thread-context/src/main/java/software/amazon/awssdk/threadcontext/ThreadStorage.java
rename to utils-lite/src/main/java/software/amazon/awssdk/utilslite/internal/SdkInternalThreadLocal.java
index 187551292b9..6cff2983f3c 100644
--- a/thread-context/src/main/java/software/amazon/awssdk/threadcontext/ThreadStorage.java
+++ b/utils-lite/src/main/java/software/amazon/awssdk/utilslite/internal/SdkInternalThreadLocal.java
@@ -13,24 +13,28 @@
* permissions and limitations under the License.
*/
-package software.amazon.awssdk.threadcontext;
+package software.amazon.awssdk.utilslite.internal;
import java.util.HashMap;
import java.util.Map;
-import software.amazon.awssdk.annotations.SdkProtectedApi;
+import software.amazon.awssdk.annotations.SdkInternalApi;
/**
* Utility for thread-local context storage.
*/
-@SdkProtectedApi
-public final class ThreadStorage {
+@SdkInternalApi
+public final class SdkInternalThreadLocal {
private static final ThreadLocal