From 0a95b73784ce537fbf4c308c3ee044aae31ba1f0 Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Wed, 21 Oct 2026 13:47:20 +0200 Subject: [PATCH 1/4] feat(ffe): Add the agent bridge instrumentation for the dd-openfeature SDK Instrument the SDK bridge detection to connect the SDK to an agent Feature Flags backend registered on the bootstrap gateway. The backend interface only carries JDK types. No backend is registered yet, so the SDK keeps using its own fallback. Co-Authored-By: Claude Opus 5.5 --- .github/CODEOWNERS | 7 +- .../dd-openfeature-1.69/build.gradle | 38 +++++ .../dd-openfeature-1.69/gradle.lockfile | 132 ++++++++++++++++++ .../DDOpenFeatureInstrumentation.java | 55 ++++++++ .../openfeature/AgentConfigurationSource.java | 19 +++ .../openfeature/AgentEventProxy.java | 22 +++ .../openfeature/AgentHealthMetrics.java | 19 +++ .../openfeature/AgentSpanEnricher.java | 25 ++++ .../openfeature/DetectBridgeAdvice.java | 11 ++ .../openfeature/JavaAgentBridge.java | 70 ++++++++++ ...tureInstrumentationDisabledForkedTest.java | 26 ++++ .../DDOpenFeatureInstrumentationTest.java | 103 ++++++++++++++ metadata/agent-jar-checks.properties | 1 + metadata/supported-configurations.json | 8 ++ .../featureflag/FeatureFlaggingGateway.java | 88 ++++++++++++ settings.gradle.kts | 1 + 16 files changed, 622 insertions(+), 3 deletions(-) create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/build.gradle create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/gradle.lockfile create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentation.java create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentConfigurationSource.java create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentEventProxy.java create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentHealthMetrics.java create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentSpanEnricher.java create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/JavaAgentBridge.java create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationDisabledForkedTest.java create mode 100644 dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationTest.java diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 09e44b790e1..f7dec0f13c9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -399,9 +399,10 @@ **/kafka*/**/*Iast* @DataDog/asm-java @DataDog/data-streams-monitoring @DataDog/apm-idm-java # @DataDog/feature-flagging-and-experimentation-sdk -/dd-openfeature/ @DataDog/feature-flagging-and-experimentation-sdk -/dd-smoke-tests/openfeature/ @DataDog/feature-flagging-and-experimentation-sdk -/products/feature-flagging/ @DataDog/feature-flagging-and-experimentation-sdk +/dd-java-agent/instrumentation/datadog/openfeature/ @DataDog/feature-flagging-and-experimentation-sdk +/dd-openfeature/ @DataDog/feature-flagging-and-experimentation-sdk +/dd-smoke-tests/openfeature/ @DataDog/feature-flagging-and-experimentation-sdk +/products/feature-flagging/ @DataDog/feature-flagging-and-experimentation-sdk # @DataDog/profiling-java /dd-java-agent/ddprof-lib/ @DataDog/profiling-java diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/build.gradle b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/build.gradle new file mode 100644 index 00000000000..5a8f8b3fd41 --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/build.gradle @@ -0,0 +1,38 @@ +plugins { + id 'dd-trace-java.module.instrumentation' + id 'idea' +} + +idea { + module { + jdkName = '11' + } +} + +// TODO Add a muzzle pass directive on com.datadoghq:dd-openfeature once the SDK is published. + +tracerJava { + addSourceSetFor(JavaVersion.VERSION_11) +} + +testJvmConstraints { + minJavaVersion = JavaVersion.VERSION_11 +} + +dependencies { + main_java11CompileOnly project(':dd-openfeature') + main_java11CompileOnly project(':products:feature-flagging:feature-flagging-bootstrap') + main_java11CompileOnly libs.spotbugs.annotations + + testImplementation project(':dd-openfeature') + testImplementation project(':products:feature-flagging:feature-flagging-bootstrap') + testImplementation libs.bundles.mockito +} + +tasks.named("compileMain_java11Java", JavaCompile) { + configureCompiler(it, JavaVersion.VERSION_11) +} + +tasks.named("compileTestJava", JavaCompile) { + configureCompiler(it, JavaVersion.VERSION_11) +} diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/gradle.lockfile b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/gradle.lockfile new file mode 100644 index 00000000000..766eb3c9ac9 --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/gradle.lockfile @@ -0,0 +1,132 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +# To regenerate this file, run: ./gradlew :dd-java-agent:instrumentation:datadog:openfeature:dd-openfeature-1.69:dependencies --write-locks +cafe.cryptography:curve25519-elisabeth:0.1.0=testRuntimeClasspath +cafe.cryptography:ed25519-elisabeth:0.1.0=testRuntimeClasspath +ch.qos.logback:logback-classic:1.2.13=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.2.13=testCompileClasspath,testRuntimeClasspath +com.blogspot.mydailyjava:weak-lock-free:0.17=buildTimeInstrumentationPlugin,compileClasspath,main_java11CompileClasspath,main_java11RuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.datadoghq.okhttp3:okhttp:3.12.15=testCompileClasspath,testRuntimeClasspath +com.datadoghq.okio:okio:1.17.6=testCompileClasspath,testRuntimeClasspath +com.datadoghq:dd-instrument-java:0.0.6=buildTimeInstrumentationPlugin,compileClasspath,main_java11CompileClasspath,main_java11RuntimeClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.datadoghq:dd-javac-plugin-client:0.2.2=buildTimeInstrumentationPlugin,compileClasspath,main_java11CompileClasspath,main_java11RuntimeClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.datadoghq:dd-openfeature:1.67.0=legacySdk +com.datadoghq:java-dogstatsd-client:4.4.5=testRuntimeClasspath +com.datadoghq:sketches-java:0.8.3=testRuntimeClasspath +com.fasterxml.jackson.core:jackson-core:2.20.0=main_java11CompileClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson:jackson-bom:2.20.0=main_java11CompileClasspath,testCompileClasspath,testRuntimeClasspath +com.github.javaparser:javaparser-core:3.25.6=codenarc +com.github.jnr:jffi:1.3.15=testRuntimeClasspath +com.github.jnr:jnr-a64asm:1.0.0=testRuntimeClasspath +com.github.jnr:jnr-constants:0.10.4=testRuntimeClasspath +com.github.jnr:jnr-enxio:0.32.20=testRuntimeClasspath +com.github.jnr:jnr-ffi:2.2.19=testRuntimeClasspath +com.github.jnr:jnr-posix:3.1.22=testRuntimeClasspath +com.github.jnr:jnr-unixsocket:0.38.25=testRuntimeClasspath +com.github.jnr:jnr-x86asm:1.0.2=testRuntimeClasspath +com.github.spotbugs:spotbugs-annotations:4.10.4=compileClasspath,main_java11CompileClasspath,spotbugs +com.github.spotbugs:spotbugs:4.10.4=spotbugs +com.github.stephenc.jcip:jcip-annotations:1.0-1=spotbugs +com.google.auto.service:auto-service-annotations:1.1.1=annotationProcessor,compileClasspath,testAnnotationProcessor,testCompileClasspath +com.google.auto.service:auto-service:1.1.1=annotationProcessor,testAnnotationProcessor +com.google.auto:auto-common:1.2.1=annotationProcessor,testAnnotationProcessor +com.google.code.findbugs:jsr305:3.0.2=annotationProcessor,compileClasspath,main_java11CompileClasspath,spotbugs,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath +com.google.code.gson:gson:2.14.0=spotbugs +com.google.errorprone:error_prone_annotations:2.18.0=annotationProcessor,testAnnotationProcessor +com.google.errorprone:error_prone_annotations:2.47.0=testCompileClasspath,testRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.48.0=spotbugs +com.google.guava:failureaccess:1.0.1=annotationProcessor,testAnnotationProcessor +com.google.guava:failureaccess:1.0.3=testCompileClasspath,testRuntimeClasspath +com.google.guava:guava:32.0.1-jre=annotationProcessor,testAnnotationProcessor +com.google.guava:guava:33.6.0-jre=testCompileClasspath,testRuntimeClasspath +com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:2.8=annotationProcessor,testAnnotationProcessor +com.google.j2objc:j2objc-annotations:3.1=testCompileClasspath,testRuntimeClasspath +com.google.re2j:re2j:1.8=testRuntimeClasspath +com.squareup.moshi:moshi:1.11.0=testCompileClasspath,testRuntimeClasspath +com.squareup.okhttp3:logging-interceptor:3.12.12=testCompileClasspath,testRuntimeClasspath +com.squareup.okhttp3:okhttp:3.12.12=testCompileClasspath,testRuntimeClasspath +com.squareup.okio:okio:1.17.5=testCompileClasspath,testRuntimeClasspath +com.thoughtworks.qdox:qdox:1.12.1=codenarc +commons-fileupload:commons-fileupload:1.5=testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.11.0=testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.21.0=spotbugs +de.thetaphi:forbiddenapis:3.11=compileClasspath,testCompileClasspath,testRuntimeClasspath +dev.openfeature:sdk:1.23.0=main_java11CompileClasspath,testCompileClasspath,testRuntimeClasspath +io.leangen.geantyref:geantyref:1.3.16=testRuntimeClasspath +io.opentelemetry:opentelemetry-api:1.66.0=testRuntimeClasspath +io.opentelemetry:opentelemetry-common:1.66.0=testRuntimeClasspath +io.opentelemetry:opentelemetry-context:1.66.0=testRuntimeClasspath +io.sqreen:libsqreen:17.5.0=testRuntimeClasspath +javax.servlet:javax.servlet-api:3.1.0=testCompileClasspath,testRuntimeClasspath +jaxen:jaxen:2.0.6=spotbugs +junit:junit:4.13.2=testRuntimeClasspath +net.bytebuddy:byte-buddy-agent:1.18.12=buildTimeInstrumentationPlugin,compileClasspath,main_java11CompileClasspath,main_java11RuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +net.bytebuddy:byte-buddy:1.18.12=buildTimeInstrumentationPlugin,compileClasspath,main_java11CompileClasspath,main_java11RuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +net.java.dev.jna:jna-platform:5.8.0=testRuntimeClasspath +net.java.dev.jna:jna:5.8.0=testRuntimeClasspath +net.sf.saxon:Saxon-HE:12.10=spotbugs +org.apache.ant:ant-antlr:1.10.14=codenarc +org.apache.ant:ant-junit:1.10.14=codenarc +org.apache.bcel:bcel:6.12.0=spotbugs +org.apache.commons:commons-lang3:3.20.0=spotbugs +org.apache.commons:commons-text:1.15.0=spotbugs +org.apache.logging.log4j:log4j-api:2.26.1=spotbugs +org.apache.logging.log4j:log4j-core:2.26.1=spotbugs +org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testRuntimeClasspath +org.checkerframework:checker-qual:3.33.0=annotationProcessor,testAnnotationProcessor +org.codehaus.groovy:groovy-ant:3.0.23=codenarc +org.codehaus.groovy:groovy-docgenerator:3.0.23=codenarc +org.codehaus.groovy:groovy-groovydoc:3.0.23=codenarc +org.codehaus.groovy:groovy-json:3.0.23=codenarc +org.codehaus.groovy:groovy-json:3.0.25=testCompileClasspath,testRuntimeClasspath +org.codehaus.groovy:groovy-templates:3.0.23=codenarc +org.codehaus.groovy:groovy-xml:3.0.23=codenarc +org.codehaus.groovy:groovy:3.0.23=codenarc +org.codehaus.groovy:groovy:3.0.25=testCompileClasspath,testRuntimeClasspath +org.codenarc:CodeNarc:3.7.0=codenarc +org.dom4j:dom4j:2.2.0=spotbugs +org.gmetrics:GMetrics:2.1.0=codenarc +org.hamcrest:hamcrest-core:1.3=testRuntimeClasspath +org.hamcrest:hamcrest:3.0=testCompileClasspath,testRuntimeClasspath +org.jctools:jctools-core-jdk11:4.0.6=testRuntimeClasspath +org.jctools:jctools-core:4.0.6=testRuntimeClasspath +org.jspecify:jspecify:1.0.0=testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-api:5.14.1=testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-engine:5.14.1=testRuntimeClasspath +org.junit.jupiter:junit-jupiter-params:5.14.1=testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter:5.14.1=testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-commons:1.14.1=testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-engine:1.14.1=testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-launcher:1.14.1=testRuntimeClasspath +org.junit.platform:junit-platform-runner:1.14.1=testRuntimeClasspath +org.junit.platform:junit-platform-suite-api:1.14.1=testRuntimeClasspath +org.junit.platform:junit-platform-suite-commons:1.14.1=testRuntimeClasspath +org.junit:junit-bom:5.14.1=testCompileClasspath,testRuntimeClasspath +org.mockito:mockito-core:4.4.0=testCompileClasspath,testRuntimeClasspath +org.mockito:mockito-junit-jupiter:4.4.0=testCompileClasspath,testRuntimeClasspath +org.objenesis:objenesis:3.3=testCompileClasspath,testRuntimeClasspath +org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath +org.ow2.asm:asm-analysis:9.10.1=spotbugs +org.ow2.asm:asm-analysis:9.7.1=testRuntimeClasspath +org.ow2.asm:asm-commons:9.10.1=spotbugs,testRuntimeClasspath +org.ow2.asm:asm-tree:9.10.1=spotbugs,testRuntimeClasspath +org.ow2.asm:asm-util:9.10.1=spotbugs +org.ow2.asm:asm-util:9.7.1=testRuntimeClasspath +org.ow2.asm:asm:9.10.1=buildTimeInstrumentationPlugin,compileClasspath,main_java11CompileClasspath,main_java11RuntimeClasspath,muzzleTooling,runtimeClasspath,spotbugs,testCompileClasspath,testRuntimeClasspath +org.slf4j:jcl-over-slf4j:1.7.30=testCompileClasspath,testRuntimeClasspath +org.slf4j:jul-to-slf4j:1.7.30=testCompileClasspath,testRuntimeClasspath +org.slf4j:log4j-over-slf4j:1.7.30=testCompileClasspath,testRuntimeClasspath +org.slf4j:slf4j-api:1.7.30=buildTimeInstrumentationPlugin,compileClasspath,main_java11RuntimeClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath +org.slf4j:slf4j-api:2.0.17=spotbugsSlf4j +org.slf4j:slf4j-api:2.0.18=spotbugs +org.slf4j:slf4j-api:2.0.19=main_java11CompileClasspath,testCompileClasspath,testRuntimeClasspath +org.slf4j:slf4j-simple:2.0.17=spotbugsSlf4j +org.snakeyaml:snakeyaml-engine:2.9=buildTimeInstrumentationPlugin,main_java11RuntimeClasspath,muzzleTooling,runtimeClasspath,testRuntimeClasspath +org.spockframework:spock-bom:2.4-groovy-3.0=testCompileClasspath,testRuntimeClasspath +org.spockframework:spock-core:2.4-groovy-3.0=testCompileClasspath,testRuntimeClasspath +org.tabletest:tabletest-junit:1.2.2=testCompileClasspath,testRuntimeClasspath +org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath +org.xmlresolver:xmlresolver:5.3.3=spotbugs +empty=main_java11AnnotationProcessor,spotbugsPlugins diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentation.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentation.java new file mode 100644 index 00000000000..5b47eaeb6c4 --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentation.java @@ -0,0 +1,55 @@ +package datadog.trace.instrumentation.openfeature; + +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.FEATURE_FLAGS; +import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.isStatic; +import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; + +import com.google.auto.service.AutoService; +import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.agent.tooling.InstrumenterModule; +import java.util.Set; + +/** + * Connects the {@code dd-openfeature} SDK to the agent: Remote Configuration, the event platform + * proxy, health metrics and span enrichment. + */ +@SuppressWarnings("unused") +@AutoService(InstrumenterModule.class) +public class DDOpenFeatureInstrumentation extends InstrumenterModule + implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice { + + public DDOpenFeatureInstrumentation() { + super("openfeature"); + } + + @Override + public boolean isApplicable(final Set enabledSystems) { + return enabledSystems.contains(FEATURE_FLAGS); + } + + @Override + public String instrumentedType() { + return "com.datadog.openfeature.internal.bridge.AgentBridges"; + } + + @Override + public String[] helperClassNames() { + // Helpers are compiled in the java11 source set, out of reach of helper discovery. + return new String[] { + packageName + ".AgentConfigurationSource", + packageName + ".AgentEventProxy", + packageName + ".AgentHealthMetrics", + packageName + ".AgentSpanEnricher", + packageName + ".JavaAgentBridge", + }; + } + + @Override + public void methodAdvice(final MethodTransformer transformer) { + transformer.applyAdvice( + isMethod().and(isStatic()).and(named("detect")).and(takesNoArguments()), + packageName + ".DetectBridgeAdvice"); + } +} diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentConfigurationSource.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentConfigurationSource.java new file mode 100644 index 00000000000..40ec60469e8 --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentConfigurationSource.java @@ -0,0 +1,19 @@ +package datadog.trace.instrumentation.openfeature; + +import com.datadog.openfeature.internal.bridge.ConfigurationSource; +import datadog.trace.api.featureflag.FeatureFlaggingGateway; +import java.util.function.Consumer; + +/** Receives the flag configuration from the agent Remote Configuration client. */ +public final class AgentConfigurationSource implements ConfigurationSource { + private final FeatureFlaggingGateway.Backend backend; + + AgentConfigurationSource(final FeatureFlaggingGateway.Backend backend) { + this.backend = backend; + } + + @Override + public AutoCloseable subscribe(final Consumer listener) { + return this.backend.subscribeRemoteConfig(listener); + } +} diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentEventProxy.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentEventProxy.java new file mode 100644 index 00000000000..cd1e4c049de --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentEventProxy.java @@ -0,0 +1,22 @@ +package datadog.trace.instrumentation.openfeature; + +import com.datadog.openfeature.internal.bridge.EventProxyUnavailableException; +import com.datadog.openfeature.internal.bridge.EventTransport; +import datadog.trace.api.featureflag.FeatureFlaggingGateway; +import java.io.IOException; + +/** Posts events through the Datadog Agent event platform proxy. */ +public final class AgentEventProxy implements EventTransport { + private final FeatureFlaggingGateway.Backend backend; + + AgentEventProxy(final FeatureFlaggingGateway.Backend backend) { + this.backend = backend; + } + + @Override + public void post(final String route, final byte[] json) throws IOException { + if (!this.backend.postEvent(route, json)) { + throw new EventProxyUnavailableException("Datadog Agent event platform proxy unavailable"); + } + } +} diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentHealthMetrics.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentHealthMetrics.java new file mode 100644 index 00000000000..69615c45a65 --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentHealthMetrics.java @@ -0,0 +1,19 @@ +package datadog.trace.instrumentation.openfeature; + +import com.datadog.openfeature.internal.bridge.HealthMetrics; +import datadog.trace.api.featureflag.FeatureFlaggingGateway; +import javax.annotation.Nullable; + +/** Reports the SDK health counters through the agent telemetry. */ +public final class AgentHealthMetrics implements HealthMetrics { + private final FeatureFlaggingGateway.Backend backend; + + AgentHealthMetrics(final FeatureFlaggingGateway.Backend backend) { + this.backend = backend; + } + + @Override + public void count(final String metric, final long value, @Nullable final String reason) { + this.backend.count(metric, value, reason); + } +} diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentSpanEnricher.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentSpanEnricher.java new file mode 100644 index 00000000000..8c947158161 --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentSpanEnricher.java @@ -0,0 +1,25 @@ +package datadog.trace.instrumentation.openfeature; + +import com.datadog.openfeature.internal.bridge.SpanEnricher; +import datadog.trace.api.featureflag.FeatureFlaggingGateway; +import javax.annotation.Nullable; + +/** Reflects flag evaluations onto the agent local root span. */ +public final class AgentSpanEnricher implements SpanEnricher { + private final FeatureFlaggingGateway.Backend backend; + + AgentSpanEnricher(final FeatureFlaggingGateway.Backend backend) { + this.backend = backend; + } + + @Override + public void serialId( + final int serialId, final boolean doLog, @Nullable final String targetingKey) { + this.backend.enrichSerialId(serialId, doLog, targetingKey); + } + + @Override + public void runtimeDefault(final String flagKey, @Nullable final Object defaultValue) { + this.backend.enrichRuntimeDefault(flagKey, defaultValue); + } +} diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java new file mode 100644 index 00000000000..d4fba3958ad --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java @@ -0,0 +1,11 @@ +package datadog.trace.instrumentation.openfeature; + +import com.datadog.openfeature.internal.bridge.AgentBridge; +import net.bytebuddy.asm.Advice; + +public class DetectBridgeAdvice { + @Advice.OnMethodExit(suppress = Throwable.class) + public static void detect(@Advice.Return(readOnly = false) AgentBridge bridge) { + bridge = JavaAgentBridge.connect(bridge); + } +} diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/JavaAgentBridge.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/JavaAgentBridge.java new file mode 100644 index 00000000000..4398c1d3caf --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/JavaAgentBridge.java @@ -0,0 +1,70 @@ +package datadog.trace.instrumentation.openfeature; + +import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.EventTransport; +import com.datadog.openfeature.internal.bridge.HealthMetrics; +import com.datadog.openfeature.internal.bridge.ShutdownSource; +import com.datadog.openfeature.internal.bridge.SpanEnricher; +import datadog.trace.api.featureflag.FeatureFlaggingGateway; +import javax.annotation.Nullable; + +/** The bridge backed by the agent Feature Flags backend. */ +public final class JavaAgentBridge implements AgentBridge { + private final FeatureFlaggingGateway.Backend backend; + private final HealthMetrics healthMetrics; + private final SpanEnricher spanEnricher; + + JavaAgentBridge(final FeatureFlaggingGateway.Backend backend) { + this.backend = backend; + this.healthMetrics = new AgentHealthMetrics(backend); + this.spanEnricher = new AgentSpanEnricher(backend); + } + + /** + * Connects the SDK to the agent backend. + * + * @param fallback the bridge to use if the agent backend is not started. + * @return the agent bridge, or the fallback one. + */ + public static AgentBridge connect(final AgentBridge fallback) { + final FeatureFlaggingGateway.Backend backend = FeatureFlaggingGateway.backend(); + return backend == null ? fallback : new JavaAgentBridge(backend); + } + + @Nullable + @Override + public String setting(final String key) { + return this.backend.setting(key); + } + + @Nullable + @Override + public ConfigurationSource remoteConfiguration() { + return this.backend.isRemoteConfigAvailable() + ? new AgentConfigurationSource(this.backend) + : null; + } + + @Nullable + @Override + public EventTransport eventProxy() { + return this.backend.isEventProxyAvailable() ? new AgentEventProxy(this.backend) : null; + } + + @Override + public HealthMetrics healthMetrics() { + return this.healthMetrics; + } + + @Override + public SpanEnricher spanEnricher() { + return this.spanEnricher; + } + + @Override + public ShutdownSource shutdown() { + // TODO Flush the SDK through the agent shutdown. Until then, the SDK uses a JVM shutdown hook. + return null; + } +} diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationDisabledForkedTest.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationDisabledForkedTest.java new file mode 100644 index 00000000000..1dcca26aa0c --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationDisabledForkedTest.java @@ -0,0 +1,26 @@ +package datadog.trace.instrumentation.openfeature; + +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.Mockito.mock; + +import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.AgentBridges; +import datadog.trace.agent.test.AbstractInstrumentationTest; +import datadog.trace.api.featureflag.FeatureFlaggingGateway; +import datadog.trace.test.junit.utils.config.WithConfig; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +@WithConfig(key = "feature.flags.enabled", value = "false") +class DDOpenFeatureInstrumentationDisabledForkedTest extends AbstractInstrumentationTest { + @AfterEach + void unregisterBackend() { + FeatureFlaggingGateway.register(null); + } + + @Test + void doesNotInstrumentWhenFeatureFlagsIsDisabled() { + FeatureFlaggingGateway.register(mock(FeatureFlaggingGateway.Backend.class)); + assertSame(AgentBridge.NONE, AgentBridges.detect()); + } +} diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationTest.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationTest.java new file mode 100644 index 00000000000..492fce5e34d --- /dev/null +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationTest.java @@ -0,0 +1,103 @@ +package datadog.trace.instrumentation.openfeature; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.AgentBridges; +import com.datadog.openfeature.internal.bridge.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.EventProxyUnavailableException; +import com.datadog.openfeature.internal.bridge.EventTransport; +import datadog.trace.agent.test.AbstractInstrumentationTest; +import datadog.trace.api.featureflag.FeatureFlaggingGateway; +import java.util.function.Consumer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +// Bootstrap types are not allowed in test class signatures, so the backend is a local variable. +class DDOpenFeatureInstrumentationTest extends AbstractInstrumentationTest { + @AfterEach + void unregisterBackend() { + FeatureFlaggingGateway.register(null); + } + + @Test + void detectsTheAgentBridge() { + final FeatureFlaggingGateway.Backend backend = mock(FeatureFlaggingGateway.Backend.class); + FeatureFlaggingGateway.register(backend); + assertInstanceOf(JavaAgentBridge.class, AgentBridges.detect()); + } + + @Test + void keepsTheDefaultBridgeWithoutBackend() { + assertSame(AgentBridge.NONE, AgentBridges.detect()); + } + + @Test + void delegatesSettingsAndHealthMetrics() { + final FeatureFlaggingGateway.Backend backend = mock(FeatureFlaggingGateway.Backend.class); + FeatureFlaggingGateway.register(backend); + when(backend.setting("site")).thenReturn("datadoghq.eu"); + final AgentBridge bridge = AgentBridges.detect(); + + assertEquals("datadoghq.eu", bridge.setting("site")); + bridge.healthMetrics().count("metric", 2, "reason"); + verify(backend).count("metric", 2, "reason"); + } + + @Test + void exposesRemoteConfigurationOnlyWhenAvailable() throws Exception { + final FeatureFlaggingGateway.Backend backend = mock(FeatureFlaggingGateway.Backend.class); + FeatureFlaggingGateway.register(backend); + final AgentBridge bridge = AgentBridges.detect(); + assertNull(bridge.remoteConfiguration()); + + when(backend.isRemoteConfigAvailable()).thenReturn(true); + final AutoCloseable subscription = mock(AutoCloseable.class); + when(backend.subscribeRemoteConfig(any())).thenReturn(subscription); + final ConfigurationSource source = bridge.remoteConfiguration(); + final Consumer listener = content -> {}; + + assertSame(subscription, source.subscribe(listener)); + verify(backend).subscribeRemoteConfig(listener); + } + + @Test + void postsThroughTheEventProxyOnlyWhenAvailable() throws Exception { + final FeatureFlaggingGateway.Backend backend = mock(FeatureFlaggingGateway.Backend.class); + FeatureFlaggingGateway.register(backend); + final AgentBridge bridge = AgentBridges.detect(); + assertNull(bridge.eventProxy()); + + when(backend.isEventProxyAvailable()).thenReturn(true); + final EventTransport proxy = bridge.eventProxy(); + final byte[] payload = "{}".getBytes(UTF_8); + when(backend.postEvent("exposures", payload)).thenReturn(true); + proxy.post("exposures", payload); + verify(backend).postEvent("exposures", payload); + + when(backend.postEvent("exposures", payload)).thenReturn(false); + assertThrows(EventProxyUnavailableException.class, () -> proxy.post("exposures", payload)); + } + + @Test + void delegatesSpanEnrichment() { + final FeatureFlaggingGateway.Backend backend = mock(FeatureFlaggingGateway.Backend.class); + FeatureFlaggingGateway.register(backend); + final AgentBridge bridge = AgentBridges.detect(); + + bridge.spanEnricher().serialId(42, true, "user"); + bridge.spanEnricher().runtimeDefault("flag", "default"); + + verify(backend).enrichSerialId(42, true, "user"); + verify(backend).enrichRuntimeDefault("flag", "default"); + } +} diff --git a/metadata/agent-jar-checks.properties b/metadata/agent-jar-checks.properties index 82bc8070731..27b576ea1c4 100644 --- a/metadata/agent-jar-checks.properties +++ b/metadata/agent-jar-checks.properties @@ -128,6 +128,7 @@ expected.integrations = IastInstrumentation,\ ognl,\ okhttp,\ openai-java,\ + openfeature,\ opensearch,\ opentelemetry-annotations,\ opentelemetry-beta,\ diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index b9dc242c780..e0c919b4414 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -8676,6 +8676,14 @@ "aliases": ["DD_TRACE_INTEGRATION_OPENAI_JAVA_ENABLED", "DD_INTEGRATION_OPENAI_JAVA_ENABLED"] } ], + "DD_TRACE_OPENFEATURE_ENABLED": [ + { + "version": "A", + "type": "boolean", + "default": "true", + "aliases": ["DD_TRACE_INTEGRATION_OPENFEATURE_ENABLED", "DD_INTEGRATION_OPENFEATURE_ENABLED"] + } + ], "DD_TRACE_OPENSEARCH_ANALYTICS_ENABLED": [ { "version": "A", diff --git a/products/feature-flagging/feature-flagging-bootstrap/src/main/java/datadog/trace/api/featureflag/FeatureFlaggingGateway.java b/products/feature-flagging/feature-flagging-bootstrap/src/main/java/datadog/trace/api/featureflag/FeatureFlaggingGateway.java index 2a823bd32ef..191841dfabd 100644 --- a/products/feature-flagging/feature-flagging-bootstrap/src/main/java/datadog/trace/api/featureflag/FeatureFlaggingGateway.java +++ b/products/feature-flagging/feature-flagging-bootstrap/src/main/java/datadog/trace/api/featureflag/FeatureFlaggingGateway.java @@ -3,10 +3,12 @@ import datadog.trace.api.featureflag.exposure.ExposureEvent; import datadog.trace.api.featureflag.flagevaluation.FlagEvaluationWriter; import datadog.trace.api.featureflag.ufc.v1.ServerConfiguration; +import java.io.IOException; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import javax.annotation.Nullable; public abstract class FeatureFlaggingGateway { @@ -39,9 +41,27 @@ public interface SpanEnrichmentListener extends Consumer {} new AtomicReference<>(); private static volatile boolean flagEvalEnqueueEnabled = true; + private static volatile Backend backend; private FeatureFlaggingGateway() {} + /** + * Registers the agent backend. + * + * @param registered the backend, or {@code null} to unregister it. + */ + public static void register(@Nullable final Backend registered) { + backend = registered; + } + + /** + * @return the agent backend, or {@code null} if Feature Flags is not started. + */ + @Nullable + public static Backend backend() { + return backend; + } + public static void addConfigListener(final ConfigListener listener) { CONFIG_LISTENERS.add(listener); final ServerConfiguration current = CURRENT_CONFIG.get(); @@ -128,4 +148,72 @@ public static void removeSpanEnrichmentListener(final SpanEnrichmentListener lis public static void dispatch(final SpanEnrichmentEvent event) { SPAN_ENRICHMENT_LISTENERS.forEach(listener -> listener.accept(event)); } + + /** The agent services exposed to the Feature Flags SDK. */ + public interface Backend { + /** + * Looks up a setting from the agent configuration. + * + * @param key the setting key, using the {@code dd.} system property notation without prefix. + * @return the setting value, or {@code null} if not set. + */ + @Nullable + String setting(String key); + + /** + * @return whether Remote Configuration is available. + */ + boolean isRemoteConfigAvailable(); + + /** + * Subscribes to the Feature Flags Remote Configuration product. + * + * @param listener the listener receiving raw configuration documents, or {@code null} when the + * configuration is removed. + * @return the handle to close to unsubscribe. + */ + AutoCloseable subscribeRemoteConfig(Consumer listener); + + /** + * @return whether the Datadog Agent event platform proxy is available. + */ + boolean isEventProxyAvailable(); + + /** + * Posts an event payload through the Datadog Agent event platform proxy. + * + * @param route the event platform route. + * @param json the UTF-8 JSON payload. + * @return {@code true} if the payload was delivered, {@code false} if the proxy definitively + * rejected it as unavailable. + * @throws IOException if the payload could not be delivered. + */ + boolean postEvent(String route, byte[] json) throws IOException; + + /** + * Increments a health counter. + * + * @param metric the metric name. + * @param value the increment. + * @param reason the optional {@code reason} tag value. + */ + void count(String metric, long value, @Nullable String reason); + + /** + * Records an evaluation that resolved to a split with a serial id on the local root span. + * + * @param serialId the split serial id. + * @param doLog whether the allocation logs exposures. + * @param targetingKey the optional targeting key. + */ + void enrichSerialId(int serialId, boolean doLog, @Nullable String targetingKey); + + /** + * Records an evaluation that resolved to its runtime default on the local root span. + * + * @param flagKey the flag key. + * @param defaultValue the native default value. + */ + void enrichRuntimeDefault(String flagKey, @Nullable Object defaultValue); + } } diff --git a/settings.gradle.kts b/settings.gradle.kts index b58d64cc1a3..7e83730b139 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -345,6 +345,7 @@ include( ":dd-java-agent:instrumentation:cxf-2.1", ":dd-java-agent:instrumentation:datadog:asm:iast-instrumenter", ":dd-java-agent:instrumentation:datadog:dynamic-instrumentation:span-origin", + ":dd-java-agent:instrumentation:datadog:openfeature:dd-openfeature-1.69", ":dd-java-agent:instrumentation:datadog:profiling:enable-wallclock-profiling", ":dd-java-agent:instrumentation:datadog:profiling:exception-profiling", ":dd-java-agent:instrumentation:datadog:tracing:trace-annotation", From 4445d55a0c28457a450b900876d1f0012b79bcdd Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Thu, 22 Oct 2026 12:56:36 +0200 Subject: [PATCH 2/4] chore(ffe): Remove the redundant IDEA module configuration Master removed the Gradle IDEA plugin configuration: the Java toolchain and compiler settings already give IntelliJ the right JDK. Co-Authored-By: Claude Opus 5.5 --- .../datadog/openfeature/dd-openfeature-1.69/build.gradle | 7 ------- 1 file changed, 7 deletions(-) diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/build.gradle b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/build.gradle index 5a8f8b3fd41..900c517f4b8 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/build.gradle +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/build.gradle @@ -1,12 +1,5 @@ plugins { id 'dd-trace-java.module.instrumentation' - id 'idea' -} - -idea { - module { - jdkName = '11' - } } // TODO Add a muzzle pass directive on com.datadoghq:dd-openfeature once the SDK is published. From aae96201ea2967ef2741f9c1a4596fbc73b9e6c3 Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Thu, 22 Oct 2026 13:07:40 +0200 Subject: [PATCH 3/4] style(ffe): Follow the instrumentation conventions Mark the instrumentation module and advice classes as unused, as they are only referenced through AutoService and advice class names, and import the Advice annotations statically. Co-Authored-By: Claude Opus 5.5 --- .../instrumentation/openfeature/DetectBridgeAdvice.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java index d4fba3958ad..4a462be86d0 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java @@ -1,11 +1,14 @@ package datadog.trace.instrumentation.openfeature; +import static net.bytebuddy.asm.Advice.OnMethodExit; +import static net.bytebuddy.asm.Advice.Return; + import com.datadog.openfeature.internal.bridge.AgentBridge; -import net.bytebuddy.asm.Advice; +@SuppressWarnings("unused") public class DetectBridgeAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) - public static void detect(@Advice.Return(readOnly = false) AgentBridge bridge) { + @OnMethodExit(suppress = Throwable.class) + public static void detect(@Return(readOnly = false) AgentBridge bridge) { bridge = JavaAgentBridge.connect(bridge); } } From c138f0881ec90e0b223b7120b66df31a32ba4a23 Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Fri, 23 Oct 2026 11:08:44 +0200 Subject: [PATCH 4/4] refactor(ffe): Version the agent bridge SPI Move the agent bridge SPI to a versioned package, bridge.v1: once released, a version is frozen and only gets default methods, and a breaking change goes to a new package. Check each released SPI version against the first SDK release that shipped it with japicmp, failing on any change breaking the agent implementation. The v1 baseline is set once the first SDK release with the agent bridge is published. Co-Authored-By: Claude Opus 5.5 --- .../DDOpenFeatureInstrumentation.java | 2 +- .../openfeature/AgentConfigurationSource.java | 2 +- .../openfeature/AgentEventProxy.java | 4 +-- .../openfeature/AgentHealthMetrics.java | 2 +- .../openfeature/AgentSpanEnricher.java | 2 +- .../openfeature/DetectBridgeAdvice.java | 2 +- .../openfeature/JavaAgentBridge.java | 12 ++++---- ...tureInstrumentationDisabledForkedTest.java | 4 +-- .../DDOpenFeatureInstrumentationTest.java | 10 +++---- dd-openfeature/build.gradle.kts | 28 +++++++++++++++++++ ...gEvaluationEnqueueContentionBenchmark.java | 2 +- .../FlagEvaluationHotPathBenchmark.java | 4 +-- .../com/datadog/openfeature/DDEvaluator.java | 2 +- .../com/datadog/openfeature/Provider.java | 4 +-- .../openfeature/SpanEnrichmentHook.java | 2 +- .../internal/FeatureFlagsRuntime.java | 8 +++--- .../openfeature/internal/RuntimeServices.java | 2 +- .../internal/bridge/package-info.java | 8 ------ .../internal/bridge/{ => v1}/AgentBridge.java | 2 +- .../bridge/{ => v1}/AgentBridges.java | 2 +- .../bridge/{ => v1}/ConfigurationSource.java | 2 +- .../EventProxyUnavailableException.java | 2 +- .../bridge/{ => v1}/EventTransport.java | 2 +- .../bridge/{ => v1}/HealthMetrics.java | 2 +- .../bridge/{ => v1}/NoopAgentBridge.java | 2 +- .../bridge/{ => v1}/ShutdownSource.java | 2 +- .../bridge/{ => v1}/SpanEnricher.java | 2 +- .../internal/bridge/v1/package-info.java | 9 ++++++ .../openfeature/internal/config/Settings.java | 2 +- .../delivery/DirectIntakeTransport.java | 2 +- .../internal/delivery/FallbackTransport.java | 4 +-- .../delivery/RemoteConfigurationService.java | 2 +- .../internal/exposure/ExposurePipeline.java | 2 +- .../FlagEvaluationPipeline.java | 2 +- .../openfeature/CanonicalFixtureTest.java | 2 +- .../DDEvaluatorSpanEnrichmentTest.java | 2 +- .../datadog/openfeature/DDEvaluatorTest.java | 2 +- .../DatadogExposureLoggingTest.java | 12 ++++---- .../EvaluationTelemetryOptOutTest.java | 8 +++--- .../openfeature/ExposureLoggingHookTest.java | 2 +- .../openfeature/ExposureTestEvaluator.java | 2 +- .../com/datadog/openfeature/ProviderTest.java | 12 ++++---- .../openfeature/SpanEnrichmentHookTest.java | 2 +- .../internal/FeatureFlagsRuntimeTest.java | 12 ++++---- .../internal/config/SettingsTest.java | 12 ++++---- .../internal/config/TestSettings.java | 2 +- .../delivery/CdnConfigurationSourceTest.java | 2 +- .../delivery/FallbackTransportTest.java | 4 +-- .../exposure/ExposurePipelineTest.java | 4 +-- .../FlagEvaluationTestSupport.java | 4 +-- 50 files changed, 127 insertions(+), 98 deletions(-) delete mode 100644 dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/package-info.java rename dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/{ => v1}/AgentBridge.java (96%) rename dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/{ => v1}/AgentBridges.java (91%) rename dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/{ => v1}/ConfigurationSource.java (89%) rename dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/{ => v1}/EventProxyUnavailableException.java (87%) rename dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/{ => v1}/EventTransport.java (89%) rename dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/{ => v1}/HealthMetrics.java (89%) rename dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/{ => v1}/NoopAgentBridge.java (92%) rename dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/{ => v1}/ShutdownSource.java (86%) rename dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/{ => v1}/SpanEnricher.java (95%) create mode 100644 dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/package-info.java diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentation.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentation.java index 5b47eaeb6c4..8fa3abcb5e7 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentation.java +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentation.java @@ -31,7 +31,7 @@ public boolean isApplicable(final Set enabledSystems) { @Override public String instrumentedType() { - return "com.datadog.openfeature.internal.bridge.AgentBridges"; + return "com.datadog.openfeature.internal.bridge.v1.AgentBridges"; } @Override diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentConfigurationSource.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentConfigurationSource.java index 40ec60469e8..4ae21393a20 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentConfigurationSource.java +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentConfigurationSource.java @@ -1,6 +1,6 @@ package datadog.trace.instrumentation.openfeature; -import com.datadog.openfeature.internal.bridge.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.v1.ConfigurationSource; import datadog.trace.api.featureflag.FeatureFlaggingGateway; import java.util.function.Consumer; diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentEventProxy.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentEventProxy.java index cd1e4c049de..9a3164adfcc 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentEventProxy.java +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentEventProxy.java @@ -1,7 +1,7 @@ package datadog.trace.instrumentation.openfeature; -import com.datadog.openfeature.internal.bridge.EventProxyUnavailableException; -import com.datadog.openfeature.internal.bridge.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.EventProxyUnavailableException; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; import datadog.trace.api.featureflag.FeatureFlaggingGateway; import java.io.IOException; diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentHealthMetrics.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentHealthMetrics.java index 69615c45a65..b809995f8a5 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentHealthMetrics.java +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentHealthMetrics.java @@ -1,6 +1,6 @@ package datadog.trace.instrumentation.openfeature; -import com.datadog.openfeature.internal.bridge.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; import datadog.trace.api.featureflag.FeatureFlaggingGateway; import javax.annotation.Nullable; diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentSpanEnricher.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentSpanEnricher.java index 8c947158161..f7a3cb2ccca 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentSpanEnricher.java +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/AgentSpanEnricher.java @@ -1,6 +1,6 @@ package datadog.trace.instrumentation.openfeature; -import com.datadog.openfeature.internal.bridge.SpanEnricher; +import com.datadog.openfeature.internal.bridge.v1.SpanEnricher; import datadog.trace.api.featureflag.FeatureFlaggingGateway; import javax.annotation.Nullable; diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java index 4a462be86d0..3be76c444b6 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/DetectBridgeAdvice.java @@ -3,7 +3,7 @@ import static net.bytebuddy.asm.Advice.OnMethodExit; import static net.bytebuddy.asm.Advice.Return; -import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; @SuppressWarnings("unused") public class DetectBridgeAdvice { diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/JavaAgentBridge.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/JavaAgentBridge.java index 4398c1d3caf..a0122636ff5 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/JavaAgentBridge.java +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/main/java11/datadog/trace/instrumentation/openfeature/JavaAgentBridge.java @@ -1,11 +1,11 @@ package datadog.trace.instrumentation.openfeature; -import com.datadog.openfeature.internal.bridge.AgentBridge; -import com.datadog.openfeature.internal.bridge.ConfigurationSource; -import com.datadog.openfeature.internal.bridge.EventTransport; -import com.datadog.openfeature.internal.bridge.HealthMetrics; -import com.datadog.openfeature.internal.bridge.ShutdownSource; -import com.datadog.openfeature.internal.bridge.SpanEnricher; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.ShutdownSource; +import com.datadog.openfeature.internal.bridge.v1.SpanEnricher; import datadog.trace.api.featureflag.FeatureFlaggingGateway; import javax.annotation.Nullable; diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationDisabledForkedTest.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationDisabledForkedTest.java index 1dcca26aa0c..4a825dfd686 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationDisabledForkedTest.java +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationDisabledForkedTest.java @@ -3,8 +3,8 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.mockito.Mockito.mock; -import com.datadog.openfeature.internal.bridge.AgentBridge; -import com.datadog.openfeature.internal.bridge.AgentBridges; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridges; import datadog.trace.agent.test.AbstractInstrumentationTest; import datadog.trace.api.featureflag.FeatureFlaggingGateway; import datadog.trace.test.junit.utils.config.WithConfig; diff --git a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationTest.java b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationTest.java index 492fce5e34d..61470453cd9 100644 --- a/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationTest.java +++ b/dd-java-agent/instrumentation/datadog/openfeature/dd-openfeature-1.69/src/test/java/datadog/trace/instrumentation/openfeature/DDOpenFeatureInstrumentationTest.java @@ -11,11 +11,11 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.datadog.openfeature.internal.bridge.AgentBridge; -import com.datadog.openfeature.internal.bridge.AgentBridges; -import com.datadog.openfeature.internal.bridge.ConfigurationSource; -import com.datadog.openfeature.internal.bridge.EventProxyUnavailableException; -import com.datadog.openfeature.internal.bridge.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridges; +import com.datadog.openfeature.internal.bridge.v1.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.v1.EventProxyUnavailableException; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; import datadog.trace.agent.test.AbstractInstrumentationTest; import datadog.trace.api.featureflag.FeatureFlaggingGateway; import java.util.function.Consumer; diff --git a/dd-openfeature/build.gradle.kts b/dd-openfeature/build.gradle.kts index 3aedba8be93..2401aa4491f 100644 --- a/dd-openfeature/build.gradle.kts +++ b/dd-openfeature/build.gradle.kts @@ -1,5 +1,6 @@ import datadog.gradle.configureCompiler import datadog.gradle.plugin.testJvmConstraints.TestJvmConstraintsExtension +import me.champeau.gradle.japicmp.JapicmpTask plugins { `java-library` @@ -43,3 +44,30 @@ jmh { tasks.withType().configureEach { configureCompiler(JavaVersion.VERSION_11) } + +// The agent bridge SPI versions, with the first SDK release shipping each of them. A released +// version is frozen (only default methods can be added): check it against that release. +// TODO Set the v1 baseline once the first SDK release with the agent bridge is published. +val bridgeSpiBaselines = mapOf( + "v1" to null, +) +bridgeSpiBaselines.forEach { (spi, baseline) -> + if (baseline != null) { + val baselineSdk = "com.datadoghq:dd-openfeature:$baseline" + val check = tasks.register("japicmpBridge${spi.uppercase()}") { + description = "Checks the agent bridge SPI $spi stays compatible with dd-openfeature $baseline." + oldArchives.from(configurations.detachedConfiguration(dependencies.create("$baselineSdk@jar"))) + oldClasspath.from(configurations.detachedConfiguration(dependencies.create(baselineSdk))) + newArchives.from(tasks.named("jar")) + newClasspath.from(configurations.named("runtimeClasspath")) + packageIncludes.add("com.datadog.openfeature.internal.bridge.$spi") + // The agent implements the SPI: an abstract method added to an interface breaks it. + failOnModification.set(true) + failOnSourceIncompatibility.set(true) + txtOutputFile.set(layout.buildDirectory.file("reports/japicmp/bridge-$spi.txt")) + } + tasks.named("check") { + dependsOn(check) + } + } +} diff --git a/dd-openfeature/src/jmh/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationEnqueueContentionBenchmark.java b/dd-openfeature/src/jmh/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationEnqueueContentionBenchmark.java index 7ca26289a3e..55fde9906c6 100644 --- a/dd-openfeature/src/jmh/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationEnqueueContentionBenchmark.java +++ b/dd-openfeature/src/jmh/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationEnqueueContentionBenchmark.java @@ -4,7 +4,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; import com.datadog.openfeature.internal.RuntimeServices; -import com.datadog.openfeature.internal.bridge.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; import de.thetaphi.forbiddenapis.SuppressForbidden; import java.util.HashMap; import java.util.Map; diff --git a/dd-openfeature/src/jmh/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationHotPathBenchmark.java b/dd-openfeature/src/jmh/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationHotPathBenchmark.java index d5f756d6d1a..197b15c8ca4 100644 --- a/dd-openfeature/src/jmh/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationHotPathBenchmark.java +++ b/dd-openfeature/src/jmh/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationHotPathBenchmark.java @@ -4,8 +4,8 @@ import static java.util.concurrent.TimeUnit.SECONDS; import com.datadog.openfeature.internal.RuntimeServices; -import com.datadog.openfeature.internal.bridge.EventTransport; -import com.datadog.openfeature.internal.bridge.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; import java.util.HashMap; import java.util.Map; import org.openjdk.jmh.annotations.Benchmark; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/DDEvaluator.java b/dd-openfeature/src/main/java/com/datadog/openfeature/DDEvaluator.java index 384fadb9585..8c6ced76c65 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/DDEvaluator.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/DDEvaluator.java @@ -1,7 +1,7 @@ package com.datadog.openfeature; import com.datadog.openfeature.internal.FeatureFlagsRuntime; -import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; import com.datadog.openfeature.internal.config.Settings; import com.datadog.openfeature.internal.evaluation.ConfigurationStore; import com.datadog.openfeature.internal.evaluation.FlagEvaluator; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/Provider.java b/dd-openfeature/src/main/java/com/datadog/openfeature/Provider.java index b8b72493c9d..e3ac093b7ad 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/Provider.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/Provider.java @@ -4,8 +4,8 @@ import com.datadog.openfeature.internal.FeatureFlagsRuntime; import com.datadog.openfeature.internal.FeatureFlagsRuntime.RemoteConfigurationUnavailableException; -import com.datadog.openfeature.internal.bridge.AgentBridge; -import com.datadog.openfeature.internal.bridge.AgentBridges; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridges; import com.datadog.openfeature.internal.config.Settings; import com.datadog.openfeature.internal.flagevaluation.FlagEvaluationWriter; import dev.openfeature.sdk.ErrorCode; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/SpanEnrichmentHook.java b/dd-openfeature/src/main/java/com/datadog/openfeature/SpanEnrichmentHook.java index c02f3705c8c..13dc63ac9fd 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/SpanEnrichmentHook.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/SpanEnrichmentHook.java @@ -1,6 +1,6 @@ package com.datadog.openfeature; -import com.datadog.openfeature.internal.bridge.SpanEnricher; +import com.datadog.openfeature.internal.bridge.v1.SpanEnricher; import com.datadog.openfeature.internal.evaluation.MetadataKeys; import dev.openfeature.sdk.EvaluationContext; import dev.openfeature.sdk.FlagEvaluationDetails; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/FeatureFlagsRuntime.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/FeatureFlagsRuntime.java index 4ff8fecadac..393b0ef300d 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/FeatureFlagsRuntime.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/FeatureFlagsRuntime.java @@ -2,10 +2,10 @@ import static com.datadog.openfeature.internal.config.Settings.CONFIGURATION_SOURCE_REMOTE_CONFIG; -import com.datadog.openfeature.internal.bridge.AgentBridge; -import com.datadog.openfeature.internal.bridge.ConfigurationSource; -import com.datadog.openfeature.internal.bridge.EventTransport; -import com.datadog.openfeature.internal.bridge.ShutdownSource; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.ShutdownSource; import com.datadog.openfeature.internal.config.Settings; import com.datadog.openfeature.internal.delivery.CdnConfigurationSource; import com.datadog.openfeature.internal.delivery.DirectIntakeTransport; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/RuntimeServices.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/RuntimeServices.java index 8227e19d851..20af59e7674 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/RuntimeServices.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/RuntimeServices.java @@ -1,6 +1,6 @@ package com.datadog.openfeature.internal; -import com.datadog.openfeature.internal.bridge.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; import javax.annotation.Nullable; /** Thread creation and health metrics shared by the runtime components. */ diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/package-info.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/package-info.java deleted file mode 100644 index f4d9dead3c4..00000000000 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Extension points the Datadog Java agent fills in through instrumentation. - * - *

