Skip to content

Commit 646461c

Browse files
BaptisteFoymcculls
andauthored
Fix NPE for keys with empty value in Stable Configuration (#9461)
* fix(StableConfig): Support keys with no value in YAML * Update internal-api/src/main/java/datadog/trace/bootstrap/config/provider/stableconfig/StableConfig.java Co-authored-by: Stuart McCulloch <[email protected]> * spotless --------- Co-authored-by: Stuart McCulloch <[email protected]>
1 parent 5797f3c commit 646461c

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ public final class StableConfig {
1818
public StableConfig(Object yaml) {
1919
Map<Object, Object> map = (Map<Object, Object>) yaml;
2020
this.configId = map.get("config_id") == null ? null : String.valueOf(map.get("config_id"));
21+
22+
// getOrDefault returns null if key exists with null value, so we need explicit null check
23+
Map<String, Object> apmConfigDefault =
24+
(Map<String, Object>) map.get("apm_configuration_default");
2125
this.apmConfigurationDefault =
22-
unmodifiableMap(
23-
(Map<String, Object>) map.getOrDefault("apm_configuration_default", emptyMap()));
26+
unmodifiableMap(apmConfigDefault != null ? apmConfigDefault : emptyMap());
27+
2428
this.apmConfigurationRules = parseRules(map);
2529
}
2630

internal-api/src/test/groovy/datadog/trace/bootstrap/config/provider/StableConfigParserTest.groovy

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,4 +298,46 @@ apm_configuration_rules:
298298
"{{environment_variables['']}}" | "Empty environment variable name in template"
299299
"{{environment_variables['DD_KEY']}" | "Unterminated template in config"
300300
}
301+
302+
def "test null and empty values in YAML"() {
303+
given:
304+
Path filePath = Files.createTempFile("testFile_", ".yaml")
305+
306+
when:
307+
String yaml = """
308+
config_id: "12345"
309+
apm_configuration_default:
310+
apm_configuration_rules:
311+
"""
312+
Files.write(filePath, yaml.getBytes())
313+
StableConfigSource.StableConfig cfg = StableConfigParser.parse(filePath.toString())
314+
315+
then:
316+
cfg.getConfigId() == "12345"
317+
cfg.getKeys().isEmpty()
318+
319+
cleanup:
320+
Files.delete(filePath)
321+
}
322+
323+
def "test completely empty values in YAML"() {
324+
given:
325+
Path filePath = Files.createTempFile("testFile_", ".yaml")
326+
327+
when:
328+
String yaml = """
329+
config_id: "12345"
330+
apm_configuration_default:
331+
apm_configuration_rules:
332+
"""
333+
Files.write(filePath, yaml.getBytes())
334+
StableConfigSource.StableConfig cfg = StableConfigParser.parse(filePath.toString())
335+
336+
then:
337+
cfg.getConfigId() == "12345"
338+
cfg.getKeys().isEmpty()
339+
340+
cleanup:
341+
Files.delete(filePath)
342+
}
301343
}

internal-api/src/test/groovy/datadog/trace/bootstrap/config/provider/StableConfigSourceTest.groovy

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,31 @@ class StableConfigSourceTest extends DDSpecification {
7171
"12345" | "this is not yaml format!"
7272
}
7373

74+
def "test null values in YAML"() {
75+
when:
76+
Path filePath = Files.createTempFile("testFile_", ".yaml")
77+
then:
78+
if (filePath == null) {
79+
throw new AssertionError("Failed to create: " + filePath)
80+
}
81+
82+
when:
83+
// Test the scenario where YAML contains null values for apm_configuration_default and apm_configuration_rules
84+
String yaml = """
85+
config_id: "12345"
86+
apm_configuration_default:
87+
apm_configuration_rules:
88+
"""
89+
Files.write(filePath, yaml.getBytes())
90+
StableConfigSource stableCfg = new StableConfigSource(filePath.toString(), ConfigOrigin.LOCAL_STABLE_CONFIG)
91+
92+
then:
93+
// Should not throw NullPointerException and should handle null values gracefully
94+
stableCfg.getConfigId() == "12345"
95+
stableCfg.getKeys().size() == 0
96+
Files.delete(filePath)
97+
}
98+
7499
def "test file valid format"() {
75100
given:
76101
Path filePath = Files.createTempFile("testFile_", ".yaml")

0 commit comments

Comments
 (0)