Skip to content

Commit 20e051e

Browse files
Minor fixes
1 parent 85d9e5c commit 20e051e

File tree

6 files changed

+79
-17
lines changed

6 files changed

+79
-17
lines changed

dd-java-agent/agent-featureflag/src/main/java/com/datadog/featureflag/FeatureFlagSystem.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.datadog.featureflag;
22

3-
import datadog.communication.ddagent.DDAgentFeaturesDiscovery;
43
import datadog.communication.ddagent.SharedCommunicationObjects;
54
import datadog.remoteconfig.ConfigurationPoller;
65
import datadog.trace.api.Config;
@@ -26,13 +25,8 @@ public static void start(final SharedCommunicationObjects sco) {
2625
"Feature flags evaluation won't be started, remote config is likely disabled");
2726
}
2827

29-
final DDAgentFeaturesDiscovery features = sco.featuresDiscovery(config);
30-
if (features.supportsEvpProxy()) {
31-
EXPOSURE_WRITER = new ExposureWriterImpl(sco.agentUrl, config);
32-
EXPOSURE_WRITER.init();
33-
} else {
34-
LOGGER.debug("Feature Flag exposures won't be submitted");
35-
}
28+
EXPOSURE_WRITER = new ExposureWriterImpl(sco.agentUrl, config);
29+
EXPOSURE_WRITER.init();
3630

3731
CONFIG_SERVICE = new FeatureFlagRemoteConfigServiceImpl(poller);
3832
CONFIG_SERVICE.init();

dd-java-agent/agent-featureflag/src/test/groovy/com/datadog/featureflag/FeatureFlagSystemTest.groovy

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.datadog.featureflag
22

