Skip to content

Commit 191543e

Browse files
committed
fix(ffe): keep source resolution within agent budget
1 parent 88d966a commit 191543e

10 files changed

Lines changed: 107 additions & 141 deletions

File tree

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/Agent.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import datadog.trace.api.config.TracerConfig;
4545
import datadog.trace.api.config.UsmConfig;
4646
import datadog.trace.api.featureflag.config.FeatureFlaggingConfig;
47-
import datadog.trace.api.featureflag.config.FeatureFlaggingConfigurationSource;
4847
import datadog.trace.api.gateway.RequestContextSlot;
4948
import datadog.trace.api.gateway.SubscriptionService;
5049
import datadog.trace.api.git.EmbeddedGitInfoBuilder;
@@ -1657,9 +1656,9 @@ private static boolean isFeatureFlaggingEnabled() {
16571656
final Boolean legacyProviderEnabled =
16581657
featureFlaggingBooleanSetting(FeatureFlaggingConfig.EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED);
16591658

1660-
return FeatureFlaggingConfigurationSource.resolve(
1661-
providerEnabled, configurationSource, legacyProviderEnabled)
1662-
!= FeatureFlaggingConfigurationSource.OFFLINE;
1659+
return !FeatureFlaggingConfig.CONFIGURATION_SOURCE_OFFLINE.equals(
1660+
FeatureFlaggingConfig.resolveConfigurationSource(
1661+
providerEnabled, configurationSource, legacyProviderEnabled));
16631662
}
16641663

16651664
private static Boolean featureFlaggingBooleanSetting(final String configKey) {

internal-api/src/main/java/datadog/trace/api/Config.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -725,12 +725,15 @@
725725
import static datadog.trace.api.config.TracerConfig.WRITER_BAGGAGE_INJECT;
726726
import static datadog.trace.api.config.TracerConfig.WRITER_LINKS_INJECT;
727727
import static datadog.trace.api.config.TracerConfig.WRITER_TYPE;
728+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.CONFIGURATION_SOURCE_OFFLINE;
728729
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED;
729730
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.FEATURE_FLAGS_CONFIGURATION_SOURCE;
730731
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL;
731732
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_POLL_INTERVAL_SECONDS;
732733
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_REQUEST_TIMEOUT_SECONDS;
733734
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.FLAGGING_PROVIDER_ENABLED;
735+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.isSupportedConfigurationSource;
736+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.resolveConfigurationSource;
734737
import static datadog.trace.api.telemetry.LogCollector.SEND_TELEMETRY;
735738
import static datadog.trace.bootstrap.instrumentation.api.WriterConstants.OTLP_WRITER_TYPE;
736739
import static datadog.trace.util.CollectionUtils.tryMakeImmutableList;
@@ -747,7 +750,6 @@
747750
import datadog.trace.api.config.OtlpConfig;
748751
import datadog.trace.api.config.ProfilingConfig;
749752
import datadog.trace.api.config.TracerConfig;
750-
import datadog.trace.api.featureflag.config.FeatureFlaggingConfigurationSource;
751753
import datadog.trace.api.iast.IastContext;
752754
import datadog.trace.api.iast.IastDetectionMode;
753755
import datadog.trace.api.iast.telemetry.Verbosity;
@@ -2862,8 +2864,8 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment())
28622864
configProvider.isSet(FEATURE_FLAGS_CONFIGURATION_SOURCE)
28632865
? configProvider.getString(FEATURE_FLAGS_CONFIGURATION_SOURCE)
28642866
: null;
2865-
final FeatureFlaggingConfigurationSource resolvedFeatureFlaggingConfigurationSource =
2866-
FeatureFlaggingConfigurationSource.resolve(
2867+
final String resolvedFeatureFlaggingConfigurationSource =
2868+
resolveConfigurationSource(
28672869
configuredFeatureFlaggingProviderEnabled,
28682870
configuredFeatureFlaggingConfigurationSource,
28692871
legacyFeatureFlaggingProviderEnabled);
@@ -2874,15 +2876,14 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment())
28742876
FLAGGING_PROVIDER_ENABLED,
28752877
FEATURE_FLAGS_CONFIGURATION_SOURCE);
28762878
}
2877-
if (!FeatureFlaggingConfigurationSource.isSupportedExplicitSource(
2878-
configuredFeatureFlaggingConfigurationSource)) {
2879+
if (!isSupportedConfigurationSource(configuredFeatureFlaggingConfigurationSource)) {
28792880
log.warn(
28802881
"Unsupported Feature Flagging configuration source: {}. Disabling Feature Flagging",
28812882
configuredFeatureFlaggingConfigurationSource);
28822883
}
28832884
featureFlaggingProviderEnabled =
2884-
resolvedFeatureFlaggingConfigurationSource != FeatureFlaggingConfigurationSource.OFFLINE;
2885-
featureFlaggingConfigurationSource = resolvedFeatureFlaggingConfigurationSource.value();
2885+
!CONFIGURATION_SOURCE_OFFLINE.equals(resolvedFeatureFlaggingConfigurationSource);
2886+
featureFlaggingConfigurationSource = resolvedFeatureFlaggingConfigurationSource;
28862887
featureFlaggingConfigurationSourceAgentlessBaseUrl =
28872888
configProvider.getStringNotEmpty(
28882889
FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL, null);

metadata/supported-configurations.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1541,7 +1541,7 @@
15411541
{
15421542
"version": "A",
15431543
"type": "boolean",
1544-
"default": null,
1544+
"default": "false",
15451545
"aliases": []
15461546
}
15471547
],