These types are not customer API. They form the contract between this SDK and the agent - * instrumentation, which can run a different version than the SDK, so they must evolve in a - * backward compatible way. - */ -package com.datadog.openfeature.internal.bridge; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/AgentBridge.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/AgentBridge.java similarity index 96% rename from dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/AgentBridge.java rename to dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/AgentBridge.java index 342c2c2bc8c..22531167beb 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/AgentBridge.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/AgentBridge.java @@ -1,4 +1,4 @@ -package com.datadog.openfeature.internal.bridge; +package com.datadog.openfeature.internal.bridge.v1; import javax.annotation.Nullable; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/AgentBridges.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/AgentBridges.java similarity index 91% rename from dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/AgentBridges.java rename to dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/AgentBridges.java index f11022880ae..3580094b2a2 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/AgentBridges.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/AgentBridges.java @@ -1,4 +1,4 @@ -package com.datadog.openfeature.internal.bridge; +package com.datadog.openfeature.internal.bridge.v1; /** * Resolves the {@link AgentBridge} to use. Kept apart from {@link AgentBridge}: the agent injects diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/ConfigurationSource.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/ConfigurationSource.java similarity index 89% rename from dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/ConfigurationSource.java rename to dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/ConfigurationSource.java index 263938ee973..5cda6a93009 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/ConfigurationSource.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/ConfigurationSource.java @@ -1,4 +1,4 @@ -package com.datadog.openfeature.internal.bridge; +package com.datadog.openfeature.internal.bridge.v1; import java.util.function.Consumer; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/EventProxyUnavailableException.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/EventProxyUnavailableException.java similarity index 87% rename from dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/EventProxyUnavailableException.java rename to dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/EventProxyUnavailableException.java index b141a2fce00..209ffe3142a 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/EventProxyUnavailableException.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/EventProxyUnavailableException.java @@ -1,4 +1,4 @@ -package com.datadog.openfeature.internal.bridge; +package com.datadog.openfeature.internal.bridge.v1; import java.io.IOException; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/EventTransport.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/EventTransport.java similarity index 89% rename from dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/EventTransport.java rename to dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/EventTransport.java index 6f2eb3aca6e..a429099eb77 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/EventTransport.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/EventTransport.java @@ -1,4 +1,4 @@ -package com.datadog.openfeature.internal.bridge; +package com.datadog.openfeature.internal.bridge.v1; import java.io.IOException; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/HealthMetrics.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/HealthMetrics.java similarity index 89% rename from dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/HealthMetrics.java rename to dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/HealthMetrics.java index 2b1c247cb91..55d79c760c5 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/HealthMetrics.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/HealthMetrics.java @@ -1,4 +1,4 @@ -package com.datadog.openfeature.internal.bridge; +package com.datadog.openfeature.internal.bridge.v1; import javax.annotation.Nullable; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/NoopAgentBridge.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/NoopAgentBridge.java similarity index 92% rename from dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/NoopAgentBridge.java rename to dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/NoopAgentBridge.java index 0a8ff1709ae..bd684b8ef68 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/NoopAgentBridge.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/NoopAgentBridge.java @@ -1,4 +1,4 @@ -package com.datadog.openfeature.internal.bridge; +package com.datadog.openfeature.internal.bridge.v1; import javax.annotation.Nullable; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/ShutdownSource.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/ShutdownSource.java similarity index 86% rename from dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/ShutdownSource.java rename to dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/ShutdownSource.java index 145bf413b7b..8616003b7f5 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/ShutdownSource.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/ShutdownSource.java @@ -1,4 +1,4 @@ -package com.datadog.openfeature.internal.bridge; +package com.datadog.openfeature.internal.bridge.v1; /** A source of application shutdown notifications. */ public interface ShutdownSource { diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/SpanEnricher.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/SpanEnricher.java similarity index 95% rename from dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/SpanEnricher.java rename to dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/SpanEnricher.java index 768481bb6e8..3b1b1c6cd29 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/SpanEnricher.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/SpanEnricher.java @@ -1,4 +1,4 @@ -package com.datadog.openfeature.internal.bridge; +package com.datadog.openfeature.internal.bridge.v1; import javax.annotation.Nullable; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/package-info.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/package-info.java new file mode 100644 index 00000000000..f54d91769bd --- /dev/null +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/bridge/v1/package-info.java @@ -0,0 +1,9 @@ +/** + * Extension points the Datadog Java agent fills in through instrumentation. + * + *

These types are not customer API. They form the contract between this SDK and the agent + * instrumentation, which can run a different version than the SDK. Once released, this version of + * the contract is frozen: only {@code default} methods can be added. A breaking change goes to a + * new {@code bridge.v2} package, and the {@code japicmpBridge} checks enforce it. + */ +package com.datadog.openfeature.internal.bridge.v1; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/config/Settings.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/config/Settings.java index 1213c5d2ca4..b9dc8a63c0d 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/config/Settings.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/config/Settings.java @@ -1,6 +1,6 @@ package com.datadog.openfeature.internal.config; -import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; import de.thetaphi.forbiddenapis.SuppressForbidden; import java.util.Locale; import java.util.function.UnaryOperator; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/DirectIntakeTransport.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/DirectIntakeTransport.java index bd2c0171a6b..509f24fb699 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/DirectIntakeTransport.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/DirectIntakeTransport.java @@ -3,7 +3,7 @@ import static java.net.http.HttpClient.Redirect.NEVER; import static java.net.http.HttpRequest.BodyPublishers.ofByteArray; -import com.datadog.openfeature.internal.bridge.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; import com.datadog.openfeature.internal.config.Settings; import java.io.IOException; import java.net.URI; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/FallbackTransport.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/FallbackTransport.java index 3c4ca077f0b..49ae9f3e7c6 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/FallbackTransport.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/FallbackTransport.java @@ -1,7 +1,7 @@ package com.datadog.openfeature.internal.delivery; -import com.datadog.openfeature.internal.bridge.EventProxyUnavailableException; -import com.datadog.openfeature.internal.bridge.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.EventProxyUnavailableException; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/RemoteConfigurationService.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/RemoteConfigurationService.java index 8d1a4c6434a..63cae4527cb 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/RemoteConfigurationService.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/delivery/RemoteConfigurationService.java @@ -1,7 +1,7 @@ package com.datadog.openfeature.internal.delivery; import com.datadog.openfeature.internal.ConfigurationService; -import com.datadog.openfeature.internal.bridge.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.v1.ConfigurationSource; import com.datadog.openfeature.internal.ufc.ServerConfiguration; import com.datadog.openfeature.internal.ufc.UniversalFlagConfigParser; import java.io.IOException; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/exposure/ExposurePipeline.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/exposure/ExposurePipeline.java index 9577b1df211..fb0acac0989 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/exposure/ExposurePipeline.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/exposure/ExposurePipeline.java @@ -5,7 +5,7 @@ import com.datadog.openfeature.internal.EventPipeline; import com.datadog.openfeature.internal.EventQueue; import com.datadog.openfeature.internal.RuntimeServices; -import com.datadog.openfeature.internal.bridge.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationPipeline.java b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationPipeline.java index e3daf400dae..915ce31f61b 100644 --- a/dd-openfeature/src/main/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationPipeline.java +++ b/dd-openfeature/src/main/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationPipeline.java @@ -5,7 +5,7 @@ import com.datadog.openfeature.internal.EventPipeline; import com.datadog.openfeature.internal.EventQueue; import com.datadog.openfeature.internal.RuntimeServices; -import com.datadog.openfeature.internal.bridge.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; import java.util.List; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/CanonicalFixtureTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/CanonicalFixtureTest.java index b2496d0f3dd..9dd40371799 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/CanonicalFixtureTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/CanonicalFixtureTest.java @@ -7,7 +7,7 @@ import static org.mockito.Mockito.mock; import com.datadog.openfeature.internal.JsonReading; -import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; import com.datadog.openfeature.internal.config.TestSettings; import com.datadog.openfeature.internal.ufc.UniversalFlagConfigParser; import dev.openfeature.sdk.ErrorCode; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/DDEvaluatorSpanEnrichmentTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/DDEvaluatorSpanEnrichmentTest.java index 4f8bbca6e83..cd3717de70e 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/DDEvaluatorSpanEnrichmentTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/DDEvaluatorSpanEnrichmentTest.java @@ -10,7 +10,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.Mockito.mock; -import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; import com.datadog.openfeature.internal.config.TestSettings; import com.datadog.openfeature.internal.ufc.Allocation; import com.datadog.openfeature.internal.ufc.Flag; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/DDEvaluatorTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/DDEvaluatorTest.java index 7998a071a8c..f38c0eaf570 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/DDEvaluatorTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/DDEvaluatorTest.java @@ -26,7 +26,7 @@ import static org.mockito.Mockito.when; import com.datadog.openfeature.internal.LocalHttpServer; -import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; import com.datadog.openfeature.internal.config.Settings; import com.datadog.openfeature.internal.config.TestSettings; import com.datadog.openfeature.internal.exposure.ExposureDeduplicationCache; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/DatadogExposureLoggingTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/DatadogExposureLoggingTest.java index 7f75c8ab611..ddc32258e95 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/DatadogExposureLoggingTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/DatadogExposureLoggingTest.java @@ -10,12 +10,12 @@ import com.datadog.openfeature.Provider.Options; import com.datadog.openfeature.internal.LocalHttpServer; -import com.datadog.openfeature.internal.bridge.AgentBridge; -import com.datadog.openfeature.internal.bridge.ConfigurationSource; -import com.datadog.openfeature.internal.bridge.EventTransport; -import com.datadog.openfeature.internal.bridge.HealthMetrics; -import com.datadog.openfeature.internal.bridge.ShutdownSource; -import com.datadog.openfeature.internal.bridge.SpanEnricher; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.ShutdownSource; +import com.datadog.openfeature.internal.bridge.v1.SpanEnricher; import com.datadog.openfeature.internal.config.TestSettings; import com.datadog.openfeature.internal.exposure.ExposureEvent; import com.datadog.openfeature.internal.ufc.Allocation; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/EvaluationTelemetryOptOutTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/EvaluationTelemetryOptOutTest.java index d5e3ab218c0..b85b8dff282 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/EvaluationTelemetryOptOutTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/EvaluationTelemetryOptOutTest.java @@ -20,9 +20,9 @@ import com.datadog.openfeature.internal.ConfigurationService; import com.datadog.openfeature.internal.FeatureFlagsRuntime; import com.datadog.openfeature.internal.RuntimeServices; -import com.datadog.openfeature.internal.bridge.AgentBridge; -import com.datadog.openfeature.internal.bridge.HealthMetrics; -import com.datadog.openfeature.internal.bridge.SpanEnricher; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.SpanEnricher; import com.datadog.openfeature.internal.config.TestSettings; import com.datadog.openfeature.internal.exposure.ExposureDeduplicationCache; import com.datadog.openfeature.internal.exposure.ExposureEvent; @@ -82,7 +82,7 @@ * {@link ExposureHook} evaluations. * *

The provider reads its settings from the real system properties and environment through {@link - * com.datadog.openfeature.internal.bridge.AgentBridges#detect()}, so the configuration scenarios + * com.datadog.openfeature.internal.bridge.v1.AgentBridges#detect()}, so the configuration scenarios * use the system property; the environment fallback is covered by {@code SettingsTest}. */ class EvaluationTelemetryOptOutTest { diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/ExposureLoggingHookTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/ExposureLoggingHookTest.java index 70d2c6f468a..e705bb0ffef 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/ExposureLoggingHookTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/ExposureLoggingHookTest.java @@ -14,7 +14,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.datadog.openfeature.Provider.Options; -import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; import com.datadog.openfeature.internal.config.TestSettings; import com.datadog.openfeature.internal.exposure.ExposureEvent; import com.datadog.openfeature.internal.ufc.Allocation; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/ExposureTestEvaluator.java b/dd-openfeature/src/test/java/com/datadog/openfeature/ExposureTestEvaluator.java index db8e81a2c08..9e95c00f9a5 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/ExposureTestEvaluator.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/ExposureTestEvaluator.java @@ -2,7 +2,7 @@ import static org.mockito.Mockito.mock; -import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; import com.datadog.openfeature.internal.config.TestSettings; import com.datadog.openfeature.internal.exposure.ExposureDeduplicationCache; import com.datadog.openfeature.internal.exposure.ExposureEvent; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/ProviderTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/ProviderTest.java index 97325594548..5e8b9c47ce3 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/ProviderTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/ProviderTest.java @@ -23,12 +23,12 @@ import com.datadog.openfeature.Provider.Options; import com.datadog.openfeature.internal.JsonReading; import com.datadog.openfeature.internal.LocalHttpServer; -import com.datadog.openfeature.internal.bridge.AgentBridge; -import com.datadog.openfeature.internal.bridge.ConfigurationSource; -import com.datadog.openfeature.internal.bridge.EventTransport; -import com.datadog.openfeature.internal.bridge.HealthMetrics; -import com.datadog.openfeature.internal.bridge.ShutdownSource; -import com.datadog.openfeature.internal.bridge.SpanEnricher; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.ShutdownSource; +import com.datadog.openfeature.internal.bridge.v1.SpanEnricher; import com.datadog.openfeature.internal.config.TestSettings; import com.datadog.openfeature.internal.ufc.Allocation; import com.datadog.openfeature.internal.ufc.Flag; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/SpanEnrichmentHookTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/SpanEnrichmentHookTest.java index 8267b28993c..e8efe65ef95 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/SpanEnrichmentHookTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/SpanEnrichmentHookTest.java @@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import com.datadog.openfeature.internal.bridge.SpanEnricher; +import com.datadog.openfeature.internal.bridge.v1.SpanEnricher; import dev.openfeature.sdk.FlagEvaluationDetails; import dev.openfeature.sdk.FlagValueType; import dev.openfeature.sdk.Hook; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/FeatureFlagsRuntimeTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/FeatureFlagsRuntimeTest.java index 995174b8fa4..248edec0485 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/FeatureFlagsRuntimeTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/FeatureFlagsRuntimeTest.java @@ -13,12 +13,12 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import com.datadog.openfeature.internal.bridge.AgentBridge; -import com.datadog.openfeature.internal.bridge.ConfigurationSource; -import com.datadog.openfeature.internal.bridge.EventTransport; -import com.datadog.openfeature.internal.bridge.HealthMetrics; -import com.datadog.openfeature.internal.bridge.ShutdownSource; -import com.datadog.openfeature.internal.bridge.SpanEnricher; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.ShutdownSource; +import com.datadog.openfeature.internal.bridge.v1.SpanEnricher; import com.datadog.openfeature.internal.config.TestSettings; import com.datadog.openfeature.internal.flagevaluation.FlagEvalEvent; import com.datadog.openfeature.internal.ufc.ServerConfiguration; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/config/SettingsTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/config/SettingsTest.java index 80c3a9258b3..9e6675a1edc 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/config/SettingsTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/config/SettingsTest.java @@ -5,12 +5,12 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import com.datadog.openfeature.internal.bridge.AgentBridge; -import com.datadog.openfeature.internal.bridge.ConfigurationSource; -import com.datadog.openfeature.internal.bridge.EventTransport; -import com.datadog.openfeature.internal.bridge.HealthMetrics; -import com.datadog.openfeature.internal.bridge.ShutdownSource; -import com.datadog.openfeature.internal.bridge.SpanEnricher; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.ConfigurationSource; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.ShutdownSource; +import com.datadog.openfeature.internal.bridge.v1.SpanEnricher; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/config/TestSettings.java b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/config/TestSettings.java index 6acc0792138..45f5dfb00dc 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/config/TestSettings.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/config/TestSettings.java @@ -1,6 +1,6 @@ package com.datadog.openfeature.internal.config; -import com.datadog.openfeature.internal.bridge.AgentBridge; +import com.datadog.openfeature.internal.bridge.v1.AgentBridge; import java.util.HashMap; import java.util.Map; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/delivery/CdnConfigurationSourceTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/delivery/CdnConfigurationSourceTest.java index 7ddcbaba216..9dc8168dd5c 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/delivery/CdnConfigurationSourceTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/delivery/CdnConfigurationSourceTest.java @@ -17,7 +17,7 @@ import com.datadog.openfeature.internal.LocalHttpServer; import com.datadog.openfeature.internal.RuntimeServices; -import com.datadog.openfeature.internal.bridge.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; import com.datadog.openfeature.internal.config.Settings; import com.datadog.openfeature.internal.config.TestSettings; import com.datadog.openfeature.internal.ufc.ServerConfiguration; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/delivery/FallbackTransportTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/delivery/FallbackTransportTest.java index 585236831f4..d125e60cadd 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/delivery/FallbackTransportTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/delivery/FallbackTransportTest.java @@ -8,8 +8,8 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import com.datadog.openfeature.internal.bridge.EventProxyUnavailableException; -import com.datadog.openfeature.internal.bridge.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.EventProxyUnavailableException; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; import java.io.IOException; import org.junit.jupiter.api.Test; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/exposure/ExposurePipelineTest.java b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/exposure/ExposurePipelineTest.java index 38574b51d44..1324100acdb 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/exposure/ExposurePipelineTest.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/exposure/ExposurePipelineTest.java @@ -11,8 +11,8 @@ import com.datadog.openfeature.internal.JsonReading; import com.datadog.openfeature.internal.RuntimeServices; -import com.datadog.openfeature.internal.bridge.EventTransport; -import com.datadog.openfeature.internal.bridge.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; diff --git a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationTestSupport.java b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationTestSupport.java index 1dd1e51d911..68ec703e81f 100644 --- a/dd-openfeature/src/test/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationTestSupport.java +++ b/dd-openfeature/src/test/java/com/datadog/openfeature/internal/flagevaluation/FlagEvaluationTestSupport.java @@ -7,8 +7,8 @@ import com.datadog.openfeature.internal.JsonReading; import com.datadog.openfeature.internal.RuntimeServices; -import com.datadog.openfeature.internal.bridge.EventTransport; -import com.datadog.openfeature.internal.bridge.HealthMetrics; +import com.datadog.openfeature.internal.bridge.v1.EventTransport; +import com.datadog.openfeature.internal.bridge.v1.HealthMetrics; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList;