Skip to content

Commit 43109aa

Browse files
committed
Use precedence field on ConfigOrigin to determine seq_id
1 parent 31e2345 commit 43109aa

File tree

7 files changed

+71
-73
lines changed

7 files changed

+71
-73
lines changed

dd-smoke-tests/log-injection/src/main/java/datadog/smoketest/loginjection/BaseApplication.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ public void run() throws InterruptedException {
4444
}
4545

4646
private static Object getLogInjectionEnabled() {
47-
ConfigSetting configSetting = ConfigCollector.get().collect().get(LOGS_INJECTION_ENABLED);
47+
ConfigSetting configSetting =
48+
ConfigCollector.get().getAppliedConfigSetting(LOGS_INJECTION_ENABLED);
4849
if (configSetting == null) {
4950
return null;
5051
}

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,6 @@ public void put(String key, Object value, ConfigOrigin origin) {
3434
originMap.put(origin, setting); // replaces any previous value for this origin
3535
}
3636

37-
// TODO: Replace old `put` with this `put`
38-
public void put(String key, Object value, ConfigOrigin origin, int seqId) {
39-
ConfigSetting setting = ConfigSetting.of(key, value, origin, seqId);
40-
Map<ConfigOrigin, ConfigSetting> originMap =
41-
collected.computeIfAbsent(key, k -> new ConcurrentHashMap<>());
42-
originMap.put(origin, setting); // replaces any previous value for this origin
43-
}
44-
4537
public void putAll(Map<String, Object> keysAndValues, ConfigOrigin origin) {
4638
for (Map.Entry<String, Object> entry : keysAndValues.entrySet()) {
4739
put(entry.getKey(), entry.getValue(), origin);
@@ -56,4 +48,14 @@ public Map<String, Map<ConfigOrigin, ConfigSetting>> collect() {
5648
return Collections.emptyMap();
5749
}
5850
}
51+
52+
public ConfigSetting getAppliedConfigSetting(String key) {
53+
Map<ConfigOrigin, ConfigSetting> originMap = collected.get(key);
54+
if (originMap == null || originMap.isEmpty()) {
55+
return null;
56+
}
57+
return originMap.values().stream()
58+
.max(java.util.Comparator.comparingInt(setting -> setting.origin.precedence))
59+
.orElse(null);
60+
}
5961
}

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,29 @@
44
// GeneratedDocumentation/ApiDocs/v2/SchemaDocumentation/Schemas/conf_key_value.md
55
public enum ConfigOrigin {
66
/** configurations that are set through environment variables */
7-
ENV("env_var"),
7+
ENV("env_var", 5),
88
/** values that are set using remote config */
9-
REMOTE("remote_config"),
9+
REMOTE("remote_config", 9),
1010
/** configurations that are set through JVM properties */
11-
JVM_PROP("jvm_prop"),
11+
JVM_PROP("jvm_prop", 6),
1212
/** configuration read in the stable config file, managed by users */
13-
LOCAL_STABLE_CONFIG("local_stable_config"),
13+
LOCAL_STABLE_CONFIG("local_stable_config", 4),
1414
/** configuration read in the stable config file, managed by fleet */
15-
FLEET_STABLE_CONFIG("fleet_stable_config"),
15+
FLEET_STABLE_CONFIG("fleet_stable_config", 7),
1616
/** configurations that are set through the customer application */
17-
CODE("code"),
17+
CODE("code", 8),
1818
/** set by the dd.yaml file or json */
19-
DD_CONFIG("dd_config"),
19+
DD_CONFIG("dd_config", 3),
2020
/** set for cases where it is difficult/not possible to determine the source of a config. */
21-
UNKNOWN("unknown"),
21+
UNKNOWN("unknown", 2),
2222
/** set when the user has not set any configuration for the key (defaults to a value) */
23-
DEFAULT("default");
23+
DEFAULT("default", 1);
2424

2525
public final String value;
26+
public final int precedence;
2627

27-
ConfigOrigin(String value) {
28+
ConfigOrigin(String value, int precedence) {
2829
this.value = value;
30+
this.precedence = precedence;
2931
}
3032
}

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

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,19 @@ public final class ConfigSetting {
1111
public final String key;
1212
public final Object value;
1313
public final ConfigOrigin origin;
14-
public final int seqID;
1514

1615
private static final Set<String> CONFIG_FILTER_LIST =
1716
new HashSet<>(
1817
Arrays.asList("DD_API_KEY", "dd.api-key", "dd.profiling.api-key", "dd.profiling.apikey"));
1918

2019
public static ConfigSetting of(String key, Object value, ConfigOrigin origin) {
21-
return new ConfigSetting(key, value, origin, 0);
20+
return new ConfigSetting(key, value, origin);
2221
}
2322

24-
public static ConfigSetting of(String key, Object value, ConfigOrigin origin, int seqID) {
25-
return new ConfigSetting(key, value, origin, seqID);
26-
}
27-
28-
private ConfigSetting(String key, Object value, ConfigOrigin origin, int seqID) {
23+
private ConfigSetting(String key, Object value, ConfigOrigin origin) {
2924
this.key = key;
3025
this.value = CONFIG_FILTER_LIST.contains(key) ? "<hidden>" : value;
3126
this.origin = origin;
32-
this.seqID = seqID;
3327
}
3428

3529
public String normalizedKey() {
@@ -105,10 +99,7 @@ public boolean equals(Object o) {
10599
if (this == o) return true;
106100
if (o == null || getClass() != o.getClass()) return false;
107101
ConfigSetting that = (ConfigSetting) o;
108-
return key.equals(that.key)
109-
&& Objects.equals(value, that.value)
110-
&& origin == that.origin
111-
&& seqID == that.seqID;
102+
return key.equals(that.key) && Objects.equals(value, that.value) && origin == that.origin;
112103
}
113104

114105
@Override
@@ -125,9 +116,9 @@ public String toString() {
125116
+ ", value="
126117
+ stringValue()
127118
+ ", origin="
128-
+ origin
119+
+ origin.value
129120
+ ", seq_id="
130-
+ seqID
121+
+ origin.precedence
131122
+ '}';
132123
}
133124
}

internal-api/src/main/java/datadog/trace/bootstrap/config/provider/ConfigProvider.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,13 @@ private static final class Singleton {
3232

3333
private final ConfigProvider.Source[] sources;
3434

35-
private final int numSources;
36-
3735
private ConfigProvider(ConfigProvider.Source... sources) {
3836
this(true, sources);
3937
}
4038

4139
private ConfigProvider(boolean collectConfig, ConfigProvider.Source... sources) {
4240
this.collectConfig = collectConfig;
4341
this.sources = sources;
44-
this.numSources = sources.length;
4542
}
4643

4744
public String getConfigFileStatus() {
@@ -78,27 +75,23 @@ public <T extends Enum<T>> T getEnum(String key, Class<T> enumType, T defaultVal
7875

7976
public String getString(String key, String defaultValue, String... aliases) {
8077
String foundValue = null;
81-
int ctr = numSources + 1;
78+
8279
for (ConfigProvider.Source source : sources) {
8380
String value = source.get(key, aliases);
8481
if (value != null) {
8582
if (collectConfig) {
86-
if (ctr <= 1) {
87-
// log a developer error? Report some log to telemetry for developer use?
88-
ConfigCollector.get().put(key, value, source.origin()); // report without seq_id
89-
} else {
90-
ctr--;
91-
ConfigCollector.get().put(key, value, source.origin(), ctr);
92-
}
83+
ConfigCollector.get().put(key, value, source.origin());
9384
}
9485
if (foundValue == null) {
9586
foundValue = value;
9687
}
9788
}
9889
}
90+
9991
if (collectConfig) {
10092
ConfigCollector.get().put(key, defaultValue, ConfigOrigin.DEFAULT);
10193
}
94+
10295
return foundValue != null ? foundValue : defaultValue;
10396
}
10497

internal-api/src/test/groovy/datadog/trace/api/ConfigCollectorTest.groovy

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -157,45 +157,48 @@ class ConfigCollectorTest extends DDSpecification {
157157
}
158158

159159
def "put-get configurations"() {
160-
// TODO: Migrate test to new ConfigCollector data structure
161160
setup:
162161
ConfigCollector.get().collect()
163162

164163
when:
165164
ConfigCollector.get().put('key1', 'value1', ConfigOrigin.DEFAULT)
166165
ConfigCollector.get().put('key2', 'value2', ConfigOrigin.ENV)
167-
ConfigCollector.get().put('key1', 'replaced', ConfigOrigin.REMOTE)
166+
ConfigCollector.get().put('key1', 'value11', ConfigOrigin.REMOTE)
168167
ConfigCollector.get().put('key3', 'value3', ConfigOrigin.JVM_PROP)
169168

170169
then:
171-
ConfigCollector.get().collect().values().toSet() == [
172-
ConfigSetting.of('key1', 'replaced', ConfigOrigin.REMOTE),
170+
def allSettings = ConfigCollector.get().collect().values().collectMany { it.values() }.toSet()
171+
allSettings == [
172+
ConfigSetting.of('key1', 'value1', ConfigOrigin.DEFAULT),
173+
ConfigSetting.of('key1', 'value11', ConfigOrigin.REMOTE),
173174
ConfigSetting.of('key2', 'value2', ConfigOrigin.ENV),
174175
ConfigSetting.of('key3', 'value3', ConfigOrigin.JVM_PROP)
175176
] as Set
176177
}
177178

178179

179180
def "hide pii configuration data"() {
180-
// TODO: Migrate test to new ConfigCollector data structure
181181
setup:
182182
ConfigCollector.get().collect()
183183

184184
when:
185185
ConfigCollector.get().put('DD_API_KEY', 'sensitive data', ConfigOrigin.ENV)
186186

187187
then:
188-
ConfigCollector.get().collect().get('DD_API_KEY').stringValue() == '<hidden>'
188+
def configsByOrigin = ConfigCollector.get().collect().get('DD_API_KEY')
189+
configsByOrigin != null
190+
configsByOrigin.get(ConfigOrigin.ENV).stringValue() == '<hidden>'
189191
}
190192

191193
def "collects common setting default values"() {
192-
// TODO: Migrate test to new ConfigCollector data structure
193194
when:
194195
def settings = ConfigCollector.get().collect()
195196

196197
then:
197-
def setting = settings.get(key)
198-
198+
def configsByOrigin = settings.get(key)
199+
configsByOrigin != null
200+
def setting = configsByOrigin.get(ConfigOrigin.DEFAULT)
201+
setting != null
199202
setting.key == key
200203
setting.stringValue() == value
201204
setting.origin == ConfigOrigin.DEFAULT
@@ -214,7 +217,6 @@ class ConfigCollectorTest extends DDSpecification {
214217
}
215218

216219
def "collects common setting overridden values"() {
217-
// TODO: Migrate test to new ConfigCollector data structure
218220
setup:
219221
injectEnvConfig("DD_TRACE_ENABLED", "false")
220222
injectEnvConfig("DD_PROFILING_ENABLED", "true")
@@ -229,8 +231,10 @@ class ConfigCollectorTest extends DDSpecification {
229231
def settings = ConfigCollector.get().collect()
230232

231233
then:
232-
def setting = settings.get(key)
233-
234+
def configsByOrigin = settings.get(key)
235+
configsByOrigin != null
236+
def setting = configsByOrigin.get(ConfigOrigin.ENV)
237+
setting != null
234238
setting.key == key
235239
setting.stringValue() == value
236240
setting.origin == ConfigOrigin.ENV
@@ -249,24 +253,28 @@ class ConfigCollectorTest extends DDSpecification {
249253
"trace.sample.rate" | "0.3"
250254
}
251255

252-
def "seqID increases with precedence"() {
256+
def "getAppliedConfigSetting returns the setting with the highest precedence for a key"() {
253257
setup:
254-
def configKey = IastConfig.IAST_TELEMETRY_VERBOSITY
255-
def envValue = Verbosity.DEBUG.toString()
256-
def sysValue = Verbosity.MANDATORY.toString()
257-
injectEnvConfig(Strings.toEnvVar(configKey), envValue)
258-
injectSysConfig(configKey, sysValue)
258+
def collector = ConfigCollector.get()
259+
collector.collect() // clear previous state
260+
collector.put('test.key', 'default', ConfigOrigin.DEFAULT)
261+
collector.put('test.key', 'env', ConfigOrigin.ENV)
262+
collector.put('test.key', 'remote', ConfigOrigin.REMOTE)
263+
collector.put('test.key', 'jvm', ConfigOrigin.JVM_PROP)
259264

260-
expect:
261-
def configsByOrigin = ConfigCollector.get().collect().get(configKey)
262-
configsByOrigin != null
263-
def sysSetting = configsByOrigin.get(ConfigOrigin.JVM_PROP)
264-
sysSetting != null
265-
def envSetting = configsByOrigin.get(ConfigOrigin.ENV)
266-
envSetting != null
267-
def defaultSetting = configsByOrigin.get(ConfigOrigin.DEFAULT)
268-
defaultSetting != null
269-
sysSetting.seqID > envSetting.seqID
270-
envSetting.seqID > defaultSetting.seqID
265+
when:
266+
def applied = collector.getAppliedConfigSetting('test.key')
267+
268+
then:
269+
applied != null
270+
applied.key == 'test.key'
271+
applied.value == 'remote'
272+
applied.origin == ConfigOrigin.REMOTE
273+
274+
when: "no settings for a key"
275+
def none = collector.getAppliedConfigSetting('nonexistent.key')
276+
277+
then:
278+
none == null
271279
}
272280
}

telemetry/src/main/java/datadog/telemetry/TelemetryRequestBody.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ public void writeConfiguration(ConfigSetting configSetting) throws IOException {
230230
bodyWriter.name("value").value(configSetting.stringValue());
231231
bodyWriter.setSerializeNulls(false);
232232
bodyWriter.name("origin").value(configSetting.origin.value);
233+
bodyWriter.name("seq_id").value(configSetting.origin.precedence);
233234
bodyWriter.endObject();
234235
}
235236

0 commit comments

Comments
 (0)