Skip to content

Commit 93582c5

Browse files
authored
Update UA configurator to comply with 50 chars limit. (#2268)
1 parent 41f3ef5 commit 93582c5

File tree

2 files changed

+111
-5
lines changed

2 files changed

+111
-5
lines changed

powertools-common/src/main/java/software/amazon/lambda/powertools/common/internal/UserAgentConfigurator.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,25 +82,52 @@ static String getVersionFromProperties(String propertyFileName, String versionKe
8282

8383
/**
8484
* Configures the AWS SDK to use Powertools user agent by setting the sdk.ua.appId system property.
85-
* If the property is already set and not empty, appends the Powertools user agent with a "/" separator.
85+
* Preserves any user-provided value and replaces any existing Powertools user agent.
86+
* Enforces a 50 character limit to comply with AWS SDK recommendations.
8687
* This should be called during library initialization to ensure the user agent is properly configured.
8788
*/
8889
public static void configureUserAgent(String ptFeature) {
8990
try {
9091
String existingValue = System.getProperty(SDK_USER_AGENT_APP_ID);
9192
String powertoolsUserAgent = getUserAgent(ptFeature);
93+
String newValue;
9294

93-
if (existingValue != null && !existingValue.isEmpty()) {
94-
System.setProperty(SDK_USER_AGENT_APP_ID, existingValue + "/" + powertoolsUserAgent);
95+
if (existingValue == null || existingValue.isEmpty()) {
96+
newValue = powertoolsUserAgent;
9597
} else {
96-
System.setProperty(SDK_USER_AGENT_APP_ID, powertoolsUserAgent);
98+
String userValue = extractUserValue(existingValue);
99+
if (userValue.isEmpty()) {
100+
newValue = powertoolsUserAgent;
101+
} else {
102+
newValue = userValue + "/" + powertoolsUserAgent;
103+
}
104+
}
105+
106+
if (newValue.length() <= 50) {
107+
System.setProperty(SDK_USER_AGENT_APP_ID, newValue);
97108
}
98109
} catch (Exception e) {
99110
// We don't re-raise since we don't want to break the user if something in this logic doesn't work
100111
LOG.warn("Unable to configure user agent system property", e);
101112
}
102113
}
103114

115+
/**
116+
* Extracts the user-provided value from the existing user agent string by removing any Powertools user agent.
117+
* A Powertools user agent follows the pattern "PT/{FEATURE}/{VERSION} PTENV/{ENV}".
118+
*
119+
* @param existingValue the existing user agent string
120+
* @return the user-provided value without Powertools user agent, or empty string if none exists
121+
*/
122+
static String extractUserValue(String existingValue) {
123+
if (existingValue == null || existingValue.isEmpty()) {
124+
return "";
125+
}
126+
// Remove Powertools user agent pattern: PT/{FEATURE}/{VERSION} PTENV/{ENV}
127+
String result = existingValue.replaceAll("/?PT/[^/]+/[^ ]+ PTENV/[^ ]+", "");
128+
return result.trim();
129+
}
130+
104131
/**
105132
* Retrieves the user agent string for the Powertools for AWS Lambda.
106133
* It follows the pattern PT/{PT_FEATURE}/{PT_VERSION} PTENV/{PT_EXEC_ENV}

powertools-common/src/test/java/software/amazon/lambda/powertools/common/internal/UserAgentConfiguratorTest.java

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,72 @@ void testConfigureUserAgent() {
131131
}
132132

133133
@Test
134-
void testConfigureUserAgent_WithExistingValue() {
134+
void testConfigureUserAgent_WithExistingUserValue() {
135135
System.setProperty("sdk.ua.appId", "UserValueABC123");
136136
UserAgentConfigurator.configureUserAgent("test-feature");
137137

138138
assertThat(System.getProperty("sdk.ua.appId"))
139139
.isEqualTo("UserValueABC123/PT/TEST-FEATURE/" + VERSION + " PTENV/NA");
140140
}
141141

142+
@Test
143+
void testConfigureUserAgent_ReplacePowertoolsUserAgent() {
144+
System.setProperty("sdk.ua.appId", "PT/BATCH/" + VERSION + " PTENV/NA");
145+
UserAgentConfigurator.configureUserAgent("logging-log4j");
146+
147+
assertThat(System.getProperty("sdk.ua.appId"))
148+
.isEqualTo("PT/LOGGING-LOG4J/" + VERSION + " PTENV/NA");
149+
}
150+
151+
@Test
152+
void testConfigureUserAgent_PreserveUserValueAndReplacePowertools() {
153+
System.setProperty("sdk.ua.appId", "UserValue/PT/BATCH/" + VERSION + " PTENV/NA");
154+
UserAgentConfigurator.configureUserAgent("tracing");
155+
156+
assertThat(System.getProperty("sdk.ua.appId"))
157+
.isEqualTo("UserValue/PT/TRACING/" + VERSION + " PTENV/NA");
158+
}
159+
160+
@Test
161+
void testConfigureUserAgent_ExceedsLimit() {
162+
System.setProperty("sdk.ua.appId", "VeryLongUserValueThatExceedsTheLimitWhenCombined");
163+
UserAgentConfigurator.configureUserAgent("test-feature");
164+
165+
// Should not update if it would exceed 50 characters
166+
assertThat(System.getProperty("sdk.ua.appId"))
167+
.isEqualTo("VeryLongUserValueThatExceedsTheLimitWhenCombined");
168+
}
169+
170+
@Test
171+
void testExtractUserValue_NoUserValue() {
172+
String result = UserAgentConfigurator.extractUserValue("PT/BATCH/" + VERSION + " PTENV/NA");
173+
assertThat(result).isEmpty();
174+
}
175+
176+
@Test
177+
void testExtractUserValue_WithUserValue() {
178+
String result = UserAgentConfigurator.extractUserValue("UserValue/PT/BATCH/" + VERSION + " PTENV/NA");
179+
assertThat(result).isEqualTo("UserValue");
180+
}
181+
182+
@Test
183+
void testExtractUserValue_EmptyString() {
184+
String result = UserAgentConfigurator.extractUserValue("");
185+
assertThat(result).isEmpty();
186+
}
187+
188+
@Test
189+
void testExtractUserValue_NullString() {
190+
String result = UserAgentConfigurator.extractUserValue(null);
191+
assertThat(result).isEmpty();
192+
}
193+
194+
@Test
195+
void testExtractUserValue_OnlyUserValue() {
196+
String result = UserAgentConfigurator.extractUserValue("MyCustomValue");
197+
assertThat(result).isEqualTo("MyCustomValue");
198+
}
199+
142200
@Test
143201
void testConfigureUserAgent_WithEmptyExistingValue() {
144202
System.setProperty("sdk.ua.appId", "");
@@ -148,4 +206,25 @@ void testConfigureUserAgent_WithEmptyExistingValue() {
148206
.isEqualTo("PT/TEST-FEATURE/" + VERSION + " PTENV/NA");
149207
}
150208

209+
@Test
210+
@SetEnvironmentVariable(key = AWS_EXECUTION_ENV, value = "AWS_Lambda_java11")
211+
void testConfigureUserAgent_MultipleUtilities() {
212+
System.clearProperty("sdk.ua.appId");
213+
214+
// First utility
215+
UserAgentConfigurator.configureUserAgent("batch");
216+
assertThat(System.getProperty("sdk.ua.appId"))
217+
.isEqualTo("PT/BATCH/" + VERSION + " PTENV/AWS_Lambda_java11");
218+
219+
// Second utility - should replace, not append
220+
UserAgentConfigurator.configureUserAgent("logging-log4j");
221+
assertThat(System.getProperty("sdk.ua.appId"))
222+
.isEqualTo("PT/LOGGING-LOG4J/" + VERSION + " PTENV/AWS_Lambda_java11");
223+
224+
// Third utility - should replace again
225+
UserAgentConfigurator.configureUserAgent("tracing");
226+
assertThat(System.getProperty("sdk.ua.appId"))
227+
.isEqualTo("PT/TRACING/" + VERSION + " PTENV/AWS_Lambda_java11");
228+
}
229+
151230
}

0 commit comments

Comments
 (0)