From 1e93d7c5f956086951caecd10831efc089324645 Mon Sep 17 00:00:00 2001 From: navneet singh Date: Sat, 14 Nov 2026 20:06:04 +0530 Subject: [PATCH 1/3] Refine declarative config public contract for stabilization - Demote api:incubator from api to implementation dependency to prevent transitive compile-scope leakage in published POM metadata - Update DeclarativeConfigResult.getSdk() to return public stable OpenTelemetrySdk instead of internal ExtendedOpenTelemetrySdk - Add PublicApiUsageTest to validate end-to-end consumer usage using only public APIs - Update create and factory tests to match OpenTelemetrySdk --- .../declarative-config/build.gradle.kts | 2 +- .../DeclarativeConfigResult.java | 8 +- .../DeclarativeConfigurationCreateTest.java | 3 +- ...OpenTelemetryConfigurationFactoryTest.java | 11 ++- .../declarativeconfig/PublicApiUsageTest.java | 84 +++++++++++++++++++ 5 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/PublicApiUsageTest.java diff --git a/sdk-extensions/declarative-config/build.gradle.kts b/sdk-extensions/declarative-config/build.gradle.kts index 3b4e36ec043..cd30a62a418 100644 --- a/sdk-extensions/declarative-config/build.gradle.kts +++ b/sdk-extensions/declarative-config/build.gradle.kts @@ -26,7 +26,7 @@ otelJava.osgiServiceLoaderRequires.set(listOf( dependencies { api(project(":sdk:all")) - api(project(":api:incubator")) + implementation(project(":api:incubator")) compileOnly(project(":sdk-extensions:autoconfigure-spi")) runtimeOnly(project(":sdk-extensions:declarative-config-jackson2")) runtimeOnly(project(":sdk-extensions:declarative-config-snakeyaml-engine2")) diff --git a/sdk-extensions/declarative-config/src/main/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/DeclarativeConfigResult.java b/sdk-extensions/declarative-config/src/main/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/DeclarativeConfigResult.java index cdfb8623b61..047f5a641d1 100644 --- a/sdk-extensions/declarative-config/src/main/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/DeclarativeConfigResult.java +++ b/sdk-extensions/declarative-config/src/main/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/DeclarativeConfigResult.java @@ -5,22 +5,22 @@ package io.opentelemetry.sdk.autoconfigure.declarativeconfig; +import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.OpenTelemetryConfigurationModel; -import io.opentelemetry.sdk.internal.ExtendedOpenTelemetrySdk; import io.opentelemetry.sdk.resources.Resource; /** The result of {@link DeclarativeConfiguration#create(OpenTelemetryConfigurationModel)}. */ public final class DeclarativeConfigResult { - private final ExtendedOpenTelemetrySdk sdk; + private final OpenTelemetrySdk sdk; private final Resource resource; - DeclarativeConfigResult(ExtendedOpenTelemetrySdk sdk, Resource resource) { + DeclarativeConfigResult(OpenTelemetrySdk sdk, Resource resource) { this.sdk = sdk; this.resource = resource; } - public ExtendedOpenTelemetrySdk getSdk() { + public OpenTelemetrySdk getSdk() { return sdk; } diff --git a/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/DeclarativeConfigurationCreateTest.java b/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/DeclarativeConfigurationCreateTest.java index 089ce2132dd..fc6610df7ea 100644 --- a/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/DeclarativeConfigurationCreateTest.java +++ b/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/DeclarativeConfigurationCreateTest.java @@ -22,7 +22,6 @@ import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.SpanProcessorModel; import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.TracerProviderModel; -import io.opentelemetry.sdk.internal.ExtendedOpenTelemetrySdk; import io.opentelemetry.sdk.resources.ResourceBuilder; import io.opentelemetry.sdk.trace.samplers.ParentBasedSamplerBuilder; import java.io.ByteArrayInputStream; @@ -181,7 +180,7 @@ void create_ModelCustomizer() { .setProcessors( Collections.singletonList( new SpanProcessorModel().setExtensionProperty("test", null)))); - ExtendedOpenTelemetrySdk sdk = + OpenTelemetrySdk sdk = DeclarativeConfiguration.create( model, // customizer is TestDeclarativeConfigurationCustomizerProvider diff --git a/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/OpenTelemetryConfigurationFactoryTest.java index c9cfb2186cd..0a975aca909 100644 --- a/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/OpenTelemetryConfigurationFactoryTest.java +++ b/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/OpenTelemetryConfigurationFactoryTest.java @@ -53,7 +53,6 @@ import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.internal.ExperimentalResourceDetectionModel; import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.internal.ExperimentalResourceDetectorModel; import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.internal.ResourceModelAccessor; -import io.opentelemetry.sdk.internal.ExtendedOpenTelemetrySdk; import io.opentelemetry.sdk.internal.OpenTelemetrySdkBuilderUtil; import io.opentelemetry.sdk.internal.SdkConfigProvider; import io.opentelemetry.sdk.logs.LogLimits; @@ -147,7 +146,7 @@ void create_FileFormatVersionMismatch_LogsWarning() { OpenTelemetryConfigurationModel model = new OpenTelemetryConfigurationModel().setFileFormat("1.0-rc.3"); - ExtendedOpenTelemetrySdk sdk = + OpenTelemetrySdk sdk = OpenTelemetryConfigurationFactory.getInstance().create(model, context).getSdk(); cleanup.addCloseable(sdk); @@ -160,7 +159,7 @@ void create_FileFormatExactMatch_NoWarning() { OpenTelemetryConfigurationModel model = new OpenTelemetryConfigurationModel().setFileFormat("1.2"); - ExtendedOpenTelemetrySdk sdk = + OpenTelemetrySdk sdk = OpenTelemetryConfigurationFactory.getInstance().create(model, context).getSdk(); cleanup.addCloseable(sdk); @@ -179,7 +178,7 @@ void create_Defaults() { .build(); cleanup.addCloseable(expectedSdk); - ExtendedOpenTelemetrySdk sdk = + OpenTelemetrySdk sdk = OpenTelemetryConfigurationFactory.getInstance().create(model, context).getSdk(); cleanup.addCloseable(sdk); cleanup.addCloseables(closeables); @@ -212,7 +211,7 @@ void create_Disabled() { .build(); cleanup.addCloseable(expectedSdk); - ExtendedOpenTelemetrySdk sdk = + OpenTelemetrySdk sdk = OpenTelemetryConfigurationFactory.getInstance().create(model, context).getSdk(); cleanup.addCloseable(sdk); cleanup.addCloseables(closeables); @@ -372,7 +371,7 @@ void create_Configured() throws NoSuchFieldException { cleanup.addCloseable(expectedSdk); - ExtendedOpenTelemetrySdk sdk = + OpenTelemetrySdk sdk = OpenTelemetryConfigurationFactory.getInstance().create(model, context).getSdk(); cleanup.addCloseable(sdk); cleanup.addCloseables(closeables); diff --git a/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/PublicApiUsageTest.java b/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/PublicApiUsageTest.java new file mode 100644 index 00000000000..f47b54262fb --- /dev/null +++ b/sdk-extensions/declarative-config/src/test/java/io/opentelemetry/sdk/autoconfigure/declarativeconfig/PublicApiUsageTest.java @@ -0,0 +1,84 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure.declarativeconfig; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.autoconfigure.declarativeconfig.model.ResourceModel; +import io.opentelemetry.sdk.resources.Resource; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.junit.jupiter.api.Test; + +/** + * Validates that an external consumer can parse, inspect, customize, and create an {@link + * OpenTelemetrySdk} strictly using the public declarative configuration API surface without + * importing or relying on any incubator or internal packages. + */ +class PublicApiUsageTest { + + private static final String MINIMAL_CONFIG = + "file_format: \"1.2\"\n" + + "resource:\n" + + " attributes:\n" + + " - name: service.name\n" + + " value: test-service\n"; + + @Test + void parseAndCreate_endToEndPublicApiWorkflow() { + InputStream inputStream = + new ByteArrayInputStream(MINIMAL_CONFIG.getBytes(StandardCharsets.UTF_8)); + + // 1. Parse configuration strictly via public API + OpenTelemetryConfigurationModel model = DeclarativeConfiguration.parse(inputStream); + assertThat(model).isNotNull(); + assertThat(model.getFileFormat()).isEqualTo("1.2"); + + // 2. Inspect and customize model using only public model methods + ResourceModel resourceModel = model.getResource(); + assertThat(resourceModel).isNotNull(); + + // 3. Create SDK via DeclarativeConfiguration.create(model) + DeclarativeConfigResult result = DeclarativeConfiguration.create(model); + assertThat(result).isNotNull(); + + Resource resource = result.getResource(); + assertThat(resource.getAttribute(AttributeKey.stringKey("service.name"))) + .isEqualTo("test-service"); + + OpenTelemetrySdk sdk = result.getSdk(); + assertThat(sdk).isNotNull(); + try { + Tracer tracer = sdk.getTracer("test-tracer"); + assertThat(tracer).isNotNull(); + } finally { + sdk.close(); + } + } + + @Test + void parseAndCreate_convenienceMethod() { + InputStream inputStream = + new ByteArrayInputStream(MINIMAL_CONFIG.getBytes(StandardCharsets.UTF_8)); + + DeclarativeConfigResult result = DeclarativeConfiguration.parseAndCreate(inputStream); + assertThat(result).isNotNull(); + + OpenTelemetrySdk sdk = result.getSdk(); + assertThat(sdk).isNotNull(); + try { + assertThat(result.getResource().getAttribute(AttributeKey.stringKey("service.name"))) + .isEqualTo("test-service"); + } finally { + sdk.close(); + } + } +} From d1b2f04d7460b611ffe23ebbb42b3eb4b3aeda92 Mon Sep 17 00:00:00 2001 From: navneet singh Date: Sat, 14 Nov 2026 21:34:29 +0530 Subject: [PATCH 2/3] Add explicit api:incubator dependency to OSGi autoconfigureDeclarativeConfig suite --- integration-tests/osgi/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-tests/osgi/build.gradle.kts b/integration-tests/osgi/build.gradle.kts index 3db229d7b2c..631fcd3df99 100644 --- a/integration-tests/osgi/build.gradle.kts +++ b/integration-tests/osgi/build.gradle.kts @@ -304,6 +304,7 @@ val autoconfigureDeclarativeConfigSuiteTask = registerOsgiSuite( implementation(project(":sdk:all")) implementation(project(":sdk-extensions:autoconfigure")) implementation(project(":sdk-extensions:declarative-config")) + implementation(project(":api:incubator")) implementation(project(":exporters:otlp:all")) implementation(project(":extensions:trace-propagators")) runtimeOnly(project(":exporters:sender:jdk")) From 02b8412f6c8378dc0032b1281ab019ebae2c3203 Mon Sep 17 00:00:00 2001 From: navneet singh Date: Sat, 14 Nov 2026 22:18:29 +0530 Subject: [PATCH 3/3] Add explicit api:incubator dependency to autoconfigure test suites --- sdk-extensions/autoconfigure/build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index 692bb0c7812..9c2fabe7e94 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -107,6 +107,7 @@ testing { register("testIncubating") { dependencies { implementation(project(":sdk-extensions:declarative-config")) + implementation(project(":api:incubator")) implementation(project(":exporters:logging")) implementation(project(":exporters:otlp:all")) implementation(project(":sdk:testing")) @@ -120,6 +121,7 @@ testing { register("testDeclarativeConfigSpi") { dependencies { implementation(project(":sdk-extensions:declarative-config")) + implementation(project(":api:incubator")) implementation(project(":exporters:logging")) implementation(project(":sdk:testing")) }