products/feature-flagging/feature-flagging-agent/src/main/java/com/datadog/featureflag/FeatureFlaggingSystem.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package com.datadog.featureflag;
22

3+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.CONFIGURATION_SOURCE_AGENTLESS;
4+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.CONFIGURATION_SOURCE_OFFLINE;
5+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.CONFIGURATION_SOURCE_REMOTE_CONFIG;
6+
37
import datadog.communication.ddagent.SharedCommunicationObjects;
48
import datadog.trace.api.Config;
59
import datadog.trace.api.featureflag.FeatureFlaggingGateway;
6-
import datadog.trace.api.featureflag.config.FeatureFlaggingConfigurationSource;
710
import org.slf4j.Logger;
811
import org.slf4j.LoggerFactory;
912

@@ -26,16 +29,14 @@ public static synchronized void start(final SharedCommunicationObjects sco) {
2629
}
2730
LOGGER.debug("Feature Flagging system starting");
2831
final Config config = Config.get();
29-
final FeatureFlaggingConfigurationSource source =
30-
FeatureFlaggingConfigurationSource.fromResolved(
31-
config.getFeatureFlaggingConfigurationSource());
32+
final String source = config.getFeatureFlaggingConfigurationSource();
3233
STARTED = true;
3334

34-
if (source == FeatureFlaggingConfigurationSource.OFFLINE) {
35+
if (CONFIGURATION_SOURCE_OFFLINE.equals(source)) {
3536
LOGGER.debug("Feature Flagging system disabled");
3637
return;
3738
}
38-
if (source == FeatureFlaggingConfigurationSource.AGENTLESS) {
39+
if (CONFIGURATION_SOURCE_AGENTLESS.equals(source)) {
3940
final FeatureFlaggingGateway.ActivationListener activationListener =
4041
() -> activateAgentless(sco, config);
4142
ACTIVATION_LISTENER = activationListener;
@@ -107,17 +108,15 @@ static void initialize(
107108

108109
static ConfigurationSourceService createConfigurationSourceService(
109110
final SharedCommunicationObjects sco, final Config config) {
110-
final FeatureFlaggingConfigurationSource configurationSource =
111-
FeatureFlaggingConfigurationSource.fromResolved(
112-
config.getFeatureFlaggingConfigurationSource());
111+
final String configurationSource = config.getFeatureFlaggingConfigurationSource();
113112

114-
if (configurationSource == FeatureFlaggingConfigurationSource.REMOTE_CONFIG) {
113+
if (CONFIGURATION_SOURCE_REMOTE_CONFIG.equals(configurationSource)) {
115114
if (!config.isRemoteConfigEnabled()) {
116115
throw new IllegalStateException("Feature Flagging system started without RC");
117116
}
118117
return new RemoteConfigServiceImpl(sco, config);
119118
}
120-
if (configurationSource == FeatureFlaggingConfigurationSource.AGENTLESS) {
119+
if (CONFIGURATION_SOURCE_AGENTLESS.equals(configurationSource)) {
121120
return new AgentlessConfigurationSource(config);
122121
}
123122
LOGGER.debug(

products/feature-flagging/feature-flagging-agent/src/test/java/com/datadog/featureflag/FeatureFlaggingSystemTest.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,9 @@ void rejectsUnsupportedNormalizedConfigurationSource() {
124124
Config config = mock(Config.class);
125125
when(config.getFeatureFlaggingConfigurationSource()).thenReturn("invalid");
126126

127-
assertThrows(
128-
IllegalArgumentException.class,
129-
() ->
130-
FeatureFlaggingSystem.createConfigurationSourceService(
131-
sharedCommunicationObjects(), config));
127+
assertNull(
128+
FeatureFlaggingSystem.createConfigurationSourceService(
129+
sharedCommunicationObjects(), config));
132130
}
133131

134132
@Test

products/feature-flagging/feature-flagging-config/build.gradle.kts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@ plugins {
44

55
apply(from = "$rootDir/gradle/java.gradle")
66

7-
description = "Feature flagging configuration keys (compile-time constants)"
8-
9-
extra["excludedClassesCoverage"] = listOf(
10-
// Constants-only holder — no executable logic to cover.
11-
"datadog.trace.api.featureflag.config.FeatureFlaggingConfig",
12-
)
7+
description = "Feature flagging configuration keys and source resolution"
138

149
dependencies {
1510
testImplementation(libs.bundles.junit5)

products/feature-flagging/feature-flagging-config/src/main/java/datadog/trace/api/featureflag/config/FeatureFlaggingConfig.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
public class FeatureFlaggingConfig {
44

5+
public static final String CONFIGURATION_SOURCE_AGENTLESS = "agentless";
6+
public static final String CONFIGURATION_SOURCE_OFFLINE = "offline";
7+
public static final String CONFIGURATION_SOURCE_REMOTE_CONFIG = "remote_config";
8+
59
public static final String FLAGGING_PROVIDER_ENABLED = "feature.flagging.provider.enabled";
610
public static final String EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED =
711
"experimental.flagging.provider.enabled";
@@ -23,5 +27,40 @@ public class FeatureFlaggingConfig {
2327
public static final String FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_REQUEST_TIMEOUT_SECONDS =
2428
"feature.flags.configuration.source.agentless.request.timeout.seconds";
2529

30+
public static String resolveConfigurationSource(
31+
final Boolean providerEnabled,
32+
final String explicitSource,
33+
final Boolean legacyProviderEnabled) {
34+
if (Boolean.FALSE.equals(providerEnabled)) {
35+
return CONFIGURATION_SOURCE_OFFLINE;
36+
}
37+
if (explicitSource != null && !explicitSource.trim().isEmpty()) {
38+
final String source = explicitSource.trim();
39+
if (CONFIGURATION_SOURCE_AGENTLESS.equalsIgnoreCase(source)) {
40+
return CONFIGURATION_SOURCE_AGENTLESS;
41+
}
42+
if (CONFIGURATION_SOURCE_REMOTE_CONFIG.equalsIgnoreCase(source)) {
43+
return CONFIGURATION_SOURCE_REMOTE_CONFIG;
44+
}
45+
return CONFIGURATION_SOURCE_OFFLINE;
46+
}
47+
if (legacyProviderEnabled != null) {
48+
return legacyProviderEnabled
49+
? CONFIGURATION_SOURCE_REMOTE_CONFIG
50+
: CONFIGURATION_SOURCE_OFFLINE;
51+
}
52+
return CONFIGURATION_SOURCE_AGENTLESS;
53+
}
54+
55+
public static boolean isSupportedConfigurationSource(final String source) {
56+
if (source == null || source.trim().isEmpty()) {
57+
return true;
58+
}
59+
final String normalized = source.trim();
60+
return CONFIGURATION_SOURCE_AGENTLESS.equalsIgnoreCase(normalized)
61+
|| CONFIGURATION_SOURCE_REMOTE_CONFIG.equalsIgnoreCase(normalized)
62+
|| CONFIGURATION_SOURCE_OFFLINE.equalsIgnoreCase(normalized);
63+
}
64+
2665
private FeatureFlaggingConfig() {}
2766
}

products/feature-flagging/feature-flagging-config/src/main/java/datadog/trace/api/featureflag/config/FeatureFlaggingConfigurationSource.java

Lines changed: 0 additions & 83 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package datadog.trace.api.featureflag.config;
2+
3+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.CONFIGURATION_SOURCE_AGENTLESS;
4+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.CONFIGURATION_SOURCE_OFFLINE;
5+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.CONFIGURATION_SOURCE_REMOTE_CONFIG;
6+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.isSupportedConfigurationSource;
7+
import static datadog.trace.api.featureflag.config.FeatureFlaggingConfig.resolveConfigurationSource;
8+
import static org.junit.jupiter.api.Assertions.assertEquals;
9+
import static org.junit.jupiter.api.Assertions.assertFalse;
10+
import static org.junit.jupiter.api.Assertions.assertTrue;
11+
12+
import org.junit.jupiter.api.Test;
13+
14+
class FeatureFlaggingConfigTest {
15+
16+
@Test
17+
void appliesConfigurationPrecedence() {
18+
assertEquals(CONFIGURATION_SOURCE_AGENTLESS, resolveConfigurationSource(null, null, null));
19+
assertEquals(CONFIGURATION_SOURCE_AGENTLESS, resolveConfigurationSource(null, " ", null));
20+
assertEquals(CONFIGURATION_SOURCE_REMOTE_CONFIG, resolveConfigurationSource(null, null, true));
21+
assertEquals(CONFIGURATION_SOURCE_OFFLINE, resolveConfigurationSource(null, null, false));
22+
assertEquals(
23+
CONFIGURATION_SOURCE_AGENTLESS, resolveConfigurationSource(null, "agentless", true));
24+
assertEquals(
25+
CONFIGURATION_SOURCE_REMOTE_CONFIG,
26+
resolveConfigurationSource(null, " remote_CONFIG ", false));
27+
assertEquals(
28+
CONFIGURATION_SOURCE_OFFLINE, resolveConfigurationSource(false, "agentless", true));
29+
assertEquals(CONFIGURATION_SOURCE_OFFLINE, resolveConfigurationSource(null, "invalid", null));
30+
assertEquals(CONFIGURATION_SOURCE_OFFLINE, resolveConfigurationSource(null, "offline", null));
31+
}
32+
33+
@Test
34+
void recognizesSupportedExplicitSources() {
35+
assertTrue(isSupportedConfigurationSource(null));
36+
assertTrue(isSupportedConfigurationSource(" "));
37+
assertTrue(isSupportedConfigurationSource("agentless"));
38+
assertTrue(isSupportedConfigurationSource(" REMOTE_CONFIG "));
39+
assertTrue(isSupportedConfigurationSource("OFFLINE"));
40+
assertFalse(isSupportedConfigurationSource("invalid"));
41+
}
42+
}

products/feature-flagging/feature-flagging-config/src/test/java/datadog/trace/api/featureflag/config/FeatureFlaggingConfigurationSourceTest.java

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)