Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@
* <p>This getter automatically sanitizes keys to match environment variable naming conventions:
*
* <ul>
* <li>Converts keys to uppercase (e.g., {@code traceparent} becomes {@code TRACEPARENT})
* <li>Replaces {@code .} and {@code -} with underscores
* <li>Replaces an empty key with a single underscore ({@code _})
* <li>Converts ASCII letters to uppercase (e.g., {@code traceparent} becomes {@code TRACEPARENT})
* <li>Replaces every character that is not an ASCII letter, digit, or underscore with an
* underscore
* <li>Prepends an underscore if the result would otherwise start with an ASCII digit
* </ul>
*
* <p>Values are validated to contain only characters valid in HTTP header fields per <a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* conventions:
*
* <ul>
* <li>An empty key is replaced with a single underscore ({@code _})
* <li>ASCII letters are converted to uppercase
* <li>Any character that is not an ASCII letter, digit, or underscore is replaced with an
* underscore
Expand Down Expand Up @@ -92,6 +93,7 @@ static boolean isNormalizedKey(String key) {
* Normalizes a key to be a valid environment variable name.
*
* <ul>
* <li>An empty key is replaced with a single underscore ({@code _})
* <li>ASCII letters are converted to uppercase
* <li>Any character that is not an ASCII letter, digit, or underscore is replaced with an
* underscore (including {@code .}, {@code -}, whitespace, and control characters)
Expand All @@ -102,6 +104,9 @@ static String normalizeKey(String key) {
if (isNormalizedKey(key)) {
return key;
}
if (key.isEmpty()) {
return "_";
}
StringBuilder sb = new StringBuilder(key.length() + 1);
for (int i = 0; i < key.length(); i++) {
char ch = key.charAt(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,15 @@ void get_normalization() {
// Carrier entries are expected to have normalized keys (i.e. set via EnvironmentSetter).
carrier.put("OTEL_TRACE_ID", "val1");
carrier.put("OTEL_BAGGAGE_KEY", "val2");
carrier.put("_", "val3");
// Carrier entry with an unnormalized key is not reachable via get().
carrier.put("otel-unreachable-key", "val3");
carrier.put("", "val4");
carrier.put("otel-unreachable-key", "val5");

// Lookup keys are normalized before the carrier map is consulted.
assertThat(EnvironmentGetter.getInstance().get(carrier, "otel.trace.id")).isEqualTo("val1");
assertThat(EnvironmentGetter.getInstance().get(carrier, "otel-baggage-key")).isEqualTo("val2");
assertThat(EnvironmentGetter.getInstance().get(carrier, "")).isEqualTo("val3");
// Carrier entries with unnormalized keys are not enumerated.
assertThat(EnvironmentGetter.getInstance().get(carrier, "otel-unreachable-key")).isNull();
}
Expand All @@ -60,12 +63,15 @@ void get_null() {
@SuppressLogger(EnvironmentGetter.class)
void keys_onlyNormalizedKeysIncluded() {
Map<String, String> carrier = new HashMap<>();
carrier.put("", "V0");
carrier.put("otel.trace.id", "V1");
carrier.put("otel-baggage-key", "V2");
carrier.put("OTEL_FOO", "V3");
carrier.put("_", "V4");

// Non-normalized keys are excluded; only already-normalized keys are returned.
assertThat(EnvironmentGetter.getInstance().keys(carrier)).containsExactlyInAnyOrder("OTEL_FOO");
assertThat(EnvironmentGetter.getInstance().keys(carrier))
.containsExactlyInAnyOrder("OTEL_FOO", "_");
for (String key : EnvironmentGetter.getInstance().keys(carrier)) {
assertThat(EnvironmentGetter.getInstance().get(carrier, key)).isNotNull();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ void set_sanitization() {
Map<String, String> carrier = new HashMap<>();
EnvironmentSetter.getInstance().set(carrier, "otel.trace.id", "val1");
EnvironmentSetter.getInstance().set(carrier, "otel-baggage-key", "val2");
EnvironmentSetter.getInstance().set(carrier, "", "val3");

assertThat(carrier).containsEntry("OTEL_TRACE_ID", "val1");
assertThat(carrier).containsEntry("OTEL_BAGGAGE_KEY", "val2");
assertThat(carrier).containsEntry("_", "val3");
}

@Test
Expand Down Expand Up @@ -76,6 +78,7 @@ static Stream<Arguments> isNormalizedKeyCases() {
return Stream.of(
Arguments.argumentSet("uppercase letters", "TRACEPARENT", true),
Arguments.argumentSet("uppercase with underscores", "OTEL_TRACE_ID", true),
Arguments.argumentSet("single underscore", "_", true),
Arguments.argumentSet("single letter", "A", true),
Arguments.argumentSet("letter then digit", "A0", true),
Arguments.argumentSet("mixed uppercase digits underscores", "A_B_0", true),
Expand Down
Loading