From d90cf44c879139dfc45285a3ae2aab5ece0a28c0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Jun 2025 20:30:17 -0700 Subject: [PATCH 01/13] fix(deps): update dependency com.google.api.grpc:proto-google-common-protos to v2.58.2 (#7426) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index aabfe3de3f..726e3132ce 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -68,7 +68,7 @@ val DEPENDENCIES = listOf( "io.prometheus:prometheus-metrics-exposition-formats-no-protobuf:${prometheusServerVersion}", "javax.annotation:javax.annotation-api:1.3.2", "com.github.stefanbirkner:system-rules:1.19.0", - "com.google.api.grpc:proto-google-common-protos:2.58.0", + "com.google.api.grpc:proto-google-common-protos:2.58.2", "com.google.code.findbugs:jsr305:3.0.2", "com.google.guava:guava-beta-checker:1.0", "com.sun.net.httpserver:http:20070405", From 2eb84bf41752c85ceee17ed91b0140253d3c1cac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Jun 2025 20:30:40 -0700 Subject: [PATCH 02/13] fix(deps): update dependency org.testcontainers:testcontainers-bom to v1.21.2 (#7431) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 726e3132ce..d1ec2142f7 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -23,7 +23,7 @@ val DEPENDENCY_BOMS = listOf( "io.zipkin.brave:brave-bom:6.3.0", "io.zipkin.reporter2:zipkin-reporter-bom:3.5.1", "org.assertj:assertj-bom:3.27.3", - "org.testcontainers:testcontainers-bom:1.21.1", + "org.testcontainers:testcontainers-bom:1.21.2", "org.snakeyaml:snakeyaml-engine:2.9" ) From ada5af60d156df7e73dcd5df6bb8d74badc098dd Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:47:56 -0700 Subject: [PATCH 03/13] Prevent major version bump in equalsverifier. (#7416) --- .github/renovate.json5 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 70e3507d22..6db27ec1fc 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -74,5 +74,12 @@ 'com.diffplug.spotless{/,}**', ], }, + { + // equals verifier v4+ requires java 17+ + groupName: 'nl.jqno.equalsverifier', + matchPackageNames: [ 'equalsverifier'], + matchUpdateTypes: [ 'major' ], + enabled: false + } ], } From fa31e52722c02cbb4ceeaadf2a79316d24265c0b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 09:12:39 -0700 Subject: [PATCH 04/13] fix(deps): update dependency checkstyle to v10.25.1 (#7437) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index 6dc35c271c..e49f018634 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.25.0" + toolVersion = "10.25.1" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From bf65026b71e2ff35fab8e1c023373bc4685bd1f1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 09:14:58 -0700 Subject: [PATCH 05/13] chore(deps): update weekly update (#7423) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/benchmark-tags.yml | 2 +- .github/workflows/benchmark.yml | 2 +- .github/workflows/build.yml | 4 ++-- .github/workflows/codeql.yml | 6 +++--- .github/workflows/gradle-wrapper-validation.yml | 2 +- .github/workflows/javadoc-crawler.yml | 2 +- .github/workflows/ossf-scorecard.yml | 2 +- .github/workflows/owasp-dependency-check-daily.yml | 2 +- .github/workflows/release.yml | 2 +- integration-tests/tracecontext/docker/Dockerfile | 4 ++-- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/benchmark-tags.yml b/.github/workflows/benchmark-tags.yml index 95b4675f5d..b6485ae808 100644 --- a/.github/workflows/benchmark-tags.yml +++ b/.github/workflows/benchmark-tags.yml @@ -56,7 +56,7 @@ jobs: java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0 + uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 - name: Run jmh run: ./gradlew jmhJar diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 3ddb3c6ff5..310be8bf96 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -26,7 +26,7 @@ jobs: java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0 + uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 - name: Run jmh run: ./gradlew jmhJar diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 047e602ac8..5e8ccb4e82 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,7 +69,7 @@ jobs: java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0 + uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 - name: Build run: > ./gradlew build @@ -145,7 +145,7 @@ jobs: java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0 + uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 # skipping release branches because the versions in those branches are not snapshots # (also this skips pull requests) if: ${{ github.ref_name == 'main' && github.repository == 'open-telemetry/opentelemetry-java' }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index eadfaa7abc..5f5d2a7ab9 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -34,10 +34,10 @@ jobs: java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0 + uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 - name: Initialize CodeQL - uses: github/codeql-action/init@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19 + uses: github/codeql-action/init@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 with: languages: java, actions # using "latest" helps to keep up with the latest Kotlin support @@ -51,4 +51,4 @@ jobs: run: ./gradlew assemble --no-build-cache --no-daemon - name: Perform CodeQL analysis - uses: github/codeql-action/analyze@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19 + uses: github/codeql-action/analyze@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index a9e18e8aa4..ded780070b 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: gradle/actions/wrapper-validation@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0 + - uses: gradle/actions/wrapper-validation@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 diff --git a/.github/workflows/javadoc-crawler.yml b/.github/workflows/javadoc-crawler.yml index cd87b005f7..9567c38506 100644 --- a/.github/workflows/javadoc-crawler.yml +++ b/.github/workflows/javadoc-crawler.yml @@ -20,7 +20,7 @@ jobs: java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0 + uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 - name: Run crawler run: ./gradlew :javadoc-crawler:crawl diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index 352cf133f0..cff5b894fc 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -42,6 +42,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19 + uses: github/codeql-action/upload-sarif@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 with: sarif_file: results.sarif diff --git a/.github/workflows/owasp-dependency-check-daily.yml b/.github/workflows/owasp-dependency-check-daily.yml index 8d795c6e7f..dc485ade1b 100644 --- a/.github/workflows/owasp-dependency-check-daily.yml +++ b/.github/workflows/owasp-dependency-check-daily.yml @@ -22,7 +22,7 @@ jobs: java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0 + uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 - name: Check dependencies run: ./gradlew dependencyCheckAnalyze diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ada71742b2..abc1423885 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ jobs: java-version: 17 - name: Set up gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # v4.4.0 + uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 - name: Build and publish artifacts run: ./gradlew assemble publishToSonatype closeAndReleaseSonatypeStagingRepository diff --git a/integration-tests/tracecontext/docker/Dockerfile b/integration-tests/tracecontext/docker/Dockerfile index 39d52f3b97..02f577a93c 100644 --- a/integration-tests/tracecontext/docker/Dockerfile +++ b/integration-tests/tracecontext/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.13.4@sha256:eb120d016adcbc8bac194e15826bbb4f1d1569d298d8817bb5049ed5e59f41d9 AS build +FROM python:3.13.5@sha256:5f69d22a88dd4cc4ee1576def19aef48c8faa1b566054c44291183831cbad13b AS build # Main branch SHA as of April-1-2021 ARG TRACECONTEXT_GIT_TAG="dcd3ad9b7d6ac36f70ff3739874b73c11b0302a1" @@ -11,7 +11,7 @@ RUN unzip trace-context.zip RUN rm trace-context.zip RUN mv trace-context-${TRACECONTEXT_GIT_TAG}/test /tracecontext-testsuite -FROM python:3.13.4-slim@sha256:d97b595c5f4ac718102e5a5a91adaf04b22e852961a698411637c718d45867c8 +FROM python:3.13.5-slim@sha256:f2fdaec50160418e0c2867ba3e254755edd067171725886d5d303fd7057bbf81 RUN pip install aiohttp From 55a1b57644283312c3dea83e306458bd0af3f1c1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 11:17:33 -0700 Subject: [PATCH 06/13] chore(deps): update plugin com.gradleup.shadow to v8.3.7 (#7439) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 4752f7a31b..58659284e9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,6 @@ pluginManagement { plugins { - id("com.gradleup.shadow") version "8.3.6" + id("com.gradleup.shadow") version "8.3.7" id("com.gradle.develocity") version "4.0.2" id("de.undercouch.download") version "5.6.0" id("org.jsonschema2pojo") version "1.2.2" From 76913bb22473567d2179ad2abd35c6fec6b82344 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 11:20:22 -0700 Subject: [PATCH 07/13] fix(deps): update dependency checkstyle to v10.26.0 (#7443) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts index e49f018634..54b6269d81 100644 --- a/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts @@ -42,7 +42,7 @@ java { checkstyle { configDirectory.set(file("$rootDir/buildscripts/")) - toolVersion = "10.25.1" + toolVersion = "10.26.0" isIgnoreFailures = false configProperties["rootDir"] = rootDir } From b0a9deb7d8dcf8fe8bb0ca1e077df837d328b413 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 24 Jun 2025 21:22:10 +0200 Subject: [PATCH 08/13] Fix race condition of `GlobalOpenTelemetry` initialization with `AutoConfiguredOpenTelemetrySdkBuilder` (#7365) Co-authored-by: Jack Berg Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .../api/GlobalOpenTelemetry.java | 14 ++++ .../current_vs_latest/opentelemetry-api.txt | 4 +- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 41 ++++++----- .../AutoConfiguredOpenTelemetrySdkTest.java | 69 +++++++++++++++++++ 4 files changed, 111 insertions(+), 17 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/GlobalOpenTelemetry.java b/api/all/src/main/java/io/opentelemetry/api/GlobalOpenTelemetry.java index 230a85e06a..83e70bf7d8 100644 --- a/api/all/src/main/java/io/opentelemetry/api/GlobalOpenTelemetry.java +++ b/api/all/src/main/java/io/opentelemetry/api/GlobalOpenTelemetry.java @@ -17,6 +17,7 @@ import io.opentelemetry.api.trace.TracerProvider; import io.opentelemetry.context.propagation.ContextPropagators; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -116,6 +117,19 @@ public final class GlobalOpenTelemetry { } } + /** + * Sets the {@link OpenTelemetry} that should be the global instance. + * + *

This method calls the given {@code supplier} and calls {@link #set(OpenTelemetry)}, all + * while holding the {@link GlobalOpenTelemetry} mutex. + */ + public static void set(Supplier supplier) { + synchronized (mutex) { + OpenTelemetry openTelemetry = supplier.get(); + set(openTelemetry); + } + } + /** Returns the globally registered {@link TracerProvider}. */ public static TracerProvider getTracerProvider() { return get().getTracerProvider(); diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt index ba433bd6ed..3a33f42b55 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-api.txt @@ -1,2 +1,4 @@ Comparing source compatibility of opentelemetry-api-1.52.0-SNAPSHOT.jar against opentelemetry-api-1.51.0.jar -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.api.GlobalOpenTelemetry (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) void set(java.util.function.Supplier) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index e12848f0d8..124231fa32 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -41,6 +41,8 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; @@ -424,6 +426,25 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur * the settings of this {@link AutoConfiguredOpenTelemetrySdkBuilder}. */ public AutoConfiguredOpenTelemetrySdk build() { + if (!setResultAsGlobal) { + return buildImpl(); + } + AtomicReference autoConfiguredRef = new AtomicReference<>(); + GlobalOpenTelemetry.set( + () -> { + AutoConfiguredOpenTelemetrySdk sdk = buildImpl(); + autoConfiguredRef.set(sdk); + return sdk.getOpenTelemetrySdk(); + }); + AutoConfiguredOpenTelemetrySdk sdk = Objects.requireNonNull(autoConfiguredRef.get()); + logger.log( + Level.FINE, + "Global OpenTelemetry set to {0} by autoconfiguration", + sdk.getOpenTelemetrySdk()); + return sdk; + } + + private AutoConfiguredOpenTelemetrySdk buildImpl() { SpiHelper spiHelper = SpiHelper.create(componentLoader); if (!customized) { customized = true; @@ -440,8 +461,10 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur maybeConfigureFromFile(config, componentLoader); if (fromFileConfiguration != null) { maybeRegisterShutdownHook(fromFileConfiguration.getOpenTelemetrySdk()); - maybeSetAsGlobal( - fromFileConfiguration.getOpenTelemetrySdk(), fromFileConfiguration.getConfigProvider()); + Object configProvider = fromFileConfiguration.getConfigProvider(); + if (setResultAsGlobal && INCUBATOR_AVAILABLE && configProvider != null) { + IncubatingUtil.setGlobalConfigProvider(configProvider); + } return fromFileConfiguration; } @@ -467,7 +490,6 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur OpenTelemetrySdk openTelemetrySdk = sdkBuilder.build(); maybeRegisterShutdownHook(openTelemetrySdk); - maybeSetAsGlobal(openTelemetrySdk, null); callAutoConfigureListeners(spiHelper, openTelemetrySdk); return AutoConfiguredOpenTelemetrySdk.create(openTelemetrySdk, resource, config, null); @@ -572,19 +594,6 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur Runtime.getRuntime().addShutdownHook(shutdownHook(openTelemetrySdk)); } - private void maybeSetAsGlobal( - OpenTelemetrySdk openTelemetrySdk, @Nullable Object configProvider) { - if (!setResultAsGlobal) { - return; - } - GlobalOpenTelemetry.set(openTelemetrySdk); - if (INCUBATOR_AVAILABLE && configProvider != null) { - IncubatingUtil.setGlobalConfigProvider(configProvider); - } - logger.log( - Level.FINE, "Global OpenTelemetry set to {0} by autoconfiguration", openTelemetrySdk); - } - // Visible for testing void callAutoConfigureListeners(SpiHelper spiHelper, OpenTelemetrySdk openTelemetrySdk) { for (AutoConfigureListener listener : spiHelper.getListeners()) { diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index c7ae65de9a..45d2630832 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -58,6 +58,7 @@ import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.IOException; +import java.lang.reflect.Field; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collections; @@ -65,7 +66,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Supplier; @@ -674,4 +681,66 @@ class AutoConfiguredOpenTelemetrySdkTest { logs.assertContains("Error closing io.opentelemetry.sdk.trace.SdkTracerProvider: Error!"); } + + @Test + void globalOpenTelemetryLock() throws InterruptedException, ExecutionException, TimeoutException { + CountDownLatch autoconfigStarted = new CountDownLatch(1); + CountDownLatch completeAutoconfig = new CountDownLatch(1); + ExecutorService executorService = Executors.newFixedThreadPool(2); + + // Submit a future to autoconfigure the SDK and set the result as global. Add a customization + // hook which blocks until we say so. + CompletableFuture autoConfiguredOpenTelemetryFuture = + CompletableFuture.supplyAsync( + () -> + builder + .addLoggerProviderCustomizer( + (sdkLoggerProviderBuilder, configProperties) -> { + autoconfigStarted.countDown(); + try { + completeAutoconfig.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + return sdkLoggerProviderBuilder; + }) + .setResultAsGlobal() + .build() + .getOpenTelemetrySdk(), + executorService); + + // Wait for autoconfiguration to enter our callback, then try to get an instance of + // GlobalOpenTelemetry. GlobalOpenTelemetry.get() should block until we release the + // completeAutoconfig latch and allow autoconfiguration to complete. + autoconfigStarted.await(); + CompletableFuture globalOpenTelemetryFuture = + CompletableFuture.supplyAsync(GlobalOpenTelemetry::get, executorService); + Thread.sleep(10); + assertThat(globalOpenTelemetryFuture.isDone()).isFalse(); + assertThat(autoConfiguredOpenTelemetryFuture.isDone()).isFalse(); + + // Release the latch, allowing autoconfiguration to complete. Confirm that our + // GlobalOpenTelemetry.get() future resolved to the same instance as autoconfiguration. + completeAutoconfig.countDown(); + assertThat(unobfuscate(globalOpenTelemetryFuture.get(10, TimeUnit.SECONDS))) + .isSameAs(autoConfiguredOpenTelemetryFuture.get(10, TimeUnit.SECONDS)); + + // Cleanup + executorService.shutdown(); + autoConfiguredOpenTelemetryFuture.get().shutdown().join(10, TimeUnit.SECONDS); + GlobalOpenTelemetry.resetForTest(); + } + + private static OpenTelemetry unobfuscate(OpenTelemetry openTelemetry) { + try { + Field delegateField = + Class.forName("io.opentelemetry.api.GlobalOpenTelemetry$ObfuscatedOpenTelemetry") + .getDeclaredField("delegate"); + delegateField.setAccessible(true); + Object delegate = delegateField.get(openTelemetry); + return (OpenTelemetry) delegate; + } catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) { + throw new IllegalStateException("Error unobfuscating OpenTelemetry", e); + } + } } From aeb08f40a0f3e8d13d30e74a09188ba3c03a1e73 Mon Sep 17 00:00:00 2001 From: Tyler Benson <734411+tylerbenson@users.noreply.github.com> Date: Tue, 24 Jun 2025 15:42:28 -0400 Subject: [PATCH 09/13] Propagate flush to PeriodicMetricReader's metricExporter. (#7410) --- .../metrics/export/PeriodicMetricReader.java | 16 +++++++++- .../export/PeriodicMetricReaderTest.java | 29 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java index a19dbae578..6a07b2cbb1 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReader.java @@ -81,7 +81,21 @@ public final class PeriodicMetricReader implements MetricReader { @Override public CompletableResultCode forceFlush() { - return scheduled.doRun(); + CompletableResultCode result = new CompletableResultCode(); + CompletableResultCode doRunResult = scheduled.doRun(); + doRunResult.whenComplete( + () -> { + CompletableResultCode flushResult = exporter.flush(); + flushResult.whenComplete( + () -> { + if (doRunResult.isSuccess() && flushResult.isSuccess()) { + result.succeed(); + } else { + result.fail(); + } + }); + }); + return result; } @Override diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReaderTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReaderTest.java index 03c8d05cfa..c9093d104f 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReaderTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/export/PeriodicMetricReaderTest.java @@ -154,6 +154,35 @@ class PeriodicMetricReaderTest { } } + @Test + void forceflush_callsFlush() { + MetricExporter metricExporter = mock(MetricExporter.class); + when(metricExporter.export(any())) + .thenReturn(CompletableResultCode.ofSuccess()) + .thenReturn(CompletableResultCode.ofSuccess()) + .thenThrow(new RuntimeException("Export Failed!")); + when(metricExporter.flush()) + .thenReturn(CompletableResultCode.ofSuccess()) + .thenReturn(CompletableResultCode.ofFailure()) + .thenReturn(CompletableResultCode.ofSuccess()); + when(metricExporter.shutdown()).thenReturn(CompletableResultCode.ofSuccess()); + + PeriodicMetricReader reader = + PeriodicMetricReader.builder(metricExporter) + .setInterval(Duration.ofNanos(Long.MAX_VALUE)) + .build(); + + try { + reader.register(collectionRegistration); + assertThat(reader.forceFlush().join(10, TimeUnit.SECONDS).isSuccess()).isTrue(); + assertThat(reader.forceFlush().join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + assertThat(reader.forceFlush().join(10, TimeUnit.SECONDS).isSuccess()).isFalse(); + } finally { + reader.shutdown(); + } + verify(metricExporter, times(3)).flush(); + } + @Test @Timeout(2) @SuppressLogger(PeriodicMetricReader.class) From 11e424de8d00d266ba2e7e99f783dbc5be81412d Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 24 Jun 2025 12:42:42 -0700 Subject: [PATCH 10/13] Slightly faster CodeQL (#7414) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> --- .github/workflows/codeql.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5f5d2a7ab9..740ae160f7 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -12,7 +12,7 @@ on: - release/* - benchmarks schedule: - - cron: "29 13 * * 2" # weekly at 13:29 UTC on Tuesday + - cron: "23 16 * * 2" # weekly at 16:23 UTC on Tuesday permissions: contents: read @@ -23,28 +23,37 @@ jobs: contents: read actions: read # for github/codeql-action/init to get workflow details security-events: write # for github/codeql-action/analyze to upload SARIF results + strategy: + fail-fast: false + matrix: + include: + - language: actions + - language: java runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up Java 17 + if: matrix.language == 'java' uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 with: distribution: temurin java-version: 17 - name: Set up gradle + if: matrix.language == 'java' uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 - name: Initialize CodeQL uses: github/codeql-action/init@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 with: - languages: java, actions + languages: ${{ matrix.language }} # using "latest" helps to keep up with the latest Kotlin support # see https://github.com/github/codeql-action/issues/1555#issuecomment-1452228433 tools: latest - name: Assemble + if: matrix.language == 'java' # --no-build-cache is required for codeql to analyze all modules # --no-daemon is required for codeql to observe the compilation # (see https://docs.github.com/en/code-security/codeql-cli/getting-started-with-the-codeql-cli/preparing-your-code-for-codeql-analysis#specifying-build-commands) @@ -52,3 +61,5 @@ jobs: - name: Perform CodeQL analysis uses: github/codeql-action/analyze@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 + with: + category: "/language:${{matrix.language}}" \ No newline at end of file From 9262a81432267fdf19d5299d7963651ebf1dc63c Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:42:53 -0500 Subject: [PATCH 11/13] Update to declarative config 1.0-rc.1 (#7436) --- .../DeclarativeConfigurationTest.java | 2 +- .../DeclarativeConfigurationTest.java | 4 +- sdk-extensions/incubator/build.gradle.kts | 2 +- .../OpenTelemetryConfigurationFactory.java | 10 ++- .../fileconfig/ServiceResourceDetector.java | 51 +++++++++++++++ ...toconfigure.spi.internal.ComponentProvider | 1 + .../DeclarativeConfigurationCreateTest.java | 6 +- .../DeclarativeConfigurationParseTest.java | 16 ++--- ...OpenTelemetryConfigurationFactoryTest.java | 51 +++++++++++---- .../ServiceResourceDetectorTest.java | 64 +++++++++++++++++++ .../YamlDeclarativeConfigPropertiesTest.java | 4 +- 11 files changed, 177 insertions(+), 34 deletions(-) create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetector.java create mode 100644 sdk-extensions/incubator/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetectorTest.java diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java index 85a6ab085f..c5e6c15066 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java @@ -23,7 +23,7 @@ class DeclarativeConfigurationTest { @Test void configFile(@TempDir Path tempDir) throws IOException { String yaml = - "file_format: \"0.4\"\n" + "file_format: \"1.0-rc.1\"\n" + "resource:\n" + " attributes:\n" + " - name: service.name\n" 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 345614ffc4..f92c1027cc 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 @@ -62,7 +62,7 @@ class DeclarativeConfigurationTest { @BeforeEach void setup() throws IOException { String yaml = - "file_format: \"0.4\"\n" + "file_format: \"1.0-rc.1\"\n" + "resource:\n" + " attributes:\n" + " - name: service.name\n" @@ -199,7 +199,7 @@ class DeclarativeConfigurationTest { @Test void configFile_Error(@TempDir Path tempDir) throws IOException { String yaml = - "file_format: \"0.4\"\n" + "file_format: \"1.0-rc.1\"\n" + "resource:\n" + " attributes:\n" + " - name: service.name\n" diff --git a/sdk-extensions/incubator/build.gradle.kts b/sdk-extensions/incubator/build.gradle.kts index 9ed2927a24..1bb858d699 100644 --- a/sdk-extensions/incubator/build.gradle.kts +++ b/sdk-extensions/incubator/build.gradle.kts @@ -57,7 +57,7 @@ dependencies { // 7. deleteJs2pTmp - delete tmp directory // ... proceed with normal sourcesJar, compileJava, etc -val configurationTag = "0.4.0" +val configurationTag = "1.0.0-rc.1" val configurationRef = "refs/tags/v$configurationTag" // Replace with commit SHA to point to experiment with a specific commit val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip" val buildDirectory = layout.buildDirectory.asFile.get() 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 a64e0b07de..313e5d50b7 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 @@ -11,11 +11,12 @@ import io.opentelemetry.sdk.OpenTelemetrySdkBuilder; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.resources.Resource; import java.util.Objects; +import java.util.regex.Pattern; final class OpenTelemetryConfigurationFactory implements Factory { - private static final String CURRENT_SUPPORTED_FILE_FORMAT = "0.4"; + private static final Pattern SUPPORTED_FILE_FORMATS = Pattern.compile("^(0.4)|(1.0(-rc.\\d*)?)$"); private static final OpenTelemetryConfigurationFactory INSTANCE = new OpenTelemetryConfigurationFactory(); @@ -30,10 +31,13 @@ final class OpenTelemetryConfigurationFactory public OpenTelemetrySdk create( OpenTelemetryConfigurationModel model, DeclarativeConfigContext context) { OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder(); - if (!CURRENT_SUPPORTED_FILE_FORMAT.equals(model.getFileFormat())) { + String fileFormat = model.getFileFormat(); + if (fileFormat == null || !SUPPORTED_FILE_FORMATS.matcher(fileFormat).matches()) { throw new DeclarativeConfigException( - "Unsupported file format. Supported formats include: " + CURRENT_SUPPORTED_FILE_FORMAT); + "Unsupported file format. Supported formats include 0.4, 1.0*"); } + // TODO(jack-berg): log warning if version is not exact match, which may result in unexpected + // behavior for experimental properties. if (Objects.equals(Boolean.TRUE, model.getDisabled())) { return builder.build(); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetector.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetector.java new file mode 100644 index 0000000000..a8077032ec --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetector.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.resources.ResourceBuilder; +import java.util.Collections; +import java.util.UUID; + +public class ServiceResourceDetector implements ComponentProvider { + + private static final AttributeKey SERVICE_NAME = AttributeKey.stringKey("service.name"); + private static final AttributeKey SERVICE_INSTANCE_ID = + AttributeKey.stringKey("service.instance.id"); + + // multiple calls to this resource provider should return the same value + private static final String RANDOM_SERVICE_INSTANCE_ID = UUID.randomUUID().toString(); + + @Override + public Class getType() { + return Resource.class; + } + + @Override + public String getName() { + return "service"; + } + + @Override + public Resource create(DeclarativeConfigProperties config) { + ResourceBuilder builder = Resource.builder(); + + ConfigProperties properties = DefaultConfigProperties.create(Collections.emptyMap()); + String serviceName = properties.getString("otel.service.name"); + if (serviceName != null) { + builder.put(SERVICE_NAME, serviceName).build(); + } + + builder.put(SERVICE_INSTANCE_ID, RANDOM_SERVICE_INSTANCE_ID); + + return builder.build(); + } +} diff --git a/sdk-extensions/incubator/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/sdk-extensions/incubator/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider new file mode 100644 index 0000000000..a1a361a5f3 --- /dev/null +++ b/sdk-extensions/incubator/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -0,0 +1 @@ +io.opentelemetry.sdk.extension.incubator.fileconfig.ServiceResourceDetector 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 2429ae150a..62ee078286 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 @@ -106,7 +106,7 @@ class DeclarativeConfigurationCreateTest { // exporter with OTLP exporter, following by invalid batch exporter which references invalid // exporter "foo". String yaml = - "file_format: \"0.4\"\n" + "file_format: \"1.0-rc.1\"\n" + "logger_provider:\n" + " processors:\n" + " - batch:\n" @@ -133,7 +133,7 @@ class DeclarativeConfigurationCreateTest { @Test void parseAndCreate_EmptyComponentProviderConfig() { String yaml = - "file_format: \"0.4\"\n" + "file_format: \"1.0-rc.1\"\n" + "logger_provider:\n" + " processors:\n" + " - test:\n" @@ -151,7 +151,7 @@ class DeclarativeConfigurationCreateTest { @Test void create_ModelCustomizer() { OpenTelemetryConfigurationModel model = new OpenTelemetryConfigurationModel(); - model.withFileFormat("0.4"); + model.withFileFormat("1.0-rc.1"); model.withTracerProvider( new TracerProviderModel() .withProcessors( diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationParseTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationParseTest.java index 32a8ad878b..0147cf8b68 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationParseTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationParseTest.java @@ -113,7 +113,7 @@ class DeclarativeConfigurationParseTest { void parse_KitchenSinkExampleFile() throws IOException { OpenTelemetryConfigurationModel expected = new OpenTelemetryConfigurationModel(); - expected.withFileFormat("0.4"); + expected.withFileFormat("1.0-rc.1"); expected.withDisabled(false); expected.withLogLevel("info"); @@ -171,9 +171,9 @@ class DeclarativeConfigurationParseTest { new ExperimentalResourceDetectorModel() .withAdditionalProperty("host", null), new ExperimentalResourceDetectorModel() - .withAdditionalProperty("os", null), + .withAdditionalProperty("process", null), new ExperimentalResourceDetectorModel() - .withAdditionalProperty("process", null)))) + .withAdditionalProperty("service", null)))) .withSchemaUrl("https://opentelemetry.io/schemas/1.16.0"); expected.withResource(resource); @@ -705,7 +705,7 @@ class DeclarativeConfigurationParseTest { OpenTelemetryConfigurationModel config = DeclarativeConfiguration.parse(configExampleFile); // General config - assertThat(config.getFileFormat()).isEqualTo("0.4"); + assertThat(config.getFileFormat()).isEqualTo("1.0-rc.1"); assertThat(config.getResource()).isEqualTo(resource); assertThat(config.getAttributeLimits()).isEqualTo(attributeLimits); assertThat(config.getPropagator()).isEqualTo(propagator); @@ -770,7 +770,7 @@ class DeclarativeConfigurationParseTest { @Test void parse_nullValuesParsedToEmptyObjects() { String objectPlaceholderString = - "file_format: \"0.4\"\n" + "file_format: \"1.0-rc.1\"\n" + "tracer_provider:\n" + " processors:\n" + " - batch:\n" @@ -788,7 +788,7 @@ class DeclarativeConfigurationParseTest { new ByteArrayInputStream(objectPlaceholderString.getBytes(StandardCharsets.UTF_8))); String noOjbectPlaceholderString = - "file_format: \"0.4\"\n" + "file_format: \"1.0-rc.1\"\n" + "tracer_provider:\n" + " processors:\n" + " - batch:\n" @@ -986,7 +986,7 @@ class DeclarativeConfigurationParseTest { @Test void read_WithEnvironmentVariables() { String yaml = - "file_format: \"0.4\"\n" + "file_format: \"1.0-rc.1\"\n" + "tracer_provider:\n" + " processors:\n" + " - batch:\n" @@ -1005,7 +1005,7 @@ class DeclarativeConfigurationParseTest { assertThat(model) .isEqualTo( new OpenTelemetryConfigurationModel() - .withFileFormat("0.4") + .withFileFormat("1.0-rc.1") .withTracerProvider( new TracerProviderModel() .withProcessors( 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 16ec2c284d..ba535627c0 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 @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; @@ -63,8 +64,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class OpenTelemetryConfigurationFactoryTest { @@ -74,23 +79,41 @@ class OpenTelemetryConfigurationFactoryTest { new DeclarativeConfigContext( SpiHelper.create(OpenTelemetryConfigurationFactoryTest.class.getClassLoader())); - @Test - void create_InvalidFileFormat() { - List testCases = - Arrays.asList( - new OpenTelemetryConfigurationModel(), - new OpenTelemetryConfigurationModel().withFileFormat("1")); + @ParameterizedTest + @MethodSource("fileFormatArgs") + void create_FileFormat(String fileFormat, boolean isValid) { + OpenTelemetryConfigurationModel model = + new OpenTelemetryConfigurationModel().withFileFormat(fileFormat); - List closeables = new ArrayList<>(); - for (OpenTelemetryConfigurationModel testCase : testCases) { + if (isValid) { + assertThatCode(() -> OpenTelemetryConfigurationFactory.getInstance().create(model, context)) + .doesNotThrowAnyException(); + } else { assertThatThrownBy( - () -> OpenTelemetryConfigurationFactory.getInstance().create(testCase, context)) + () -> OpenTelemetryConfigurationFactory.getInstance().create(model, context)) .isInstanceOf(DeclarativeConfigException.class) - .hasMessage("Unsupported file format. Supported formats include: 0.4"); - cleanup.addCloseables(closeables); + .hasMessage("Unsupported file format. Supported formats include 0.4, 1.0*"); } } + private static Stream fileFormatArgs() { + return Stream.of( + // Invalid file formats + Arguments.of(null, false), + Arguments.of("0.3", false), + Arguments.of("a0.4", false), + Arguments.of("0.4a", false), + Arguments.of("foo", false), + Arguments.of("1.0-rc.a", false), + Arguments.of("1.0.0", false), + Arguments.of("1.0.3", false), + // Valid file formats + Arguments.of("0.4", true), + Arguments.of("1.0-rc.1", true), + Arguments.of("1.0-rc.2", true), + Arguments.of("1.0", true)); + } + @Test void create_Defaults() { List closeables = new ArrayList<>(); @@ -99,7 +122,7 @@ class OpenTelemetryConfigurationFactoryTest { OpenTelemetrySdk sdk = OpenTelemetryConfigurationFactory.getInstance() - .create(new OpenTelemetryConfigurationModel().withFileFormat("0.4"), context); + .create(new OpenTelemetryConfigurationModel().withFileFormat("1.0-rc.1"), context); cleanup.addCloseable(sdk); cleanup.addCloseables(closeables); @@ -116,7 +139,7 @@ class OpenTelemetryConfigurationFactoryTest { OpenTelemetryConfigurationFactory.getInstance() .create( new OpenTelemetryConfigurationModel() - .withFileFormat("0.4") + .withFileFormat("1.0-rc.1") .withDisabled(true) // Logger provider configuration should be ignored since SDK is disabled .withLoggerProvider( @@ -210,7 +233,7 @@ class OpenTelemetryConfigurationFactoryTest { OpenTelemetryConfigurationFactory.getInstance() .create( new OpenTelemetryConfigurationModel() - .withFileFormat("0.4") + .withFileFormat("1.0-rc.1") .withPropagator( new PropagatorModel() .withCompositeList("tracecontext,baggage,ottrace,b3multi,b3,jaeger")) diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetectorTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetectorTest.java new file mode 100644 index 0000000000..4778fe1b61 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetectorTest.java @@ -0,0 +1,64 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.fileconfig; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.sdk.resources.Resource; +import java.util.Objects; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.ClearSystemProperty; + +class ServiceResourceDetectorTest { + + @Test + void getTypeAndName() { + ServiceResourceDetector detector = new ServiceResourceDetector(); + + assertThat(detector.getType()).isEqualTo(Resource.class); + assertThat(detector.getName()).isEqualTo("service"); + } + + @Test + @ClearSystemProperty(key = "otel.service.name") + void create_SystemPropertySet() { + System.setProperty("otel.service.name", "test"); + + assertThat(new ServiceResourceDetector().create(DeclarativeConfigProperties.empty())) + .satisfies( + resource -> { + Attributes attributes = resource.getAttributes(); + assertThat(attributes.get(AttributeKey.stringKey("service.name"))).isEqualTo("test"); + assertThatCode( + () -> + UUID.fromString( + Objects.requireNonNull( + attributes.get(AttributeKey.stringKey("service.instance.id"))))) + .doesNotThrowAnyException(); + }); + } + + @Test + void create_NoSystemProperty() { + assertThat(new ServiceResourceDetector().create(DeclarativeConfigProperties.empty())) + .satisfies( + resource -> { + Attributes attributes = resource.getAttributes(); + assertThat(attributes.get(AttributeKey.stringKey("service.name"))).isNull(); + assertThatCode( + () -> + UUID.fromString( + Objects.requireNonNull( + attributes.get(AttributeKey.stringKey("service.instance.id"))))) + .doesNotThrowAnyException(); + }); + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java index 7f1c3cb3cc..82a2d38475 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigPropertiesTest.java @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; class YamlDeclarativeConfigPropertiesTest { private static final String extendedSchema = - "file_format: \"0.4\"\n" + "file_format: \"1.0-rc.1\"\n" + "disabled: false\n" + "\n" + "resource:\n" @@ -69,7 +69,7 @@ class YamlDeclarativeConfigPropertiesTest { @Test void configurationSchema() { // Validate can read declarative configuration schema properties - assertThat(structuredConfigProps.getString("file_format")).isEqualTo("0.4"); + assertThat(structuredConfigProps.getString("file_format")).isEqualTo("1.0-rc.1"); DeclarativeConfigProperties resourceProps = structuredConfigProps.getStructured("resource"); assertThat(resourceProps).isNotNull(); List resourceAttributesList = From 9329f8675e0fafe63550773fb8978c04c31a4a31 Mon Sep 17 00:00:00 2001 From: Paul Nienaber Date: Tue, 24 Jun 2025 12:43:46 -0700 Subject: [PATCH 12/13] fixes #7427: Patch LazyStorage to pass its ClassLoader to ServiceLoader (#7424) --- .../src/main/java/io/opentelemetry/context/LazyStorage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/context/src/main/java/io/opentelemetry/context/LazyStorage.java b/context/src/main/java/io/opentelemetry/context/LazyStorage.java index 1727ee06fe..5cce59d253 100644 --- a/context/src/main/java/io/opentelemetry/context/LazyStorage.java +++ b/context/src/main/java/io/opentelemetry/context/LazyStorage.java @@ -104,7 +104,8 @@ final class LazyStorage { } List providers = new ArrayList<>(); - for (ContextStorageProvider provider : ServiceLoader.load(ContextStorageProvider.class)) { + for (ContextStorageProvider provider : + ServiceLoader.load(ContextStorageProvider.class, LazyStorage.class.getClassLoader())) { if (provider .getClass() .getName() From 0ca502bddda850eee413d5de6c8ab56452374312 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:13:33 -0500 Subject: [PATCH 13/13] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.19.1 (#7422) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- dependencyManagement/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index d1ec2142f7..b01c72f28a 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -13,7 +13,7 @@ val DEPENDENCY_BOMS = listOf( // (which is EPL licensed) or armeria bom (which is Apache licensed but is getting flagged // by FOSSA for containing EPL-licensed) - "com.fasterxml.jackson:jackson-bom:2.19.0", + "com.fasterxml.jackson:jackson-bom:2.19.1", "com.google.guava:guava-bom:33.4.8-jre", "com.google.protobuf:protobuf-bom:4.31.1", "com.squareup.okhttp3:okhttp-bom:4.12.0",