diff --git a/common/src/main/java/io/opentelemetry/common/ComponentLoader.java b/common/src/main/java/io/opentelemetry/common/ComponentLoader.java index 17dab36a1b4..544bb8c0a11 100644 --- a/common/src/main/java/io/opentelemetry/common/ComponentLoader.java +++ b/common/src/main/java/io/opentelemetry/common/ComponentLoader.java @@ -5,6 +5,9 @@ package io.opentelemetry.common; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.ServiceLoader; /** A loader for components that are discovered via SPI. */ @@ -25,4 +28,10 @@ public interface ComponentLoader { static ComponentLoader forClassLoader(ClassLoader classLoader) { return new ServiceLoaderComponentLoader(classLoader); } + + static List loadList(ComponentLoader componentLoader, Class spiClass) { + List result = new ArrayList<>(); + componentLoader.load(spiClass).forEach(result::add); + return Collections.unmodifiableList(result); + } } diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-common.txt index c056765b54e..1b64811dceb 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-common.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-common.txt @@ -1,2 +1,5 @@ Comparing source compatibility of opentelemetry-common-1.61.0-SNAPSHOT.jar against opentelemetry-common-1.60.1.jar -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.common.ComponentLoader (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) java.util.List loadList(io.opentelemetry.common.ComponentLoader, java.lang.Class) + GENERIC TEMPLATES: +++ T:java.lang.Object diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index 8ce88c79daa..2ac0cd6186c 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,5 @@ Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.61.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.60.1.jar -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.autoconfigure.spi.Ordered (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) java.util.List loadOrderedList(io.opentelemetry.common.ComponentLoader, java.lang.Class) + GENERIC TEMPLATES: +++ T:io.opentelemetry.sdk.autoconfigure.spi.Ordered diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/Ordered.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/Ordered.java index 4df8464c424..a88b80cbf11 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/Ordered.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/Ordered.java @@ -5,6 +5,12 @@ package io.opentelemetry.sdk.autoconfigure.spi; +import io.opentelemetry.common.ComponentLoader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + /** * Interface to be extended by SPIs that need to guarantee ordering during loading. * @@ -20,4 +26,11 @@ public interface Ordered { default int order() { return 0; } + + static List loadOrderedList( + ComponentLoader componentLoader, Class spiClass) { + List result = new ArrayList<>(ComponentLoader.loadList(componentLoader, spiClass)); + result.sort(Comparator.comparing(Ordered::order)); + return Collections.unmodifiableList(result); + } } diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index f0f89f58886..8ef186ee14e 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { api(project(":sdk-extensions:autoconfigure-spi")) compileOnly(project(":api:incubator")) + compileOnly(project(":sdk-extensions:incubator")) annotationProcessor("com.google.auto.value:auto-value") diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResource.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResource.java new file mode 100644 index 00000000000..67372de748b --- /dev/null +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResource.java @@ -0,0 +1,106 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.resources.Resource; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +/** + * Creates an OpenTelemetry {@link Resource} from environment configuration. + * + *

This class is intentionally self-contained (no dependencies on other autoconfigure-internal + * classes) so that it can be copied wholesale into declarative configuration without pulling in + * additional dependencies. Do not add dependencies on non-API, non-SPI classes. + */ +final class EnvironmentResource { + + private static final AttributeKey SERVICE_NAME = AttributeKey.stringKey("service.name"); + + // Visible for testing + static final String ATTRIBUTE_PROPERTY = "otel.resource.attributes"; + static final String SERVICE_NAME_PROPERTY = "otel.service.name"; + + /** + * Create a {@link Resource} from the environment. The resource contains attributes parsed from + * environment variables and system property keys {@code otel.resource.attributes} and {@code + * otel.service.name}. + * + * @param config the {@link ConfigProperties} used to obtain resource properties + * @return the resource. + */ + @SuppressWarnings("JdkObsolete") // Recommended alternative was introduced in java 10 + static Resource createEnvironmentResource(ConfigProperties config) { + AttributesBuilder resourceAttributes = Attributes.builder(); + for (Map.Entry entry : config.getMap(ATTRIBUTE_PROPERTY).entrySet()) { + resourceAttributes.put( + entry.getKey(), + // Attributes specified via otel.resource.attributes follow the W3C Baggage spec and + // characters outside the baggage-octet range are percent encoded + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#specifying-resource-information-via-an-environment-variable + decodeResourceAttributes(entry.getValue())); + } + String serviceName = config.getString(SERVICE_NAME_PROPERTY); + if (serviceName != null) { + resourceAttributes.put(SERVICE_NAME, serviceName); + } + + return Resource.create(resourceAttributes.build()); + } + + /** + * Decodes percent-encoded characters in resource attribute values per W3C Baggage spec. + * + *

Unlike {@link java.net.URLDecoder}, this method: + * + *

    + *
  • Preserves '+' as a literal plus sign (URLDecoder decodes '+' as space) + *
  • Preserves invalid percent sequences as literals (e.g., "%2G", "%", "%2") + *
  • Supports multi-byte UTF-8 sequences (e.g., "%C3%A9" decodes to "é") + *
+ * + * @param value the percent-encoded string + * @return the decoded string + */ + private static String decodeResourceAttributes(String value) { + // no percent signs means nothing to decode + if (value.indexOf('%') < 0) { + return value; + } + + int n = value.length(); + // Use byte array to properly handle multi-byte UTF-8 sequences + byte[] bytes = new byte[n]; + int pos = 0; + + for (int i = 0; i < n; i++) { + char c = value.charAt(i); + // Check for percent-encoded sequence i.e. '%' followed by two hex digits + if (c == '%' && i + 2 < n) { + int d1 = Character.digit(value.charAt(i + 1), 16); + int d2 = Character.digit(value.charAt(i + 2), 16); + // Valid hex digits return 0-15, invalid returns -1 + if (d1 != -1 && d2 != -1) { + // Combine two hex digits into a single byte (e.g., "2F" becomes 0x2F) + bytes[pos++] = (byte) ((d1 << 4) + d2); + // Skip the two hex digits (loop will also do i++) + i += 2; + continue; + } + } + // Keep '+' as '+' (unlike URLDecoder) and preserve invalid percent sequences which will be + // treated as literals + bytes[pos++] = (byte) c; + } + return new String(bytes, 0, pos, StandardCharsets.UTF_8); + } + + private EnvironmentResource() {} +} diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java index 85c22c49324..b93215e4cab 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java @@ -9,15 +9,18 @@ import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.internal.ExtendedOpenTelemetrySdk; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState; import io.opentelemetry.sdk.resources.Resource; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; +import java.lang.reflect.Field; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -32,30 +35,14 @@ final class IncubatingUtil { private IncubatingUtil() {} - // Visible for testing - interface Factory { - @Nullable - AutoConfiguredOpenTelemetrySdk create() - throws ClassNotFoundException, - NoSuchMethodException, - IllegalAccessException, - InvocationTargetException; - } - static AutoConfiguredOpenTelemetrySdk configureFromFile( Logger logger, String configurationFile, ComponentLoader componentLoader) { logger.fine("Autoconfiguring from configuration file: " + configurationFile); try (FileInputStream fis = new FileInputStream(configurationFile)) { - return requireNonNull( - createWithFactory( - "file", - () -> - getOpenTelemetrySdk( - Class.forName( - "io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration") - .getMethod("parse", InputStream.class) - .invoke(null, fis), - componentLoader))); + OpenTelemetryConfigurationModel model = DeclarativeConfiguration.parse(fis); + return create(model, componentLoader); + } catch (DeclarativeConfigException e) { + throw toConfigurationException(e); } catch (FileNotFoundException e) { throw new ConfigurationException("Configuration file not found", e); } catch (IOException e) { @@ -67,75 +54,34 @@ static AutoConfiguredOpenTelemetrySdk configureFromFile( @Nullable public static AutoConfiguredOpenTelemetrySdk configureFromSpi(ComponentLoader componentLoader) { - return createWithFactory( - "SPI", - () -> { - Class providerClass = - Class.forName( - "io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationProvider"); - Method getConfigurationModel = providerClass.getMethod("getConfigurationModel"); - - for (Object configProvider : componentLoader.load(providerClass)) { - Object model = getConfigurationModel.invoke(configProvider); - if (model != null) { - return getOpenTelemetrySdk(model, componentLoader); - } - } - return null; - }); + for (DeclarativeConfigurationProvider provider : + componentLoader.load(DeclarativeConfigurationProvider.class)) { + OpenTelemetryConfigurationModel model = provider.getConfigurationModel(); + if (model != null) { + return create(model, componentLoader); + } + } + return null; } - private static AutoConfiguredOpenTelemetrySdk getOpenTelemetrySdk( - Object model, ComponentLoader componentLoader) - throws IllegalAccessException, - InvocationTargetException, - ClassNotFoundException, - NoSuchMethodException { - - Class openTelemetryConfiguration = - Class.forName( - "io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel"); - Class declarativeConfiguration = - Class.forName( - "io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration"); - - Class contextClass = - Class.forName( - "io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigContext"); - Method createContext = contextClass.getDeclaredMethod("create", ComponentLoader.class); - createContext.setAccessible(true); - Object context = createContext.invoke(null, componentLoader); - - Method create = - declarativeConfiguration.getDeclaredMethod( - "create", openTelemetryConfiguration, contextClass); - create.setAccessible(true); - OpenTelemetrySdk sdk = (OpenTelemetrySdk) create.invoke(null, model, context); - - Method getResource = contextClass.getDeclaredMethod("getResource"); - getResource.setAccessible(true); - Resource resource = (Resource) getResource.invoke(context); - - return AutoConfiguredOpenTelemetrySdk.create(sdk, resource, null); - } + private static AutoConfiguredOpenTelemetrySdk create( + OpenTelemetryConfigurationModel model, ComponentLoader componentLoader) { + ExtendedOpenTelemetrySdk sdk; + try { + sdk = DeclarativeConfiguration.create(model, componentLoader); + } catch (DeclarativeConfigException e) { + throw toConfigurationException(e); + } - // Visible for testing - @Nullable - static AutoConfiguredOpenTelemetrySdk createWithFactory(String name, Factory factory) { try { - return factory.create(); - } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { - throw new ConfigurationException( - String.format( - "Error configuring from %s. Is opentelemetry-sdk-extension-incubator on the classpath?", - name), - e); - } catch (InvocationTargetException e) { - Throwable cause = e.getCause(); - if (cause instanceof DeclarativeConfigException) { - throw toConfigurationException((DeclarativeConfigException) cause); - } - throw new ConfigurationException("Unexpected error configuring from " + name, e); + Field sharedState = SdkMeterProvider.class.getDeclaredField("sharedState"); + sharedState.setAccessible(true); + Resource resource = + ((MeterProviderSharedState) sharedState.get(sdk.getSdkMeterProvider())).getResource(); + + return AutoConfiguredOpenTelemetrySdk.create(sdk, resource, null); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new ConfigurationException("Error resolving resource from ExtendedOpenTelemetrySdk", e); } } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java index 30bd30bdf6c..9f1a1c4d03c 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java @@ -5,9 +5,6 @@ package io.opentelemetry.sdk.autoconfigure; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; @@ -16,11 +13,9 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.resources.ResourceBuilder; -import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.function.BiFunction; @@ -31,11 +26,7 @@ */ public final class ResourceConfiguration { - private static final AttributeKey SERVICE_NAME = AttributeKey.stringKey("service.name"); - // Visible for testing - static final String ATTRIBUTE_PROPERTY = "otel.resource.attributes"; - static final String SERVICE_NAME_PROPERTY = "otel.service.name"; static final String DISABLED_ATTRIBUTE_KEYS = "otel.resource.disabled.keys"; static final String ENABLED_RESOURCE_PROVIDERS = "otel.java.enabled.resource.providers"; static final String DISABLED_RESOURCE_PROVIDERS = "otel.java.disabled.resource.providers"; @@ -62,23 +53,8 @@ public static Resource createEnvironmentResource() { * @param config the {@link ConfigProperties} used to obtain resource properties * @return the resource. */ - @SuppressWarnings("JdkObsolete") // Recommended alternative was introduced in java 10 public static Resource createEnvironmentResource(ConfigProperties config) { - AttributesBuilder resourceAttributes = Attributes.builder(); - for (Map.Entry entry : config.getMap(ATTRIBUTE_PROPERTY).entrySet()) { - resourceAttributes.put( - entry.getKey(), - // Attributes specified via otel.resource.attributes follow the W3C Baggage spec and - // characters outside the baggage-octet range are percent encoded - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#specifying-resource-information-via-an-environment-variable - decodeResourceAttributes(entry.getValue())); - } - String serviceName = config.getString(SERVICE_NAME_PROPERTY); - if (serviceName != null) { - resourceAttributes.put(SERVICE_NAME, serviceName); - } - - return Resource.create(resourceAttributes.build()); + return EnvironmentResource.createEnvironmentResource(config); } static Resource configureResource( @@ -125,52 +101,5 @@ static Resource filterAttributes(Resource resource, ConfigProperties configPrope return builder.build(); } - /** - * Decodes percent-encoded characters in resource attribute values per W3C Baggage spec. - * - *

Unlike {@link java.net.URLDecoder}, this method: - * - *

    - *
  • Preserves '+' as a literal plus sign (URLDecoder decodes '+' as space) - *
  • Preserves invalid percent sequences as literals (e.g., "%2G", "%", "%2") - *
  • Supports multi-byte UTF-8 sequences (e.g., "%C3%A9" decodes to "é") - *
- * - * @param value the percent-encoded string - * @return the decoded string - */ - private static String decodeResourceAttributes(String value) { - // no percent signs means nothing to decode - if (value.indexOf('%') < 0) { - return value; - } - - int n = value.length(); - // Use byte array to properly handle multi-byte UTF-8 sequences - byte[] bytes = new byte[n]; - int pos = 0; - - for (int i = 0; i < n; i++) { - char c = value.charAt(i); - // Check for percent-encoded sequence i.e. '%' followed by two hex digits - if (c == '%' && i + 2 < n) { - int d1 = Character.digit(value.charAt(i + 1), 16); - int d2 = Character.digit(value.charAt(i + 2), 16); - // Valid hex digits return 0-15, invalid returns -1 - if (d1 != -1 && d2 != -1) { - // Combine two hex digits into a single byte (e.g., "2F" becomes 0x2F) - bytes[pos++] = (byte) ((d1 << 4) + d2); - // Skip the two hex digits (loop will also do i++) - i += 2; - continue; - } - } - // Keep '+' as '+' (unlike URLDecoder) and preserve invalid percent sequences which will be - // treated as literals - bytes[pos++] = (byte) c; - } - return new String(bytes, 0, pos, StandardCharsets.UTF_8); - } - private ResourceConfiguration() {} } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java index d1d00aed571..96107c11ff3 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java @@ -9,9 +9,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; -import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.IdentityHashMap; import java.util.List; @@ -74,7 +72,7 @@ public NamedSpiManager loadConfigurable( name, () -> { T result = getConfigurable.apply(provider, config); - maybeAddListener(result); + maybeAddListener(Collections.singletonList(result)); return result; }); } @@ -89,8 +87,8 @@ public NamedSpiManager loadConfigurable( * @return list of SPI implementations, in order */ public List loadOrdered(Class spiClass) { - List result = load(spiClass); - result.sort(Comparator.comparing(Ordered::order)); + List result = Ordered.loadOrderedList(componentLoader, spiClass); + maybeAddListener(result); return result; } @@ -102,17 +100,16 @@ public List loadOrdered(Class spiClass) { * @return list of SPI implementations */ public List load(Class spiClass) { - List result = new ArrayList<>(); - for (T service : componentLoader.load(spiClass)) { - maybeAddListener(service); - result.add(service); - } + List result = ComponentLoader.loadList(componentLoader, spiClass); + maybeAddListener(result); return result; } - private void maybeAddListener(Object object) { - if (object instanceof AutoConfigureListener) { - listeners.add((AutoConfigureListener) object); + private void maybeAddListener(List objects) { + for (Object object : objects) { + if (object instanceof AutoConfigureListener) { + listeners.add((AutoConfigureListener) object); + } } } diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationFuzzTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationFuzzTest.java index 8165d24eb90..5fd36956189 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationFuzzTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationFuzzTest.java @@ -33,7 +33,7 @@ public void getAttributesWithRandomValues(String value1, String value2) { ResourceConfiguration.createEnvironmentResource( DefaultConfigProperties.createFromMap( singletonMap( - ResourceConfiguration.ATTRIBUTE_PROPERTY, + "otel.resource.attributes", "key1=" + escaper.escape(value1) + ",key2=" + escaper.escape(value2)))) .getAttributes(); diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java index d116bdbf37d..b07f7c98f20 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java @@ -97,8 +97,7 @@ void createEnvironmentResource_WithResourceAttributes() { ResourceConfiguration.createEnvironmentResource( DefaultConfigProperties.createFromMap( singletonMap( - ResourceConfiguration.ATTRIBUTE_PROPERTY, - "service.name=myService,appName=MyApp"))) + "otel.resource.attributes", "service.name=myService,appName=MyApp"))) .getAttributes(); assertThat(attributes) @@ -112,7 +111,7 @@ void createEnvironmentResource_WithServiceName() { Attributes attributes = ResourceConfiguration.createEnvironmentResource( DefaultConfigProperties.createFromMap( - singletonMap(ResourceConfiguration.SERVICE_NAME_PROPERTY, "myService"))) + singletonMap("otel.service.name", "myService"))) .getAttributes(); assertThat(attributes).hasSize(1).containsEntry(stringKey("service.name"), "myService"); @@ -124,9 +123,9 @@ void createEnvironmentResource_ServiceNamePriority() { ResourceConfiguration.createEnvironmentResource( DefaultConfigProperties.createFromMap( ImmutableMap.of( - ResourceConfiguration.ATTRIBUTE_PROPERTY, + "otel.resource.attributes", "service.name=myService,appName=MyApp", - ResourceConfiguration.SERVICE_NAME_PROPERTY, + "otel.service.name", "ReallyMyService"))) .getAttributes(); @@ -140,8 +139,7 @@ void createEnvironmentResource_ServiceNamePriority() { void createEnvironmentResource_EmptyResourceAttributes() { Attributes attributes = ResourceConfiguration.createEnvironmentResource( - DefaultConfigProperties.createFromMap( - singletonMap(ResourceConfiguration.ATTRIBUTE_PROPERTY, ""))) + DefaultConfigProperties.createFromMap(singletonMap("otel.resource.attributes", ""))) .getAttributes(); assertThat(attributes).isEmpty(); diff --git a/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationSpiTest.java b/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationSpiTest.java index 314fa4666b9..56653dda289 100644 --- a/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationSpiTest.java +++ b/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationSpiTest.java @@ -16,6 +16,8 @@ import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.internal.OpenTelemetrySdkBuilderUtil; import io.opentelemetry.sdk.internal.SdkConfigProvider; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; @@ -28,15 +30,15 @@ class DeclarativeConfigurationSpiTest { @Test void configFromSpi() { + Resource resource = Resource.getDefault().toBuilder().put("service.name", "test").build(); OpenTelemetrySdk expectedSdk = OpenTelemetrySdkBuilderUtil.setConfigProvider( OpenTelemetrySdk.builder() + .setMeterProvider(SdkMeterProvider.builder().setResource(resource).build()) + .setLoggerProvider(SdkLoggerProvider.builder().setResource(resource).build()) .setTracerProvider( SdkTracerProvider.builder() - .setResource( - Resource.getDefault().toBuilder() - .put("service.name", "test") - .build()) + .setResource(resource) .addSpanProcessor( SimpleSpanProcessor.create(LoggingSpanExporter.create())) .build()), diff --git a/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtilTest.java b/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtilTest.java deleted file mode 100644 index 12cb8274ed8..00000000000 --- a/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtilTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.sdk.autoconfigure; - -import static org.assertj.core.api.Assertions.assertThatCode; - -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; -import java.lang.reflect.InvocationTargetException; -import org.junit.jupiter.api.Test; - -class IncubatingUtilTest { - - @Test - void classNotFoundException() { - assertThatCode( - () -> - IncubatingUtil.createWithFactory( - "test", - () -> { - Class.forName("foo"); - return null; - })) - .isInstanceOf(ConfigurationException.class) - .hasMessage( - "Error configuring from test. Is opentelemetry-sdk-extension-incubator on the classpath?"); - } - - @Test - void invocationTargetException() { - assertThatCode( - () -> - IncubatingUtil.createWithFactory( - "test", - () -> { - throw new InvocationTargetException(new RuntimeException("test exception")); - })) - .isInstanceOf(ConfigurationException.class) - .hasMessage("Unexpected error configuring from test") - .hasRootCauseMessage("test exception"); - } -} diff --git a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java index c8e6246f8ac..64d3b68ef15 100644 --- a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java @@ -31,6 +31,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.internal.ExtendedOpenTelemetrySdk; import io.opentelemetry.sdk.internal.OpenTelemetrySdkBuilderUtil; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; @@ -126,6 +128,8 @@ void configFile_Valid() { OpenTelemetrySdk expectedSdk = OpenTelemetrySdkBuilderUtil.setConfigProvider( OpenTelemetrySdk.builder() + .setMeterProvider(SdkMeterProvider.builder().setResource(resource).build()) + .setLoggerProvider(SdkLoggerProvider.builder().setResource(resource).build()) .setTracerProvider( SdkTracerProvider.builder() .setResource(resource) diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 9719202acff..d6b686fb0be 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -30,7 +30,6 @@ dependencies { implementation("com.fasterxml.jackson.core:jackson-databind") api("com.fasterxml.jackson.core:jackson-annotations") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml") - implementation(project(":sdk-extensions:autoconfigure")) testImplementation(project(":sdk:testing")) testImplementation(project(":sdk-extensions:autoconfigure")) @@ -149,6 +148,35 @@ val deleteJs2pTmp by tasks.registering(Delete::class) { delete("$buildDirectory/generated/sources/js2p-tmp/") } +// Copies EnvironmentResource.java from the autoconfigure module into a generated source set so +// that the incubator can use the exact same source without taking a runtime dependency on +// autoconfigure and without the risk of divergence from manual syncing. +val generatedResourceConfigDir = + layout.buildDirectory.dir("generated/sources/resource-configuration/java/main") +val copyResourceConfiguration by tasks.registering(Copy::class) { + from( + project(":sdk-extensions:autoconfigure").file( + "src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResource.java" + ) + ) + into(generatedResourceConfigDir.map { it.dir("io/opentelemetry/extension/incubator/fileconfig") }) + // Only the package declaration needs rewriting; everything else is copied verbatim. + filter { line: String -> + line.replace( + "package io.opentelemetry.sdk.autoconfigure;", + "package io.opentelemetry.sdk.extension.incubator.fileconfig;" + ) + } +} + +sourceSets { + main { + java { + srcDir(generatedResourceConfigDir) + } + } +} + val buildGraalVmReflectionJson = tasks.register("buildGraalVmReflectionJson") { val buildDir = buildDirectory val targetFile = File( @@ -205,8 +233,8 @@ val buildGraalVmReflectionJson = tasks.register("buildGraalVmReflectionJson") { } } -tasks.getByName("compileJava").dependsOn(deleteJs2pTmp) -tasks.getByName("sourcesJar").dependsOn(deleteJs2pTmp, buildGraalVmReflectionJson) +tasks.getByName("compileJava").dependsOn(deleteJs2pTmp, copyResourceConfiguration) +tasks.getByName("sourcesJar").dependsOn(deleteJs2pTmp, buildGraalVmReflectionJson, copyResourceConfiguration) tasks.getByName("jar").dependsOn(deleteJs2pTmp, buildGraalVmReflectionJson) tasks.getByName("javadoc").dependsOn(buildGraalVmReflectionJson) tasks.getByName("compileTestJava").dependsOn(buildGraalVmReflectionJson) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java index 663cf374b6d..f6136a240f4 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java @@ -10,14 +10,14 @@ import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedDeclarativeConfigProperties; import io.opentelemetry.sdk.common.InternalTelemetryVersion; -import io.opentelemetry.sdk.resources.Resource; import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; +import java.util.IdentityHashMap; import java.util.List; import java.util.Locale; import java.util.Objects; @@ -27,24 +27,31 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; -/** Declarative configuration context and state carrier. */ -class DeclarativeConfigContext { +/** + * Declarative configuration context and state carrier. + * + *

This implements {@link ComponentLoader} with an implementation which delegates to an + * underlying instance while tracking instances which implement {@link AutoConfigureListener}, + * accessible via {@link #getListeners()}. + */ +class DeclarativeConfigContext implements ComponentLoader { - private final SpiHelper spiHelper; + private final ComponentLoader componentLoader; + private final Set listeners = + Collections.newSetFromMap(new IdentityHashMap<>()); private final List closeables = new ArrayList<>(); @Nullable private volatile MeterProvider meterProvider; - @Nullable private Resource resource = null; @Nullable private ConfigProvider configProvider; @Nullable private List componentProviders = null; @Nullable private DeclarativeConfigurationBuilder builder; - // Visible for testing - DeclarativeConfigContext(SpiHelper spiHelper) { - this.spiHelper = spiHelper; + DeclarativeConfigContext(ComponentLoader componentLoader) { + this.componentLoader = componentLoader; } - static DeclarativeConfigContext create(ComponentLoader componentLoader) { - return new DeclarativeConfigContext(SpiHelper.create(componentLoader)); + /** Return the underlying component loader. */ + ComponentLoader getDelegateComponentLoader() { + return componentLoader; } /** @@ -68,18 +75,6 @@ public void setConfigProvider(ConfigProvider configProvider) { this.configProvider = configProvider; } - Resource getResource() { - // called via reflection from io.opentelemetry.sdk.autoconfigure.IncubatingUtil - if (resource == null) { - throw new DeclarativeConfigException("Resource has not been configured yet."); - } - return resource; - } - - void setResource(Resource resource) { - this.resource = resource; - } - void setBuilder(DeclarativeConfigurationBuilder builder) { this.builder = builder; } @@ -136,10 +131,6 @@ private InternalTelemetryVersion getInternalTelemetryVersion() { } } - SpiHelper getSpiHelper() { - return spiHelper; - } - /** * Find a registered {@link ComponentProvider} with {@link ComponentProvider#getType()} matching * {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link @@ -157,7 +148,7 @@ T loadComponent(Class type, ConfigKeyValue configKeyValue) { configProvider == null ? ConfigProvider.noop() : configProvider); if (componentProviders == null) { - componentProviders = spiHelper.load(ComponentProvider.class); + componentProviders = ComponentLoader.loadList(this, ComponentProvider.class); } List matchedProviders = componentProviders.stream() @@ -206,6 +197,22 @@ T loadComponent(Class type, ConfigKeyValue configKeyValue) { } } + @Override + public Iterable load(Class spiClass) { + List result = ComponentLoader.loadList(componentLoader, spiClass); + result.forEach( + entry -> { + if (entry instanceof AutoConfigureListener) { + listeners.add((AutoConfigureListener) entry); + } + }); + return result; + } + + Set getListeners() { + return Collections.unmodifiableSet(listeners); + } + private static class ExtendedDeclarativeConfigPropertiesImpl implements ExtendedDeclarativeConfigProperties { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java index 6d351386e1d..7d49067d48e 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java @@ -13,7 +13,7 @@ import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; @@ -154,7 +154,7 @@ public static ExtendedOpenTelemetrySdk create( */ public static ExtendedOpenTelemetrySdk create( OpenTelemetryConfigurationModel configurationModel, ComponentLoader componentLoader) { - return create(configurationModel, DeclarativeConfigContext.create(componentLoader)); + return create(configurationModel, new DeclarativeConfigContext(componentLoader)); } private static ExtendedOpenTelemetrySdk create( @@ -162,9 +162,8 @@ private static ExtendedOpenTelemetrySdk create( DeclarativeConfigurationBuilder builder = new DeclarativeConfigurationBuilder(); context.setBuilder(builder); - SpiHelper spiHelper = context.getSpiHelper(); for (DeclarativeConfigurationCustomizerProvider provider : - spiHelper.loadOrdered(DeclarativeConfigurationCustomizerProvider.class)) { + Ordered.loadOrderedList(context, DeclarativeConfigurationCustomizerProvider.class)) { provider.customize(builder); } @@ -173,7 +172,7 @@ private static ExtendedOpenTelemetrySdk create( OpenTelemetryConfigurationFactory.getInstance(), context, builder.customizeModel(configurationModel)); - callAutoConfigureListeners(spiHelper, sdk); + callAutoConfigureListeners(context, sdk); return sdk; } @@ -263,7 +262,7 @@ public static Sampler createSampler(DeclarativeConfigProperties genericSamplerMo DeclarativeConfigProperties.toMap(yamlDeclarativeConfigProperties), SamplerModel.class); return createAndMaybeCleanup( SamplerFactory.getInstance(), - DeclarativeConfigContext.create(yamlDeclarativeConfigProperties.getComponentLoader()), + new DeclarativeConfigContext(yamlDeclarativeConfigProperties.getComponentLoader()), samplerModel); } @@ -485,8 +484,9 @@ private StringBuilder envVarSubstitution( } // Visible for testing - static void callAutoConfigureListeners(SpiHelper spiHelper, OpenTelemetrySdk openTelemetrySdk) { - for (AutoConfigureListener listener : spiHelper.getListeners()) { + static void callAutoConfigureListeners( + DeclarativeConfigContext context, OpenTelemetrySdk openTelemetrySdk) { + for (AutoConfigureListener listener : context.getListeners()) { try { listener.afterAutoConfigure(openTelemetrySdk); } catch (Throwable throwable) { diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java index e2968ac6337..7496240990f 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/FileConfigUtil.java @@ -26,8 +26,7 @@ static T requireNonNull(@Nullable T object, String description) { static ConfigKeyValue validateSingleKeyValue( DeclarativeConfigContext context, Object model, String resourceName) { DeclarativeConfigProperties modelConfigProperties = - DeclarativeConfiguration.toConfigProperties( - model, context.getSpiHelper().getComponentLoader()); + DeclarativeConfiguration.toConfigProperties(model, context); Set propertyKeys = modelConfigProperties.getPropertyKeys(); if (propertyKeys.size() != 1) { String suffix = diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java index 603a39512a9..6c7f689a921 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java @@ -9,7 +9,10 @@ import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.OpenTelemetrySdkBuilder; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; import io.opentelemetry.sdk.internal.ExtendedOpenTelemetrySdk; import io.opentelemetry.sdk.internal.OpenTelemetrySdkBuilderUtil; import io.opentelemetry.sdk.internal.SdkConfigProvider; @@ -40,8 +43,7 @@ static OpenTelemetryConfigurationFactory getInstance() { public ExtendedOpenTelemetrySdk create( OpenTelemetryConfigurationModel model, DeclarativeConfigContext context) { DeclarativeConfigProperties modelProperties = - DeclarativeConfiguration.toConfigProperties( - model, context.getSpiHelper().getComponentLoader()); + DeclarativeConfiguration.toConfigProperties(model, context.getDelegateComponentLoader()); SdkConfigProvider sdkConfigProvider = SdkConfigProvider.create(modelProperties); context.setConfigProvider(sdkConfigProvider); OpenTelemetrySdkBuilder builder = @@ -74,41 +76,46 @@ public ExtendedOpenTelemetrySdk create( if (model.getResource() != null) { resource = ResourceFactory.getInstance().create(model.getResource(), context); } - context.setResource(resource); - if (model.getMeterProvider() != null) { - SdkMeterProvider meterProvider = - MeterProviderFactory.getInstance() - .create(model.getMeterProvider(), context) - .setResource(resource) - .build(); - context.setMeterProvider(meterProvider); - builder.setMeterProvider(context.addCloseable(meterProvider)); + MeterProviderModel meterProviderModel = model.getMeterProvider(); + if (meterProviderModel == null) { + meterProviderModel = new MeterProviderModel(); } + SdkMeterProvider meterProvider = + MeterProviderFactory.getInstance() + .create(meterProviderModel, context) + .setResource(resource) + .build(); + context.setMeterProvider(meterProvider); + builder.setMeterProvider(context.addCloseable(meterProvider)); - if (model.getLoggerProvider() != null) { - builder.setLoggerProvider( - context.addCloseable( - LoggerProviderFactory.getInstance() - .create( - LoggerProviderAndAttributeLimits.create( - model.getAttributeLimits(), model.getLoggerProvider()), - context) - .setResource(resource) - .build())); + LoggerProviderModel loggerProviderModel = model.getLoggerProvider(); + if (loggerProviderModel == null) { + loggerProviderModel = new LoggerProviderModel(); } + builder.setLoggerProvider( + context.addCloseable( + LoggerProviderFactory.getInstance() + .create( + LoggerProviderAndAttributeLimits.create( + model.getAttributeLimits(), loggerProviderModel), + context) + .setResource(resource) + .build())); - if (model.getTracerProvider() != null) { - builder.setTracerProvider( - context.addCloseable( - TracerProviderFactory.getInstance() - .create( - TracerProviderAndAttributeLimits.create( - model.getAttributeLimits(), model.getTracerProvider()), - context) - .setResource(resource) - .build())); + TracerProviderModel tracerProviderModel = model.getTracerProvider(); + if (tracerProviderModel == null) { + tracerProviderModel = new TracerProviderModel(); } + builder.setTracerProvider( + context.addCloseable( + TracerProviderFactory.getInstance() + .create( + TracerProviderAndAttributeLimits.create( + model.getAttributeLimits(), tracerProviderModel), + context) + .setResource(resource) + .build())); return (ExtendedOpenTelemetrySdk) context.addCloseable(builder.build()); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java index 3f849c836af..1f82a1c1f5c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java @@ -5,8 +5,10 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import static io.opentelemetry.sdk.extension.incubator.fileconfig.EnvironmentResource.ATTRIBUTE_PROPERTY; +import static io.opentelemetry.sdk.extension.incubator.fileconfig.EnvironmentResource.createEnvironmentResource; + import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.sdk.autoconfigure.ResourceConfiguration; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.common.internal.IncludeExcludePredicate; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; @@ -60,9 +62,9 @@ public Resource create(ResourceModel model, DeclarativeConfigContext context) { String attributeList = model.getAttributesList(); if (attributeList != null) { builder.putAll( - ResourceConfiguration.createEnvironmentResource( + createEnvironmentResource( DefaultConfigProperties.createFromMap( - Collections.singletonMap("otel.resource.attributes", attributeList)))); + Collections.singletonMap(ATTRIBUTE_PROPERTY, attributeList)))); } List attributeNameValueModel = model.getAttributes(); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java index 8a8da213fd1..ef2961c5a2b 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java @@ -20,8 +20,8 @@ import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.common.internal.IncludeExcludePredicate; import io.opentelemetry.sdk.extension.incubator.fileconfig.ComposableRuleBasedSamplerFactory.AttributeMatcher; import io.opentelemetry.sdk.extension.incubator.fileconfig.ComposableRuleBasedSamplerFactory.DeclarativeConfigSamplingPredicate; @@ -48,7 +48,7 @@ class ComposableRuleBasedSamplerFactoryTest { private final DeclarativeConfigContext context = - new DeclarativeConfigContext(SpiHelper.create(SamplerFactoryTest.class.getClassLoader())); + new DeclarativeConfigContext(ComponentLoader.forClassLoader(getClass().getClassLoader())); @ParameterizedTest @MethodSource("createTestCases") diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContextTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContextTest.java index d317dbc6b3f..71b9df870df 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContextTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContextTest.java @@ -5,8 +5,6 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -14,7 +12,6 @@ import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.common.ComponentLoader; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.resources.Resource; import java.util.Collections; @@ -22,27 +19,12 @@ class DeclarativeConfigContextTest { - private final DeclarativeConfigContext context = - DeclarativeConfigContext.create( - ComponentLoader.forClassLoader(DeclarativeConfigContextTest.class.getClassLoader())); - - @Test - void resourceMustBeSetBeforeUse() { - assertThatCode(context::getResource).isInstanceOf(DeclarativeConfigException.class); - Resource resource = Resource.empty(); - context.setResource(resource); - assertThat(context.getResource()).isSameAs(resource); - } + private final ComponentLoader componentLoader = + spy(ComponentLoader.forClassLoader(getClass().getClassLoader())); + private final DeclarativeConfigContext context = new DeclarativeConfigContext(componentLoader); @Test void componentProvidersCached() { - SpiHelper spiHelper = - spy(SpiHelper.create(DeclarativeConfigContextTest.class.getClassLoader())); - DeclarativeConfigContext context = new DeclarativeConfigContext(spiHelper); - - ComponentLoader componentLoader = - ComponentLoader.forClassLoader(DeclarativeConfigContextTest.class.getClassLoader()); - // First loadComponent call should load providers assertThatThrownBy( () -> @@ -68,6 +50,6 @@ void componentProvidersCached() { .hasMessageContaining("No component provider detected"); // Verify spiHelper.load() was only called once - verify(spiHelper, times(1)).load(ComponentProvider.class); + verify(componentLoader, times(1)).load(ComponentProvider.class); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java index cc4b137da71..0391f2decb7 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java @@ -19,7 +19,6 @@ import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; @@ -194,8 +193,8 @@ void create_ModelCustomizer() { @Test @SuppressLogger(DeclarativeConfiguration.class) void callAutoConfigureListeners_exceptionIsCaught() { - SpiHelper spiHelper = mock(SpiHelper.class); - when(spiHelper.getListeners()) + DeclarativeConfigContext context = mock(DeclarativeConfigContext.class); + when(context.getListeners()) .thenReturn( Collections.singleton( sdk -> { @@ -205,7 +204,7 @@ void callAutoConfigureListeners_exceptionIsCaught() { assertThatCode( () -> DeclarativeConfiguration.callAutoConfigureListeners( - spiHelper, OpenTelemetrySdk.builder().build())) + context, OpenTelemetrySdk.builder().build())) .doesNotThrowAnyException(); } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java index 0894163e260..d9e67056f06 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java @@ -17,7 +17,6 @@ import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.internal.testing.CleanupExtension; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalOtlpFileExporterModel; @@ -54,14 +53,12 @@ class LogRecordExporterFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); private CapturingComponentLoader capturingComponentLoader; - private SpiHelper spiHelper; private DeclarativeConfigContext context; @BeforeEach void setup() { capturingComponentLoader = new CapturingComponentLoader(); - spiHelper = SpiHelper.create(capturingComponentLoader); - context = new DeclarativeConfigContext(spiHelper); + context = new DeclarativeConfigContext(capturingComponentLoader); context.setBuilder(new DeclarativeConfigurationBuilder()); } @@ -70,7 +67,7 @@ void create_OtlpHttpDefaults() { List closeables = new ArrayList<>(); OtlpHttpLogRecordExporter expectedExporter = OtlpHttpLogRecordExporter.getDefault().toBuilder() - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); @@ -108,7 +105,7 @@ void create_OtlpHttpConfigured(@TempDir Path tempDir) .addHeader("key2", "value2") .setTimeout(Duration.ofSeconds(15)) .setCompression("gzip") - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); @@ -181,7 +178,7 @@ void create_OtlpGrpcDefaults() { List closeables = new ArrayList<>(); OtlpGrpcLogRecordExporter expectedExporter = OtlpGrpcLogRecordExporter.getDefault().toBuilder() - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); @@ -218,7 +215,7 @@ void create_OtlpGrpcConfigured(@TempDir Path tempDir) .addHeader("key2", "value2") .setTimeout(Duration.ofSeconds(15)) .setCompression("gzip") - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java index 66f01ad0dbb..8a863f238f7 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactoryTest.java @@ -9,9 +9,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.internal.testing.CleanupExtension; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordProcessorComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; @@ -36,8 +36,7 @@ class LogRecordProcessorFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); private final DeclarativeConfigContext context = - new DeclarativeConfigContext( - SpiHelper.create(LogRecordProcessorFactoryTest.class.getClassLoader())); + new DeclarativeConfigContext(ComponentLoader.forClassLoader(getClass().getClassLoader())); @BeforeEach void setup() { @@ -60,7 +59,9 @@ void create_BatchNullExporter() { void create_BatchDefaults() { List closeables = new ArrayList<>(); BatchLogRecordProcessor expectedProcessor = - BatchLogRecordProcessor.builder(OtlpHttpLogRecordExporter.getDefault()).build(); + BatchLogRecordProcessor.builder( + OtlpHttpLogRecordExporter.builder().setComponentLoader(context).build()) + .build(); cleanup.addCloseable(expectedProcessor); LogRecordProcessor processor = @@ -83,7 +84,8 @@ void create_BatchDefaults() { void create_BatchConfigured() { List closeables = new ArrayList<>(); BatchLogRecordProcessor expectedProcessor = - BatchLogRecordProcessor.builder(OtlpHttpLogRecordExporter.getDefault()) + BatchLogRecordProcessor.builder( + OtlpHttpLogRecordExporter.builder().setComponentLoader(context).build()) .setScheduleDelay(Duration.ofMillis(1)) .setMaxExportBatchSize(2) .setExporterTimeout(Duration.ofMillis(3)) @@ -126,7 +128,8 @@ void create_SimpleNullExporter() { void create_SimpleConfigured() { List closeables = new ArrayList<>(); LogRecordProcessor expectedProcessor = - SimpleLogRecordProcessor.create(OtlpHttpLogRecordExporter.getDefault()); + SimpleLogRecordProcessor.create( + OtlpHttpLogRecordExporter.builder().setComponentLoader(context).build()); cleanup.addCloseable(expectedProcessor); LogRecordProcessor processor = diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java index d033c485e40..3381b3ea5e5 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactoryTest.java @@ -9,9 +9,9 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.internal.testing.CleanupExtension; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.common.internal.ScopeConfigurator; import io.opentelemetry.sdk.common.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel; @@ -44,9 +44,9 @@ class LoggerProviderFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); - private final DeclarativeConfigContext context = + private static final DeclarativeConfigContext context = new DeclarativeConfigContext( - SpiHelper.create(LoggerProviderFactoryTest.class.getClassLoader())); + ComponentLoader.forClassLoader(LoggerProviderFactoryTest.class.getClassLoader())); @BeforeEach void setup() { @@ -123,7 +123,9 @@ private static Stream createArguments() { .setMaxAttributeValueLength(2) .build()) .addLogRecordProcessor( - BatchLogRecordProcessor.builder(OtlpHttpLogRecordExporter.getDefault()).build()) + BatchLogRecordProcessor.builder( + OtlpHttpLogRecordExporter.builder().setComponentLoader(context).build()) + .build()) .build())); } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java index 46a49b68dae..1254b411992 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MeterProviderFactoryTest.java @@ -8,9 +8,9 @@ import static io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil.setMeterConfigurator; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.internal.testing.CleanupExtension; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.common.internal.ScopeConfigurator; import io.opentelemetry.sdk.common.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalMeterConfigModel; @@ -45,9 +45,9 @@ class MeterProviderFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); - private final DeclarativeConfigContext context = + private static final DeclarativeConfigContext context = new DeclarativeConfigContext( - SpiHelper.create(MeterProviderFactoryTest.class.getClassLoader())); + ComponentLoader.forClassLoader(MeterProviderFactoryTest.class.getClassLoader())); @BeforeEach void setup() { @@ -108,7 +108,9 @@ private static Stream createArguments() { .build()) .setExemplarFilter(ExemplarFilter.alwaysOn()) .registerMetricReader( - PeriodicMetricReader.builder(OtlpHttpMetricExporter.getDefault()).build()) + PeriodicMetricReader.builder( + OtlpHttpMetricExporter.builder().setComponentLoader(context).build()) + .build()) .registerView( InstrumentSelector.builder().setName("instrument-name").build(), View.builder().setName("stream-name").build()) diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java index e6b8f5cc712..62e48f337f7 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java @@ -17,7 +17,6 @@ import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.internal.testing.CleanupExtension; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleMetricExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalOtlpFileMetricExporterModel; @@ -58,14 +57,12 @@ class MetricExporterFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); private CapturingComponentLoader capturingComponentLoader; - private SpiHelper spiHelper; private DeclarativeConfigContext context; @BeforeEach void setup() { capturingComponentLoader = new CapturingComponentLoader(); - spiHelper = SpiHelper.create(capturingComponentLoader); - context = new DeclarativeConfigContext(spiHelper); + context = new DeclarativeConfigContext(capturingComponentLoader); context.setBuilder(new DeclarativeConfigurationBuilder()); } @@ -74,7 +71,7 @@ void create_OtlpHttpDefaults() { List closeables = new ArrayList<>(); OtlpHttpMetricExporter expectedExporter = OtlpHttpMetricExporter.getDefault().toBuilder() - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); @@ -119,7 +116,7 @@ void create_OtlpHttpConfigured(@TempDir Path tempDir) .setDefaultAggregationSelector( DefaultAggregationSelector.getDefault() .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())) - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); @@ -200,7 +197,7 @@ void create_OtlpGrpcDefaults() { List closeables = new ArrayList<>(); OtlpGrpcMetricExporter expectedExporter = OtlpGrpcMetricExporter.getDefault().toBuilder() - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); @@ -244,7 +241,7 @@ void create_OtlpGrpcConfigured(@TempDir Path tempDir) .setDefaultAggregationSelector( DefaultAggregationSelector.getDefault() .with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram())) - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java index a34c3510df4..3882003aa8d 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java @@ -15,10 +15,10 @@ import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.internal.testing.CleanupExtension; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.common.internal.IncludeExcludePredicate; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.CardinalityLimitsModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalPrometheusMetricExporterModel; @@ -53,7 +53,7 @@ class MetricReaderFactoryTest { private final DeclarativeConfigContext context = spy( new DeclarativeConfigContext( - SpiHelper.create(MetricReaderFactoryTest.class.getClassLoader()))); + ComponentLoader.forClassLoader(getClass().getClassLoader()))); @BeforeEach void setup() { @@ -76,7 +76,9 @@ void create_PeriodicNullExporter() { void create_PeriodicDefaults() { List closeables = new ArrayList<>(); PeriodicMetricReader expectedReader = - PeriodicMetricReader.builder(OtlpHttpMetricExporter.getDefault()).build(); + PeriodicMetricReader.builder( + OtlpHttpMetricExporter.builder().setComponentLoader(context).build()) + .build(); cleanup.addCloseable(expectedReader); MetricReaderAndCardinalityLimits readerAndCardinalityLimits = @@ -101,7 +103,8 @@ void create_PeriodicDefaults() { void create_PeriodicConfigured() { List closeables = new ArrayList<>(); MetricReader expectedReader = - PeriodicMetricReader.builder(OtlpHttpMetricExporter.getDefault()) + PeriodicMetricReader.builder( + OtlpHttpMetricExporter.builder().setComponentLoader(context).build()) .setInterval(Duration.ofMillis(1)) .build(); cleanup.addCloseable(expectedReader); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java index 87daa8abdd7..0c7ba467615 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java @@ -14,6 +14,7 @@ import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; @@ -23,7 +24,6 @@ import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnSamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; @@ -91,8 +91,7 @@ class OpenTelemetryConfigurationFactoryTest { .captureForLogger(OpenTelemetryConfigurationFactory.class.getName(), Level.WARN); private final DeclarativeConfigContext context = - new DeclarativeConfigContext( - SpiHelper.create(OpenTelemetryConfigurationFactoryTest.class.getClassLoader())); + new DeclarativeConfigContext(ComponentLoader.forClassLoader(getClass().getClassLoader())); @BeforeEach void setup() { @@ -326,7 +325,9 @@ void create_Configured() throws NoSuchFieldException { .build()) .addLogRecordProcessor( BatchLogRecordProcessor.builder( - OtlpHttpLogRecordExporter.getDefault()) + OtlpHttpLogRecordExporter.builder() + .setComponentLoader(context) + .build()) .build()) .build()) .setTracerProvider( @@ -343,14 +344,20 @@ void create_Configured() throws NoSuchFieldException { .build()) .setSampler(alwaysOn()) .addSpanProcessor( - BatchSpanProcessor.builder(OtlpHttpSpanExporter.getDefault()) + BatchSpanProcessor.builder( + OtlpHttpSpanExporter.builder() + .setComponentLoader(context) + .build()) .build()) .build()) .setMeterProvider( SdkMeterProvider.builder() .setResource(expectedResource) .registerMetricReader( - PeriodicMetricReader.builder(OtlpHttpMetricExporter.getDefault()) + PeriodicMetricReader.builder( + OtlpHttpMetricExporter.builder() + .setComponentLoader(context) + .build()) .build()) .registerView( InstrumentSelector.builder().setName("instrument-name").build(), diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java index 11672a246af..d3072f4aa31 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/PropagatorFactoryTest.java @@ -12,10 +12,10 @@ import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.extension.trace.propagation.B3Propagator; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.TextMapPropagatorComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.B3MultiPropagatorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.B3PropagatorModel; @@ -34,7 +34,7 @@ class PropagatorFactoryTest { private final DeclarativeConfigContext context = - new DeclarativeConfigContext(SpiHelper.create(PropagatorFactoryTest.class.getClassLoader())); + new DeclarativeConfigContext(ComponentLoader.forClassLoader(getClass().getClassLoader())); @ParameterizedTest @MethodSource("createArguments") diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java index 942b5cbf006..58b1bd6e7f5 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactoryTest.java @@ -9,7 +9,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectionModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel; @@ -28,7 +28,7 @@ class ResourceFactoryTest { private final DeclarativeConfigContext context = - new DeclarativeConfigContext(SpiHelper.create(ResourceFactoryTest.class.getClassLoader())); + new DeclarativeConfigContext(ComponentLoader.forClassLoader(getClass().getClassLoader())); @ParameterizedTest @MethodSource("createArgs") @@ -54,7 +54,10 @@ private static Stream createArgs() { .build()), Arguments.of( new ResourceModel().withSchemaUrl("http://foo"), - Resource.getDefault().toBuilder().setSchemaUrl("http://foo").build())); + Resource.getDefault().toBuilder().setSchemaUrl("http://foo").build()), + Arguments.of( + new ResourceModel().withAttributesList("key1=val1,key2=val2"), + Resource.getDefault().toBuilder().put("key1", "val1").put("key2", "val2").build())); } @ParameterizedTest diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java index 78b7db6c41d..52775f1abe4 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactoryTest.java @@ -9,9 +9,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SamplerComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOffSamplerModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnSamplerModel; @@ -53,7 +53,7 @@ class SamplerFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); private final DeclarativeConfigContext context = - new DeclarativeConfigContext(SpiHelper.create(SamplerFactoryTest.class.getClassLoader())); + new DeclarativeConfigContext(ComponentLoader.forClassLoader(getClass().getClassLoader())); @ParameterizedTest @MethodSource("createArguments") diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java index 741eec448c1..906ced22056 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java @@ -17,7 +17,6 @@ import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalOtlpFileExporterModel; @@ -54,14 +53,12 @@ class SpanExporterFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); private CapturingComponentLoader capturingComponentLoader; - private SpiHelper spiHelper; private DeclarativeConfigContext context; @BeforeEach void setup() { capturingComponentLoader = new CapturingComponentLoader(); - spiHelper = SpiHelper.create(capturingComponentLoader); - context = new DeclarativeConfigContext(spiHelper); + context = new DeclarativeConfigContext(capturingComponentLoader); context.setBuilder(new DeclarativeConfigurationBuilder()); } @@ -70,7 +67,7 @@ void create_OtlpHttpDefaults() { List closeables = new ArrayList<>(); OtlpHttpSpanExporter expectedExporter = OtlpHttpSpanExporter.getDefault().toBuilder() - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); @@ -107,7 +104,7 @@ void create_OtlpHttpConfigured(@TempDir Path tempDir) .addHeader("key2", "value2") .setTimeout(Duration.ofSeconds(15)) .setCompression("gzip") - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); @@ -180,7 +177,7 @@ void create_OtlpGrpcDefaults() { List closeables = new ArrayList<>(); OtlpGrpcSpanExporter expectedExporter = OtlpGrpcSpanExporter.getDefault().toBuilder() - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); @@ -216,7 +213,7 @@ void create_OtlpGrpcConfigured(@TempDir Path tempDir) .addHeader("key2", "value2") .setTimeout(Duration.ofSeconds(15)) .setCompression("gzip") - .setComponentLoader(capturingComponentLoader) // needed for the toString() check to pass + .setComponentLoader(context) // needed for the toString() check to pass .build(); cleanup.addCloseable(expectedExporter); diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java index 0b1c910487e..f56aedf746f 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactoryTest.java @@ -9,9 +9,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanProcessorComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpExporterModel; @@ -35,9 +35,9 @@ class SpanProcessorFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); - private final DeclarativeConfigContext context = + private static final DeclarativeConfigContext context = new DeclarativeConfigContext( - SpiHelper.create(SpanProcessorFactoryTest.class.getClassLoader())); + ComponentLoader.forClassLoader(SpanProcessorFactoryTest.class.getClassLoader())); @BeforeEach void setup() { @@ -59,7 +59,9 @@ void create_BatchNullExporter() { void create_BatchDefaults() { List closeables = new ArrayList<>(); BatchSpanProcessor expectedProcessor = - BatchSpanProcessor.builder(OtlpHttpSpanExporter.getDefault()).build(); + BatchSpanProcessor.builder( + OtlpHttpSpanExporter.builder().setComponentLoader(context).build()) + .build(); cleanup.addCloseable(expectedProcessor); SpanProcessor processor = @@ -81,7 +83,8 @@ void create_BatchDefaults() { void create_BatchConfigured() { List closeables = new ArrayList<>(); BatchSpanProcessor expectedProcessor = - BatchSpanProcessor.builder(OtlpHttpSpanExporter.getDefault()) + BatchSpanProcessor.builder( + OtlpHttpSpanExporter.builder().setComponentLoader(context).build()) .setScheduleDelay(Duration.ofMillis(1)) .setMaxExportBatchSize(2) .setExporterTimeout(Duration.ofMillis(3)) @@ -121,7 +124,9 @@ void create_SimpleNullExporter() { @Test void create_SimpleConfigured() { List closeables = new ArrayList<>(); - SpanProcessor expectedProcessor = SimpleSpanProcessor.create(OtlpHttpSpanExporter.getDefault()); + SpanProcessor expectedProcessor = + SimpleSpanProcessor.create( + OtlpHttpSpanExporter.builder().setComponentLoader(context).build()); cleanup.addCloseable(expectedProcessor); SpanProcessor processor = diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java index 4a680dd91cc..b2610d678b9 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactoryTest.java @@ -8,9 +8,9 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.common.internal.ScopeConfigurator; import io.opentelemetry.sdk.common.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnSamplerModel; @@ -46,9 +46,9 @@ class TracerProviderFactoryTest { @RegisterExtension CleanupExtension cleanup = new CleanupExtension(); - private final DeclarativeConfigContext context = + private static final DeclarativeConfigContext context = new DeclarativeConfigContext( - SpiHelper.create(TracerProviderFactoryTest.class.getClassLoader())); + ComponentLoader.forClassLoader(TracerProviderFactoryTest.class.getClassLoader())); @BeforeEach void setup() { @@ -127,7 +127,9 @@ private static Stream createArguments() { .build()) .setSampler(alwaysOn()) .addSpanProcessor( - BatchSpanProcessor.builder(OtlpHttpSpanExporter.getDefault()).build()) + BatchSpanProcessor.builder( + OtlpHttpSpanExporter.builder().setComponentLoader(context).build()) + .build()) .build())); }