From df9a72bbb06620fb3834520e1b7dcc06a436c0b9 Mon Sep 17 00:00:00 2001 From: Bhagirath00 Date: Thu, 12 Feb 2026 18:18:04 +0530 Subject: [PATCH 1/4] Implement Environment Variable Context Propagation carriers in api/incubator --- .../propagation/EnvironmentGetter.java | 47 +++++++++++++++++ .../propagation/EnvironmentSetter.java | 37 ++++++++++++++ .../propagation/EnvironmentGetterTest.java | 51 +++++++++++++++++++ .../propagation/EnvironmentSetterTest.java | 41 +++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetter.java create mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetter.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetterTest.java create mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetterTest.java diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetter.java new file mode 100644 index 00000000000..5dfae10392f --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetter.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.propagation; + +import io.opentelemetry.context.propagation.TextMapGetter; +import java.util.Collections; +import java.util.Locale; +import java.util.Map; +import javax.annotation.Nullable; + +/** + * A {@link TextMapGetter} that extracts context from a map carrier, intended for use with + * environment variables. + * + *

Standard environment variable names are uppercase (e.g., {@code TRACEPARENT}, {@code + * TRACESTATE}, {@code BAGGAGE}). This getter translates keys to uppercase before looking them up in + * the carrier. + */ +public enum EnvironmentGetter implements TextMapGetter> { + INSTANCE; + + @Override + public Iterable keys(Map carrier) { + if (carrier == null) { + return Collections.emptyList(); + } + return carrier.keySet(); + } + + @Nullable + @Override + public String get(@Nullable Map carrier, String key) { + if (carrier == null || key == null) { + return null; + } + // Spec recommends using uppercase for environment variable names. + return carrier.get(key.toUpperCase(Locale.ROOT)); + } + + @Override + public String toString() { + return "EnvironmentGetter"; + } +} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetter.java new file mode 100644 index 00000000000..bc94a12af23 --- /dev/null +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetter.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.propagation; + +import io.opentelemetry.context.propagation.TextMapSetter; +import java.util.Locale; +import java.util.Map; +import javax.annotation.Nullable; + +/** + * A {@link TextMapSetter} that injects context into a map carrier, intended for use with + * environment variables. + * + *

Standard environment variable names are uppercase (e.g., {@code TRACEPARENT}, {@code + * TRACESTATE}, {@code BAGGAGE}). This setter translates keys to uppercase before inserting them + * into the carrier. + */ +public enum EnvironmentSetter implements TextMapSetter> { + INSTANCE; + + @Override + public void set(@Nullable Map carrier, String key, String value) { + if (carrier == null || key == null || value == null) { + return; + } + // Spec recommends using uppercase for environment variable names. + carrier.put(key.toUpperCase(Locale.ROOT), value); + } + + @Override + public String toString() { + return "EnvironmentSetter"; + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetterTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetterTest.java new file mode 100644 index 00000000000..0370beb885b --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetterTest.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.propagation; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class EnvironmentGetterTest { + + @Test + void get() { + Map carrier = new HashMap<>(); + carrier.put("TRACEPARENT", "val1"); + carrier.put("TRACESTATE", "val2"); + carrier.put("BAGGAGE", "val3"); + carrier.put("OTHER", "val4"); + + assertThat(EnvironmentGetter.INSTANCE.get(carrier, "traceparent")).isEqualTo("val1"); + assertThat(EnvironmentGetter.INSTANCE.get(carrier, "TRACESTATE")).isEqualTo("val2"); + assertThat(EnvironmentGetter.INSTANCE.get(carrier, "Baggage")).isEqualTo("val3"); + assertThat(EnvironmentGetter.INSTANCE.get(carrier, "other")).isEqualTo("val4"); + } + + @Test + void get_null() { + assertThat(EnvironmentGetter.INSTANCE.get(null, "key")).isNull(); + assertThat(EnvironmentGetter.INSTANCE.get(Collections.emptyMap(), null)).isNull(); + } + + @Test + void keys() { + Map carrier = new HashMap<>(); + carrier.put("K1", "V1"); + carrier.put("K2", "V2"); + + assertThat(EnvironmentGetter.INSTANCE.keys(carrier)).containsExactlyInAnyOrder("K1", "K2"); + assertThat(EnvironmentGetter.INSTANCE.keys(null)).isEmpty(); + } + + @Test + void testToString() { + assertThat(EnvironmentGetter.INSTANCE.toString()).isEqualTo("EnvironmentGetter"); + } +} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetterTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetterTest.java new file mode 100644 index 00000000000..02308a7b544 --- /dev/null +++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetterTest.java @@ -0,0 +1,41 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.api.incubator.propagation; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class EnvironmentSetterTest { + + @Test + void set() { + Map carrier = new HashMap<>(); + EnvironmentSetter.INSTANCE.set(carrier, "traceparent", "val1"); + EnvironmentSetter.INSTANCE.set(carrier, "TRACESTATE", "val2"); + EnvironmentSetter.INSTANCE.set(carrier, "Baggage", "val3"); + + assertThat(carrier).containsEntry("TRACEPARENT", "val1"); + assertThat(carrier).containsEntry("TRACESTATE", "val2"); + assertThat(carrier).containsEntry("BAGGAGE", "val3"); + } + + @Test + void set_null() { + Map carrier = new HashMap<>(); + EnvironmentSetter.INSTANCE.set(null, "key", "val"); + EnvironmentSetter.INSTANCE.set(carrier, null, "val"); + EnvironmentSetter.INSTANCE.set(carrier, "key", null); + assertThat(carrier).isEmpty(); + } + + @Test + void testToString() { + assertThat(EnvironmentSetter.INSTANCE.toString()).isEqualTo("EnvironmentSetter"); + } +} From 6eed41cb82a610ad21b72daaf73a00719a5ed64b Mon Sep 17 00:00:00 2001 From: Bhagirath00 Date: Fri, 13 Feb 2026 11:45:09 +0530 Subject: [PATCH 2/4] Update DeclarativeConfigProperties to return null on type mismatch --- .../config/DeclarativeConfigProperties.java | 57 ++++++++----------- .../YamlDeclarativeConfigPropertiesTest.java | 5 ++ 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java index 425a3d768be..ac3cef17c99 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java @@ -46,8 +46,8 @@ static Map toMap(DeclarativeConfigProperties declarativeConfigPr /** * Returns a {@link String} configuration property. * - * @return null if the property has not been configured - * @throws DeclarativeConfigException if the property is not a valid scalar string + * @return null if the property has not been configured or if the property is not a valid scalar + * string */ @Nullable String getString(String name); @@ -56,8 +56,7 @@ static Map toMap(DeclarativeConfigProperties declarativeConfigPr * Returns a {@link String} configuration property. * * @return a {@link String} configuration property or {@code defaultValue} if a property with - * {@code name} has not been configured - * @throws DeclarativeConfigException if the property is not a valid scalar string + * {@code name} has not been configured or is not a valid scalar string */ default String getString(String name, String defaultValue) { return defaultIfNull(getString(name), defaultValue); @@ -67,8 +66,8 @@ default String getString(String name, String defaultValue) { * Returns a {@link Boolean} configuration property. Implementations should use the same rules as * {@link Boolean#parseBoolean(String)} for handling the values. * - * @return null if the property has not been configured - * @throws DeclarativeConfigException if the property is not a valid scalar boolean + * @return null if the property has not been configured or if the property is not a valid scalar + * boolean */ @Nullable Boolean getBoolean(String name); @@ -77,8 +76,7 @@ default String getString(String name, String defaultValue) { * Returns a {@link Boolean} configuration property. * * @return a {@link Boolean} configuration property or {@code defaultValue} if a property with - * {@code name} has not been configured - * @throws DeclarativeConfigException if the property is not a valid scalar boolean + * {@code name} has not been configured or is not a valid scalar boolean */ default boolean getBoolean(String name, boolean defaultValue) { return defaultIfNull(getBoolean(name), defaultValue); @@ -90,8 +88,8 @@ default boolean getBoolean(String name, boolean defaultValue) { *

If the underlying config property is {@link Long}, it is converted to {@link Integer} with * {@link Long#intValue()} which may result in loss of precision. * - * @return null if the property has not been configured - * @throws DeclarativeConfigException if the property is not a valid scalar integer + * @return null if the property has not been configured or if the property is not a valid scalar + * integer */ @Nullable Integer getInt(String name); @@ -103,8 +101,7 @@ default boolean getBoolean(String name, boolean defaultValue) { * {@link Long#intValue()} which may result in loss of precision. * * @return a {@link Integer} configuration property or {@code defaultValue} if a property with - * {@code name} has not been configured - * @throws DeclarativeConfigException if the property is not a valid scalar integer + * {@code name} has not been configured or is not a valid scalar integer */ default int getInt(String name, int defaultValue) { return defaultIfNull(getInt(name), defaultValue); @@ -113,8 +110,8 @@ default int getInt(String name, int defaultValue) { /** * Returns a {@link Long} configuration property. * - * @return null if the property has not been configured - * @throws DeclarativeConfigException if the property is not a valid scalar long + * @return null if the property has not been configured or if the property is not a valid scalar + * long */ @Nullable Long getLong(String name); @@ -123,8 +120,7 @@ default int getInt(String name, int defaultValue) { * Returns a {@link Long} configuration property. * * @return a {@link Long} configuration property or {@code defaultValue} if a property with {@code - * name} has not been configured - * @throws DeclarativeConfigException if the property is not a valid scalar long + * name} has not been configured or is not a valid scalar long */ default long getLong(String name, long defaultValue) { return defaultIfNull(getLong(name), defaultValue); @@ -133,8 +129,8 @@ default long getLong(String name, long defaultValue) { /** * Returns a {@link Double} configuration property. * - * @return null if the property has not been configured - * @throws DeclarativeConfigException if the property is not a valid scalar double + * @return null if the property has not been configured or if the property is not a valid scalar + * double */ @Nullable Double getDouble(String name); @@ -143,8 +139,7 @@ default long getLong(String name, long defaultValue) { * Returns a {@link Double} configuration property. * * @return a {@link Double} configuration property or {@code defaultValue} if a property with - * {@code name} has not been configured - * @throws DeclarativeConfigException if the property is not a valid scalar double + * {@code name} has not been configured or is not a valid scalar double */ default double getDouble(String name, double defaultValue) { return defaultIfNull(getDouble(name), defaultValue); @@ -158,8 +153,8 @@ default double getDouble(String name, double defaultValue) { * @param scalarType the scalar type, one of {@link String}, {@link Boolean}, {@link Long} or * {@link Double} * @return a {@link List} configuration property, or null if the property has not been configured - * @throws DeclarativeConfigException if the property is not a valid sequence of scalars, or if - * {@code scalarType} is not supported + * or if the property is not a valid sequence of scalars + * @throws DeclarativeConfigException if {@code scalarType} is not supported */ @Nullable List getScalarList(String name, Class scalarType); @@ -172,8 +167,7 @@ default double getDouble(String name, double defaultValue) { * @param scalarType the scalar type, one of {@link String}, {@link Boolean}, {@link Long} or * {@link Double} * @return a {@link List} configuration property or {@code defaultValue} if a property with {@code - * name} has not been configured - * @throws DeclarativeConfigException if the property is not a valid sequence of scalars + * name} has not been configured or is not a valid sequence of scalars */ default List getScalarList(String name, Class scalarType, List defaultValue) { return defaultIfNull(getScalarList(name, scalarType), defaultValue); @@ -183,8 +177,7 @@ default List getScalarList(String name, Class scalarType, List defa * Returns a {@link DeclarativeConfigProperties} configuration property. * * @return a map-valued configuration property, or {@code null} if {@code name} has not been - * configured - * @throws DeclarativeConfigException if the property is not a mapping + * configured or is not a mapping */ @Nullable DeclarativeConfigProperties getStructured(String name); @@ -193,8 +186,7 @@ default List getScalarList(String name, Class scalarType, List defa * Returns a list of {@link DeclarativeConfigProperties} configuration property. * * @return a map-valued configuration property, or {@code defaultValue} if {@code name} has not - * been configured - * @throws DeclarativeConfigException if the property is not a mapping + * been configured or is not a mapping */ default DeclarativeConfigProperties getStructured( String name, DeclarativeConfigProperties defaultValue) { @@ -210,8 +202,7 @@ default DeclarativeConfigProperties getStructured( * but empty vs. not set, use {@link #getStructured(String)}. * * @return a map-valued configuration property, or an empty {@link DeclarativeConfigProperties} - * instance if {@code name} has not been configured - * @throws DeclarativeConfigException if the property is not a mapping + * instance if {@code name} has not been configured or is not a mapping */ default DeclarativeConfigProperties get(String name) { return getStructured(name, empty()); @@ -221,8 +212,7 @@ default DeclarativeConfigProperties get(String name) { * Returns a list of {@link DeclarativeConfigProperties} configuration property. * * @return a list of map-valued configuration property, or {@code null} if {@code name} has not - * been configured - * @throws DeclarativeConfigException if the property is not a sequence of mappings + * been configured or is not a sequence of mappings */ @Nullable List getStructuredList(String name); @@ -231,8 +221,7 @@ default DeclarativeConfigProperties get(String name) { * Returns a list of {@link DeclarativeConfigProperties} configuration property. * * @return a list of map-valued configuration property, or {@code defaultValue} if {@code name} - * has not been configured - * @throws DeclarativeConfigException if the property is not a sequence of mappings + * has not been configured or is not a sequence of mappings */ default List getStructuredList( String name, List defaultValue) { diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java index 63ece0a0687..18611e901d1 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java @@ -230,8 +230,11 @@ void wrongType() { assertThat(otherProps.getDouble("str_key")).isNull(); assertThat(otherProps.getBoolean("str_key")).isNull(); assertThat(otherProps.getScalarList("str_key", String.class)).isNull(); + assertThat(otherProps.getScalarList("str_list_key", Long.class)).isNull(); assertThat(otherProps.getStructured("str_key")).isNull(); assertThat(otherProps.getStructuredList("str_key")).isNull(); + assertThat(otherProps.getStructured("str_list_key")).isNull(); + assertThat(otherProps.getStructuredList("map_key")).isNull(); assertWarning("Ignoring value for key [int_key] because it is Integer instead of String: 1"); assertWarning( @@ -240,6 +243,8 @@ void wrongType() { "Ignoring value for key [str_key] because it is String instead of Double: str_value"); assertWarning( "Ignoring value for key [str_key] because it is String instead of Boolean: str_value"); + assertWarning( + "Ignoring value for key [str_list_key] because it is String instead of Long: val1"); } private void assertWarning(String message) { From 2012cd9a9534c0bf4ff66ab7a73734889fb6224c Mon Sep 17 00:00:00 2001 From: Bhagirath00 Date: Mon, 16 Feb 2026 22:46:38 +0530 Subject: [PATCH 3/4] Address feedback: clean up branch and improve safety in DeclarativeConfig --- .../propagation/EnvironmentGetter.java | 47 ----------------- .../propagation/EnvironmentSetter.java | 37 -------------- .../propagation/EnvironmentGetterTest.java | 51 ------------------- .../propagation/EnvironmentSetterTest.java | 41 --------------- .../YamlDeclarativeConfigProperties.java | 11 +++- .../YamlDeclarativeConfigPropertiesTest.java | 23 ++++++++- 6 files changed, 32 insertions(+), 178 deletions(-) delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetter.java delete mode 100644 api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetter.java delete mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetterTest.java delete mode 100644 api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetterTest.java diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetter.java deleted file mode 100644 index 5dfae10392f..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetter.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.propagation; - -import io.opentelemetry.context.propagation.TextMapGetter; -import java.util.Collections; -import java.util.Locale; -import java.util.Map; -import javax.annotation.Nullable; - -/** - * A {@link TextMapGetter} that extracts context from a map carrier, intended for use with - * environment variables. - * - *

Standard environment variable names are uppercase (e.g., {@code TRACEPARENT}, {@code - * TRACESTATE}, {@code BAGGAGE}). This getter translates keys to uppercase before looking them up in - * the carrier. - */ -public enum EnvironmentGetter implements TextMapGetter> { - INSTANCE; - - @Override - public Iterable keys(Map carrier) { - if (carrier == null) { - return Collections.emptyList(); - } - return carrier.keySet(); - } - - @Nullable - @Override - public String get(@Nullable Map carrier, String key) { - if (carrier == null || key == null) { - return null; - } - // Spec recommends using uppercase for environment variable names. - return carrier.get(key.toUpperCase(Locale.ROOT)); - } - - @Override - public String toString() { - return "EnvironmentGetter"; - } -} diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetter.java deleted file mode 100644 index bc94a12af23..00000000000 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetter.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.propagation; - -import io.opentelemetry.context.propagation.TextMapSetter; -import java.util.Locale; -import java.util.Map; -import javax.annotation.Nullable; - -/** - * A {@link TextMapSetter} that injects context into a map carrier, intended for use with - * environment variables. - * - *

Standard environment variable names are uppercase (e.g., {@code TRACEPARENT}, {@code - * TRACESTATE}, {@code BAGGAGE}). This setter translates keys to uppercase before inserting them - * into the carrier. - */ -public enum EnvironmentSetter implements TextMapSetter> { - INSTANCE; - - @Override - public void set(@Nullable Map carrier, String key, String value) { - if (carrier == null || key == null || value == null) { - return; - } - // Spec recommends using uppercase for environment variable names. - carrier.put(key.toUpperCase(Locale.ROOT), value); - } - - @Override - public String toString() { - return "EnvironmentSetter"; - } -} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetterTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetterTest.java deleted file mode 100644 index 0370beb885b..00000000000 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentGetterTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.propagation; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import org.junit.jupiter.api.Test; - -class EnvironmentGetterTest { - - @Test - void get() { - Map carrier = new HashMap<>(); - carrier.put("TRACEPARENT", "val1"); - carrier.put("TRACESTATE", "val2"); - carrier.put("BAGGAGE", "val3"); - carrier.put("OTHER", "val4"); - - assertThat(EnvironmentGetter.INSTANCE.get(carrier, "traceparent")).isEqualTo("val1"); - assertThat(EnvironmentGetter.INSTANCE.get(carrier, "TRACESTATE")).isEqualTo("val2"); - assertThat(EnvironmentGetter.INSTANCE.get(carrier, "Baggage")).isEqualTo("val3"); - assertThat(EnvironmentGetter.INSTANCE.get(carrier, "other")).isEqualTo("val4"); - } - - @Test - void get_null() { - assertThat(EnvironmentGetter.INSTANCE.get(null, "key")).isNull(); - assertThat(EnvironmentGetter.INSTANCE.get(Collections.emptyMap(), null)).isNull(); - } - - @Test - void keys() { - Map carrier = new HashMap<>(); - carrier.put("K1", "V1"); - carrier.put("K2", "V2"); - - assertThat(EnvironmentGetter.INSTANCE.keys(carrier)).containsExactlyInAnyOrder("K1", "K2"); - assertThat(EnvironmentGetter.INSTANCE.keys(null)).isEmpty(); - } - - @Test - void testToString() { - assertThat(EnvironmentGetter.INSTANCE.toString()).isEqualTo("EnvironmentGetter"); - } -} diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetterTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetterTest.java deleted file mode 100644 index 02308a7b544..00000000000 --- a/api/incubator/src/test/java/io/opentelemetry/api/incubator/propagation/EnvironmentSetterTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.api.incubator.propagation; - -import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; - -import java.util.HashMap; -import java.util.Map; -import org.junit.jupiter.api.Test; - -class EnvironmentSetterTest { - - @Test - void set() { - Map carrier = new HashMap<>(); - EnvironmentSetter.INSTANCE.set(carrier, "traceparent", "val1"); - EnvironmentSetter.INSTANCE.set(carrier, "TRACESTATE", "val2"); - EnvironmentSetter.INSTANCE.set(carrier, "Baggage", "val3"); - - assertThat(carrier).containsEntry("TRACEPARENT", "val1"); - assertThat(carrier).containsEntry("TRACESTATE", "val2"); - assertThat(carrier).containsEntry("BAGGAGE", "val3"); - } - - @Test - void set_null() { - Map carrier = new HashMap<>(); - EnvironmentSetter.INSTANCE.set(null, "key", "val"); - EnvironmentSetter.INSTANCE.set(carrier, null, "val"); - EnvironmentSetter.INSTANCE.set(carrier, "key", null); - assertThat(carrier).isEmpty(); - } - - @Test - void testToString() { - assertThat(EnvironmentSetter.INSTANCE.toString()).isEqualTo("EnvironmentSetter"); - } -} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java index 3207bc36279..3a1c557b509 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java @@ -156,18 +156,21 @@ private static boolean isMap(Object object) { @Nullable @Override public String getString(String name) { + Objects.requireNonNull(name, "name"); return stringOrNull(simpleEntries.get(name), name); } @Nullable @Override public Boolean getBoolean(String name) { + Objects.requireNonNull(name, "name"); return booleanOrNull(simpleEntries.get(name), name); } @Nullable @Override public Integer getInt(String name) { + Objects.requireNonNull(name, "name"); Object value = simpleEntries.get(name); if (value instanceof Integer) { return (Integer) value; @@ -184,12 +187,14 @@ public Integer getInt(String name) { @Nullable @Override public Long getLong(String name) { + Objects.requireNonNull(name, "name"); return longOrNull(simpleEntries.get(name), name); } @Nullable @Override public Double getDouble(String name) { + Objects.requireNonNull(name, "name"); return doubleOrNull(simpleEntries.get(name), name); } @@ -197,6 +202,7 @@ public Double getDouble(String name) { @Override @SuppressWarnings("unchecked") public List getScalarList(String name, Class scalarType) { + Objects.requireNonNull(name, "name"); if (!SUPPORTED_SCALAR_TYPES.contains(scalarType)) { throw new DeclarativeConfigException( "Unsupported scalar type " @@ -291,12 +297,14 @@ private static Double doubleOrNull(@Nullable Object value, String name) { @Nullable @Override public DeclarativeConfigProperties getStructured(String name) { + Objects.requireNonNull(name, "name"); return mapEntries.get(name); } @Nullable @Override public List getStructuredList(String name) { + Objects.requireNonNull(name, "name"); List value = listEntries.get(name); if (value != null) { return Collections.unmodifiableList(value); @@ -315,7 +323,8 @@ public Set getPropertyKeys() { @Override public String toString() { - StringJoiner joiner = new StringJoiner(", ", "YamlDeclarativeConfigProperties{", "}"); + StringJoiner joiner = + new StringJoiner(", ", YamlDeclarativeConfigProperties.class.getSimpleName() + "{", "}"); simpleEntries.forEach((key, value) -> joiner.add(key + "=" + value)); listEntries.forEach((key, value) -> joiner.add(key + "=" + value)); mapEntries.forEach((key, value) -> joiner.add(key + "=" + value)); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java index 18611e901d1..7e66e6a8933 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java @@ -130,7 +130,8 @@ void additionalProperties() { .isEqualTo(Arrays.asList(1.1d, 2.2d)); assertThat(otherProps.getScalarList("bool_list_key", Boolean.class)) .isEqualTo(Arrays.asList(true, false)); - // If reading a scalar list which is mixed, entries which are not aligned with the requested + // If reading a scalar list which is mixed, entries which are not aligned with + // the requested // type are filtered out assertThat(otherProps.getScalarList("mixed_list_key", String.class)) .isEqualTo(Collections.singletonList("val1")); @@ -231,6 +232,8 @@ void wrongType() { assertThat(otherProps.getBoolean("str_key")).isNull(); assertThat(otherProps.getScalarList("str_key", String.class)).isNull(); assertThat(otherProps.getScalarList("str_list_key", Long.class)).isNull(); + assertThat(otherProps.getScalarList("str_list_key", Boolean.class)).isNull(); + assertThat(otherProps.getScalarList("str_list_key", Double.class)).isNull(); assertThat(otherProps.getStructured("str_key")).isNull(); assertThat(otherProps.getStructuredList("str_key")).isNull(); assertThat(otherProps.getStructured("str_list_key")).isNull(); @@ -247,6 +250,24 @@ void wrongType() { "Ignoring value for key [str_list_key] because it is String instead of Long: val1"); } + @Test + void wrongTypeWithDefault() { + DeclarativeConfigProperties otherProps = structuredConfigProps.getStructured("other"); + assertThat(otherProps).isNotNull(); + + assertThat(otherProps.getString("int_key", "default")).isEqualTo("default"); + assertThat(otherProps.getInt("str_key", 100)).isEqualTo(100); + assertThat(otherProps.getLong("str_key", 100L)).isEqualTo(100L); + assertThat(otherProps.getDouble("str_key", 1.1)).isEqualTo(1.1); + assertThat(otherProps.getBoolean("str_key", true)).isTrue(); + assertThat( + otherProps.getScalarList("str_key", String.class, Collections.singletonList("default"))) + .isEqualTo(Collections.singletonList("default")); + assertThat(otherProps.getStructured("str_key", empty())).isEqualTo(empty()); + assertThat(otherProps.getStructuredList("str_key", Collections.emptyList())) + .isEqualTo(Collections.emptyList()); + } + private void assertWarning(String message) { logs.assertContains( e -> From 153c5d151789d170d7ce4a8ed86e62b4b2a5f3f8 Mon Sep 17 00:00:00 2001 From: Bhagirath00 Date: Wed, 18 Feb 2026 23:41:59 +0530 Subject: [PATCH 4/4] Improve null check messages for config property name and default value --- .../config/DeclarativeConfigProperties.java | 2 ++ .../YamlDeclarativeConfigProperties.java | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java index ac3cef17c99..c745e71ad2e 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java @@ -10,6 +10,7 @@ import io.opentelemetry.common.ComponentLoader; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import javax.annotation.Nullable; @@ -59,6 +60,7 @@ static Map toMap(DeclarativeConfigProperties declarativeConfigPr * {@code name} has not been configured or is not a valid scalar string */ default String getString(String name, String defaultValue) { + Objects.requireNonNull(defaultValue, "Null default value"); return defaultIfNull(getString(name), defaultValue); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java index 3a1c557b509..26b1d5177bc 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java @@ -156,21 +156,21 @@ private static boolean isMap(Object object) { @Nullable @Override public String getString(String name) { - Objects.requireNonNull(name, "name"); + Objects.requireNonNull(name, "Null configuration property name"); return stringOrNull(simpleEntries.get(name), name); } @Nullable @Override public Boolean getBoolean(String name) { - Objects.requireNonNull(name, "name"); + Objects.requireNonNull(name, "Null configuration property name"); return booleanOrNull(simpleEntries.get(name), name); } @Nullable @Override public Integer getInt(String name) { - Objects.requireNonNull(name, "name"); + Objects.requireNonNull(name, "Null configuration property name"); Object value = simpleEntries.get(name); if (value instanceof Integer) { return (Integer) value; @@ -187,14 +187,14 @@ public Integer getInt(String name) { @Nullable @Override public Long getLong(String name) { - Objects.requireNonNull(name, "name"); + Objects.requireNonNull(name, "Null configuration property name"); return longOrNull(simpleEntries.get(name), name); } @Nullable @Override public Double getDouble(String name) { - Objects.requireNonNull(name, "name"); + Objects.requireNonNull(name, "Null configuration property name"); return doubleOrNull(simpleEntries.get(name), name); } @@ -202,7 +202,7 @@ public Double getDouble(String name) { @Override @SuppressWarnings("unchecked") public List getScalarList(String name, Class scalarType) { - Objects.requireNonNull(name, "name"); + Objects.requireNonNull(name, "Null configuration property name"); if (!SUPPORTED_SCALAR_TYPES.contains(scalarType)) { throw new DeclarativeConfigException( "Unsupported scalar type " @@ -297,14 +297,14 @@ private static Double doubleOrNull(@Nullable Object value, String name) { @Nullable @Override public DeclarativeConfigProperties getStructured(String name) { - Objects.requireNonNull(name, "name"); + Objects.requireNonNull(name, "Null configuration property name"); return mapEntries.get(name); } @Nullable @Override public List getStructuredList(String name) { - Objects.requireNonNull(name, "name"); + Objects.requireNonNull(name, "Null configuration property name"); List value = listEntries.get(name); if (value != null) { return Collections.unmodifiableList(value);