3-
import datadog.communication.ddagent.DDAgentFeaturesDiscovery
43
import datadog.communication.ddagent.SharedCommunicationObjects
54
import datadog.remoteconfig.Capabilities
65
import datadog.remoteconfig.ConfigurationDeserializer
@@ -16,15 +15,12 @@ class FeatureFlagSystemTest extends DDSpecification {
1615
setup:
1716
final poller = Mock(ConfigurationPoller)
1817
final sco = Mock(SharedCommunicationObjects)
19-
final featuresDiscovery = Mock(DDAgentFeaturesDiscovery)
2018
sco.agentUrl = HttpUrl.get('http://localhost')
2119

2220
when:
2321
FeatureFlagSystem.start(sco)
2422

2523
then:
26-
1 * sco.featuresDiscovery(_ as Config) >> featuresDiscovery
27-
1 * featuresDiscovery.supportsEvpProxy() >> evpProxy
2824
1 * sco.configurationPoller(_ as Config) >> { poller }
2925
1 * poller.addCapabilities(Capabilities.CAPABILITY_FFE_FLAG_CONFIGURATION_RULES)
3026
1 * poller.addListener(Product.FFE_FLAGS, _ as ConfigurationDeserializer, _)
@@ -38,9 +34,6 @@ class FeatureFlagSystemTest extends DDSpecification {
3834
1 * poller.removeCapabilities(Capabilities.CAPABILITY_FFE_FLAG_CONFIGURATION_RULES)
3935
1 * poller.stop()
4036
0 * _
41-
42-
where:
43-
evpProxy << [true, false]
4437
}
4538

4639
void 'test that a poller is required'() {

dd-smoke-tests/featureflag/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
package datadog.smoketest.springboot
22

3+
import com.squareup.moshi.Moshi
34
import datadog.remoteconfig.Capabilities
45
import datadog.remoteconfig.Product
56
import datadog.smoketest.AbstractServerSmokeTest
7+
import datadog.trace.api.featureflag.exposure.ExposuresRequest
68
import groovy.json.JsonOutput
79
import groovy.json.JsonSlurper
810
import okhttp3.MediaType
911
import okhttp3.Request
1012
import okhttp3.RequestBody
13+
import okio.Okio
1114
import spock.lang.Shared
1215

1316
class OpenFeatureProviderSmokeTest extends AbstractServerSmokeTest {
1417

1518
@Shared
1619
private final rcPayload = JsonOutput.toJson(new JsonSlurper().parse(Thread.currentThread().contextClassLoader.getResource("ffe/flags-v1.json")))
1720

21+
@Shared
22+
private final moshi = new Moshi.Builder().build().adapter(ExposuresRequest)
23+
1824
@Override
1925
ProcessBuilder createProcessBuilder() {
2026
setRemoteConfig("datadog/2/FFE_FLAGS/1/config", rcPayload)
@@ -31,6 +37,16 @@ class OpenFeatureProviderSmokeTest extends AbstractServerSmokeTest {
3137
return builder
3238
}
3339

40+
@Override
41+
Closure decodedEvpProxyMessageCallback() {
42+
return { String path, byte[] body ->
43+
if (!path.contains('api/v2/exposures')) {
44+
return null
45+
}
46+
return moshi.fromJson(Okio.buffer(Okio.source(new ByteArrayInputStream(body))))
47+
}
48+
}
49+
3450
void 'test open feature provider metadata'() {
3551
setup:
3652
final url = "http://localhost:${httpPort}/openfeature/provider-metadata"
@@ -74,6 +90,12 @@ class OpenFeatureProviderSmokeTest extends AbstractServerSmokeTest {
7490
final responseBody = new JsonSlurper().parse(response.body().byteStream())
7591
final value = responseBody.value
7692
assert value == testCase.result.value
93+
waitForEvpProxyMessage {
94+
final exposure = it.v2 as ExposuresRequest
95+
return exposure.events.first().with {
96+
it.flag.key == testCase.flag && it.subject.id == testCase.targetingKey
97+
}
98+
}
7799

78100
where:
79101
testCase << new JsonSlurper().parse(Thread.currentThread().contextClassLoader.getResource("ffe/test-cases.json"))

dd-smoke-tests/src/main/groovy/datadog/smoketest/AbstractSmokeTest.groovy

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ abstract class AbstractSmokeTest extends ProcessManager {
4747
@Shared
4848
private Throwable telemetryDecodingFailure = null
4949

50+
@Shared
51+
private Closure decodeEvpMessage = decodedEvpProxyMessageCallback()
52+
53+
@Shared
54+
protected CopyOnWriteArrayList<Tuple2<String, ?>> evpProxyMessages = new CopyOnWriteArrayList()
55+
56+
@Shared
57+
private Throwable evpProxyMessageDecodingFailure = null
58+
5059
@Shared
5160
protected TestHttpServer.Headers lastTraceRequestHeaders = null
5261

@@ -70,7 +79,8 @@ abstract class AbstractSmokeTest extends ProcessManager {
7079
"endpoints": [
7180
"/v0.4/traces",
7281
"/v0.5/traces",
73-
"/telemetry/proxy/"
82+
"/telemetry/proxy/",
83+
"/evp_proxy/v2/",
7484
],
7585
"client_drop_p0s": true,
7686
"span_meta_structs": true,
@@ -165,6 +175,22 @@ abstract class AbstractSmokeTest extends ProcessManager {
165175
}
166176
response.status(202).send()
167177
}
178+
prefix("/evp_proxy/v2/") {
179+
try {
180+
final path = request.path.toString()
181+
final body = request.getBody()
182+
final decoded = decodeEvpMessage.call(path, body)
183+
if (decoded) {
184+
evpProxyMessages.add(new Tuple2<>(path, decodeEvpMessage.call(path, body)))
185+
}
186+
response.status(200).send()
187+
} catch (Throwable t) {
188+
println("=== Failure during evp proxy message decoding ===")
189+
t.printStackTrace(System.out)
190+
evpProxyMessageDecodingFailure = t
191+
throw t
192+
}
193+
}
168194
}
169195
}
170196

@@ -252,6 +278,10 @@ abstract class AbstractSmokeTest extends ProcessManager {
252278
if (traceDecodingFailure != null) {
253279
throw traceDecodingFailure
254280
}
281+
evpProxyMessages.clear()
282+
if (evpProxyMessageDecodingFailure) {
283+
throw evpProxyMessageDecodingFailure
284+
}
255285
}
256286

257287
def setupSpec() {
@@ -275,6 +305,10 @@ abstract class AbstractSmokeTest extends ProcessManager {
275305
null
276306
}
277307

308+
Closure decodedEvpProxyMessageCallback() {
309+
null
310+
}
311+
278312
void setRemoteConfig(String path, String jsonData) {
279313
def targets = """
280314
{
@@ -378,6 +412,21 @@ abstract class AbstractSmokeTest extends ProcessManager {
378412
return message
379413
}
380414

415+
<T> Tuple2<String, T> waitForEvpProxyMessage(final Function<Tuple2<String, T>, Boolean> predicate) {
416+
waitForEvpProxyMessage(defaultPoll, predicate)
417+
}
418+
419+
<T> Tuple2<String, T> waitForEvpProxyMessage(final PollingConditions poll, final Function<Tuple2<String, T>, Boolean> predicate) {
420+
def message = null
421+
poll.eventually {
422+
if (evpProxyMessageDecodingFailure != null) {
423+
throw evpProxyMessageDecodingFailure
424+
}
425+
assert (message = evpProxyMessages.find { predicate.apply(it) }) != null
426+
}
427+
return message
428+
}
429+
381430
List<DecodedTrace> getTraces() {
382431
decodeTraces
383432
}

products/openfeature/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,7 @@ tasks.withType<Javadoc>().configureEach {
6161
tasks.named<CheckForbiddenApis>("forbiddenApisMain") {
6262
failOnMissingClasses = false
6363
}
64+
65+
tasks.named<Jar>("jar") {
66+
archiveBaseName.set("dd-openfeature")
67+
}

products/openfeature/src/main/java/datadog/trace/api/openfeature/Provider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public void initialize(final EvaluationContext context) throws Exception {
3535
emit(
3636
ProviderEvent.PROVIDER_READY,
3737
ProviderEventDetails.builder().message("Provider ready").build());
38-
} catch (final Exception e) {
38+
} catch (final Throwable e) {
3939
final String message = "Failed to initialize Datadog provider, is the tracer configured?";
4040
LOGGER.error(message, e);
4141
emit(ProviderEvent.PROVIDER_ERROR, ProviderEventDetails.builder().message(message).build());

0 commit comments

Comments
 (0)