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 673ced041f..f19c85116a 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 @@ -108,10 +108,19 @@ public final class DeclarativeConfiguration { */ public static OpenTelemetrySdk create( OpenTelemetryConfigurationModel configurationModel, ComponentLoader componentLoader) { + SpiHelper spiHelper = SpiHelper.create(componentLoader); + + DeclarativeConfigurationBuilder builder = new DeclarativeConfigurationBuilder(); + + for (DeclarativeConfigurationCustomizerProvider provider : + spiHelper.loadOrdered(DeclarativeConfigurationCustomizerProvider.class)) { + provider.customize(builder); + } + return createAndMaybeCleanup( OpenTelemetryConfigurationFactory.getInstance(), - SpiHelper.create(componentLoader), - configurationModel); + spiHelper, + builder.customizeModel(configurationModel)); } /** diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationBuilder.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationBuilder.java new file mode 100644 index 0000000000..c96aa629fe --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationBuilder.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import java.util.function.Function; + +/** Builder for the declarative configuration. */ +public class DeclarativeConfigurationBuilder implements DeclarativeConfigurationCustomizer { + private Function + modelCustomizer = Function.identity(); + + @Override + public void addModelCustomizer( + Function customizer) { + modelCustomizer = mergeCustomizer(modelCustomizer, customizer); + } + + private static Function mergeCustomizer( + Function first, Function second) { + return (I configured) -> { + O1 firstResult = first.apply(configured); + return second.apply(firstResult); + }; + } + + /** Customize the configuration model. */ + public OpenTelemetryConfigurationModel customizeModel( + OpenTelemetryConfigurationModel configurationModel) { + return modelCustomizer.apply(configurationModel); + } +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizer.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizer.java new file mode 100644 index 0000000000..3e8e327355 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizer.java @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import java.util.function.Function; + +/** A service provider interface (SPI) for customizing declarative configuration. */ +public interface DeclarativeConfigurationCustomizer { + /** + * Method invoked when configuring the SDK to allow further customization of the declarative + * configuration. + * + * @param customizer the customizer to add + */ + void addModelCustomizer( + Function customizer); +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizerProvider.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizerProvider.java new file mode 100644 index 0000000000..e5ec52c60d --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCustomizerProvider.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.sdk.autoconfigure.spi.Ordered; + +/** A service provider interface (SPI) for customizing declarative configuration. */ +public interface DeclarativeConfigurationCustomizerProvider extends Ordered { + /** + * Method invoked when configuring the SDK to allow further customization of the declarative + * configuration. + * + * @param customizer the customizer to add + */ + void customize(DeclarativeConfigurationCustomizer customizer); +} 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 5b0e2fbca1..262270670c 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 @@ -14,6 +14,11 @@ import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.internal.testing.CleanupExtension; +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; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; @@ -22,6 +27,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.security.cert.CertificateEncodingException; +import java.util.Collections; import java.util.Objects; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -61,7 +67,7 @@ class DeclarativeConfigurationCreateTest { tempDir, "clientCertificate.cert", clientTls.certificate().getEncoded()); File examplesDir = new File(System.getenv("CONFIG_EXAMPLE_DIR")); - assertThat(examplesDir.isDirectory()).isTrue(); + assertThat(examplesDir).isDirectory(); for (File example : Objects.requireNonNull(examplesDir.listFiles())) { // Skip anchors.yaml because support for merge (i.e. "<<: *anchor") was explicitly removed in @@ -151,4 +157,32 @@ class DeclarativeConfigurationCreateTest { new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8)))) .doesNotThrowAnyException(); } + + @Test + void create_ModelCustomizer() { + OpenTelemetryConfigurationModel model = new OpenTelemetryConfigurationModel(); + model.withFileFormat("0.3"); + model.withTracerProvider( + new TracerProviderModel() + .withProcessors( + Collections.singletonList( + new SpanProcessorModel().withAdditionalProperty("test", null)))); + OpenTelemetrySdk sdk = + DeclarativeConfiguration.create( + model, + // customizer is TestDeclarativeConfigurationCustomizerProvider + SpiHelper.serviceComponentLoader( + DeclarativeConfigurationCreateTest.class.getClassLoader())); + assertThat(sdk.toString()) + .contains( + "resource=Resource{schemaUrl=null, attributes={" + + "color=\"blue\", " + + "foo=\"bar\", " + + "order=\"second\", " + + "service.name=\"unknown_service:java\", " + + "shape=\"square\", " + + "telemetry.sdk.language=\"java\", " + + "telemetry.sdk.name=\"opentelemetry\", " + + "telemetry.sdk.version=\""); + } } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TestDeclarativeConfigurationCustomizerProvider.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TestDeclarativeConfigurationCustomizerProvider.java new file mode 100644 index 0000000000..33187b73ba --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TestDeclarativeConfigurationCustomizerProvider.java @@ -0,0 +1,42 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; +import java.util.ArrayList; +import java.util.List; + +public class TestDeclarativeConfigurationCustomizerProvider + implements DeclarativeConfigurationCustomizerProvider { + @Override + public void customize(DeclarativeConfigurationCustomizer customizer) { + customizer.addModelCustomizer( + model -> { + ResourceModel resource = model.getResource(); + if (resource == null) { + resource = new ResourceModel(); + model.withResource(resource); + } + List attributes = resource.getAttributes(); + if (attributes == null) { + attributes = new ArrayList<>(); + resource.withAttributes(attributes); + } + attributes.add( + new AttributeNameValueModel() + .withName("foo") + .withType(AttributeNameValueModel.Type.STRING) + .withValue("bar")); + attributes.add( + new AttributeNameValueModel() + .withName("color") + .withType(AttributeNameValueModel.Type.STRING) + .withValue("blue")); + return model; + }); + } +} diff --git a/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider new file mode 100644 index 0000000000..f60ca4e082 --- /dev/null +++ b/sdk-extensions/incubator/src/test/resources/META-INF/services/io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider @@ -0,0 +1 @@ +io.opentelemetry.sdk.extension.incubator.fileconfig.TestDeclarativeConfigurationCustomizerProvider