Skip to content

Commit a3cc4e6

Browse files
committed
parsing JSON at buildtime
1 parent 2828339 commit a3cc4e6

File tree

26 files changed

+260
-141
lines changed

26 files changed

+260
-141
lines changed

components/environment/build.gradle.kts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,45 @@ plugins {
33
id("com.gradleup.shadow")
44
}
55

6+
sourceSets {
7+
create("generator") {
8+
java.srcDir("src/generator/java")
9+
}
10+
val main by getting {
11+
java {
12+
srcDir("build/generated/sources/supported")
13+
}
14+
}
15+
}
16+
617
dependencies {
7-
implementation(project(":components:json"))
8-
implementation("org.slf4j:slf4j-api:1.7.36")
18+
"generatorImplementation"("com.fasterxml.jackson.core:jackson-databind:2.15.2")
19+
"generatorImplementation"("org.slf4j:slf4j-api:1.7.36")
920
}
1021

1122
apply(from = "$rootDir/gradle/java.gradle")
1223

24+
val compileGeneratorJava = tasks.named("compileGeneratorJava")
25+
26+
val generateSupportedConfigurations by tasks.registering(JavaExec::class) {
27+
// We can run the generator with the main sourceSet runtimeClasspath
28+
dependsOn(compileGeneratorJava)
29+
mainClass.set("datadog.environment.ParseSupportedConfigurations")
30+
classpath = sourceSets["generator"].runtimeClasspath
31+
32+
val outputFile = layout.buildDirectory.file("generated/sources/supported/GeneratedSupportedConfigurations.java")
33+
args("supported-configurations.json", outputFile.get().asFile.absolutePath)
34+
35+
doFirst {
36+
outputFile.get().asFile.parentFile.mkdirs()
37+
}
38+
}
39+
// Ensure Java compilation depends on the generated sources
40+
sourceSets["main"].java.srcDir(layout.buildDirectory.dir("generated/sources/supported"))
41+
42+
tasks.named("compileJava") {
43+
dependsOn(generateSupportedConfigurations)
44+
}
1345
/*
1446
* Add an addition gradle configuration to be consumed by bootstrap only.
1547
* "datadog.trace." prefix is required to be excluded from Jacoco instrumentation.
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package datadog.environment;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.io.PrintWriter;
7+
import java.nio.file.Files;
8+
import java.nio.file.Paths;
9+
import java.util.HashMap;
10+
import java.util.Iterator;
11+
import java.util.List;
12+
import java.util.Map;
13+
import java.util.Set;
14+
15+
public class ParseSupportedConfigurations {
16+
17+
public static void main(String[] args) {
18+
String supportedConfigurationsFilename =
19+
args[0]; // e.g., "resources/supported-configurations.json"
20+
String generatedMappingPath = args[1]; // e.g.,
21+
// "build/generated-sources/datadog/environment/GeneratedSupportedConfigurations.java"
22+
23+
String jsonString;
24+
try {
25+
26+
InputStream in =
27+
ParseSupportedConfigurations.class
28+
.getClassLoader()
29+
.getResourceAsStream(supportedConfigurationsFilename);
30+
if (in == null) {
31+
throw new IllegalArgumentException(
32+
"Resource not found: " + supportedConfigurationsFilename);
33+
}
34+
35+
ObjectMapper mapper = new ObjectMapper();
36+
Map<String, Object> fileData = mapper.readValue(in, Map.class);
37+
38+
Map<String, List<String>> supported =
39+
(Map<String, List<String>>) fileData.get("supportedConfigurations");
40+
Map<String, List<String>> aliases = (Map<String, List<String>>) fileData.get("aliases");
41+
Map<String, String> deprecated = (Map<String, String>) fileData.get("deprecations");
42+
43+
Map<String, String> aliasMapping = new HashMap<>();
44+
for (Map.Entry<String, List<String>> entry : aliases.entrySet()) {
45+
for (String alias : entry.getValue()) {
46+
aliasMapping.put(alias, entry.getKey());
47+
}
48+
}
49+
generateJavaFile(generatedMappingPath, supported.keySet(), aliases, aliasMapping, deprecated);
50+
} catch (IOException e) {
51+
throw new RuntimeException("Failed to read " + supportedConfigurationsFilename, e);
52+
}
53+
}
54+
55+
private static void generateJavaFile(
56+
String outputPath,
57+
Set<String> supported,
58+
Map<String, List<String>> aliases,
59+
Map<String, String> aliasMapping,
60+
Map<String, String> deprecated)
61+
throws IOException {
62+
try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(Paths.get(outputPath)))) {
63+
out.println("package datadog.environment;");
64+
out.println();
65+
out.println("import java.util.*;");
66+
out.println();
67+
out.println("public final class GeneratedSupportedConfigurations {");
68+
69+
// Supported set using Arrays.asList and HashSet
70+
out.println(" public static final Set<String> SUPPORTED;");
71+
out.println();
72+
73+
// ALIASES map
74+
out.println(" public static final Map<String, List<String>> ALIASES;");
75+
out.println();
76+
77+
// ALIAS_MAPPING map
78+
out.println(" public static final Map<String, String> ALIAS_MAPPING;");
79+
out.println();
80+
81+
// DEPRECATED map
82+
out.println(" public static final Map<String, String> DEPRECATED;");
83+
out.println();
84+
85+
// Static initializer block
86+
out.println(" static {");
87+
88+
// Initialize SUPPORTED
89+
out.print(" Set<String> supportedSet = new HashSet<>(Arrays.asList(");
90+
Iterator<String> supportedIter = supported.iterator();
91+
while (supportedIter.hasNext()) {
92+
String key = supportedIter.next();
93+
out.print("\"" + key + "\"");
94+
if (supportedIter.hasNext()) {
95+
out.print(", ");
96+
}
97+
}
98+
out.println("));");
99+
out.println(" SUPPORTED = Collections.unmodifiableSet(supportedSet);");
100+
out.println();
101+
102+
// Initialize ALIASES
103+
out.println(" Map<String, List<String>> aliasesMap = new HashMap<>();");
104+
for (Map.Entry<String, List<String>> entry : aliases.entrySet()) {
105+
out.printf(
106+
" aliasesMap.put(\"%s\", Collections.unmodifiableList(Arrays.asList(%s)));\n",
107+
entry.getKey(), quoteList(entry.getValue()));
108+
}
109+
out.println(" ALIASES = Collections.unmodifiableMap(aliasesMap);");
110+
out.println();
111+
112+
// Initialize ALIAS_MAPPING
113+
out.println(" Map<String, String> aliasMappingMap = new HashMap<>();");
114+
for (Map.Entry<String, String> entry : aliasMapping.entrySet()) {
115+
out.printf(" aliasMappingMap.put(\"%s\", \"%s\");\n", entry.getKey(), entry.getValue());
116+
}
117+
out.println(" ALIAS_MAPPING = Collections.unmodifiableMap(aliasMappingMap);");
118+
out.println();
119+
120+
// Initialize DEPRECATED
121+
out.println(" Map<String, String> deprecatedMap = new HashMap<>();");
122+
for (Map.Entry<String, String> entry : deprecated.entrySet()) {
123+
out.printf(" deprecatedMap.put(\"%s\", \"%s\");\n", entry.getKey(), entry.getValue());
124+
}
125+
out.println(" DEPRECATED = Collections.unmodifiableMap(deprecatedMap);");
126+
127+
out.println(" }"); // end static block
128+
out.println("}"); // end class
129+
}
130+
}
131+
132+
private static String quoteList(List<String> list) {
133+
StringBuilder sb = new StringBuilder();
134+
for (int i = 0; i < list.size(); i++) {
135+
sb.append("\"").append(list.get(i)).append("\"");
136+
if (i < list.size() - 1) {
137+
sb.append(", ");
138+
}
139+
}
140+
return sb.toString();
141+
}
142+
}

components/environment/src/main/java/datadog/environment/ConfigHelper.java

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,26 @@ public class ConfigHelper {
1010
// Parse the supported-configurations JSON once using ParseSupportedConfigurations.
1111

1212
public static Map<String, String> getEnvironmentVariables() {
13-
// TODO: Remove once JSON parsing is separate from data access
14-
ParseSupportedConfigurations.loadSupportedConfigurations("supported-configurations.json");
15-
1613
Map<String, String> env = System.getenv();
1714
Map<String, String> configs = new LinkedHashMap<>();
1815
for (Map.Entry<String, String> entry : env.entrySet()) {
1916
String key = entry.getKey();
2017
String value = entry.getValue();
2118
if (key.startsWith("DD_")
2219
|| key.startsWith("OTEL_")
23-
|| ParseSupportedConfigurations.aliasMapping.containsKey(key)) {
24-
if (ParseSupportedConfigurations.supportedConfigurations.contains(key)) {
20+
|| GeneratedSupportedConfigurations.ALIAS_MAPPING.containsKey(key)) {
21+
if (GeneratedSupportedConfigurations.SUPPORTED.contains(key)) {
2522
configs.put(key, value);
2623
// If this environment variable is the alias of another, and we haven't processed the
2724
// original environment variable yet, handle it here.
28-
} else if (ParseSupportedConfigurations.aliasMapping.containsKey(key)
29-
&& !configs.containsKey(ParseSupportedConfigurations.aliasMapping.get(key))) {
25+
} else if (GeneratedSupportedConfigurations.ALIAS_MAPPING.containsKey(key)
26+
&& !configs.containsKey(GeneratedSupportedConfigurations.ALIAS_MAPPING.get(key))) {
3027
List<String> aliasList =
31-
ParseSupportedConfigurations.aliases.get(
32-
ParseSupportedConfigurations.aliasMapping.get(key));
28+
GeneratedSupportedConfigurations.ALIASES.get(
29+
GeneratedSupportedConfigurations.ALIAS_MAPPING.get(key));
3330
for (String alias : aliasList) {
3431
if (env.containsKey(alias)) {
35-
configs.put(ParseSupportedConfigurations.aliasMapping.get(key), env.get(alias));
32+
configs.put(GeneratedSupportedConfigurations.ALIAS_MAPPING.get(key), env.get(alias));
3633
break;
3734
}
3835
}
@@ -52,20 +49,18 @@ public static Map<String, String> getEnvironmentVariables() {
5249
}
5350

5451
public static String getEnvironmentVariable(String name) {
55-
// TODO: Remove once JSON parsing is separate from data access
56-
ParseSupportedConfigurations.loadSupportedConfigurations("supported-configurations.json");
57-
5852
if ((name.startsWith("DD_")
5953
|| name.startsWith("OTEL_")
60-
|| ParseSupportedConfigurations.aliasMapping.containsKey(name))
61-
&& !ParseSupportedConfigurations.supportedConfigurations.contains(name)) {
54+
|| GeneratedSupportedConfigurations.ALIAS_MAPPING.containsKey(name))
55+
&& !GeneratedSupportedConfigurations.SUPPORTED.contains(name)) {
6256
throw new IllegalArgumentException(
6357
"Missing " + name + " env/configuration in supported-configurations.json file.");
6458
}
65-
String config = System.getenv(name);
66-
if (config == null && ParseSupportedConfigurations.aliases.containsKey(name)) {
67-
for (String alias : ParseSupportedConfigurations.aliases.get(name)) {
68-
String aliasValue = System.getenv(alias);
59+
60+
String config = EnvironmentVariables.get(name);
61+
if (config == null && GeneratedSupportedConfigurations.ALIASES.containsKey(name)) {
62+
for (String alias : GeneratedSupportedConfigurations.ALIASES.get(name)) {
63+
String aliasValue = EnvironmentVariables.get(alias);
6964
if (aliasValue != null) {
7065
return aliasValue;
7166
}

components/environment/src/main/java/datadog/environment/EnvironmentVariables.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ private EnvironmentVariables() {}
3232
*/
3333
public static String getOrDefault(@Nonnull String name, String defaultValue) {
3434
try {
35-
String value = ConfigHelper.getEnvironmentVariable(name);
35+
// String value = ConfigHelper.getEnvironmentVariable(name);
36+
String value = System.getenv(name);
3637
return value == null ? defaultValue : value;
3738
} catch (SecurityException e) {
3839
return defaultValue;

components/environment/src/main/java/datadog/environment/ParseSupportedConfigurations.java

Lines changed: 0 additions & 59 deletions
This file was deleted.
Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
package datadog.environment;
2-
3-
import static org.junit.jupiter.api.Assertions.assertEquals;
4-
import static org.junit.jupiter.api.Assertions.assertTrue;
5-
6-
import org.junit.jupiter.api.Test;
7-
8-
class ParseSupportedConfigurationsTest {
9-
@Test
10-
void testParsingRealJsonFile() {
11-
ParseSupportedConfigurations.loadSupportedConfigurations("test-supported-configurations.json");
12-
13-
assertTrue(ParseSupportedConfigurations.supportedConfigurations.contains("DD_AGENT_HOST"));
14-
assertEquals(
15-
"DD_AGENT_HOST", ParseSupportedConfigurations.aliasMapping.get("DD_TRACE_AGENT_HOSTNAME"));
16-
assertEquals("NEW_KEY", ParseSupportedConfigurations.deprecatedConfigurations.get("OLD_KEY"));
17-
}
18-
}
1+
// import static org.junit.jupiter.api.Assertions.assertEquals;
2+
// import static org.junit.jupiter.api.Assertions.assertTrue;
3+
//
4+
// import org.junit.jupiter.api.Test;
5+
//
6+
// class ParseSupportedConfigurationsTest {
7+
// @Test
8+
// void testParsingRealJsonFile() {
9+
//
10+
// ParseSupportedConfigurations.loadSupportedConfigurations("test-supported-configurations.json");
11+
//
12+
// assertTrue(ParseSupportedConfigurations.supportedConfigurations.contains("DD_AGENT_HOST"));
13+
// assertEquals(
14+
// "DD_AGENT_HOST",
15+
// ParseSupportedConfigurations.aliasMapping.get("DD_TRACE_AGENT_HOSTNAME"));
16+
// assertEquals("NEW_KEY", ParseSupportedConfigurations.deprecatedConfigurations.get("OLD_KEY"));
17+
// }
18+
// }

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import static datadog.trace.util.Strings.propertyNameToSystemPropertyName;
1313
import static datadog.trace.util.Strings.toEnvVar;
1414

15-
import datadog.environment.EnvironmentVariables;
15+
import datadog.environment.ConfigHelper;
1616
import datadog.environment.JavaVirtualMachine;
1717
import datadog.environment.OperatingSystem;
1818
import datadog.trace.api.Config;
@@ -1161,7 +1161,7 @@ public void withTracer(TracerAPI tracer) {
11611161
}
11621162

11631163
private static boolean isAwsLambdaRuntime() {
1164-
String val = EnvironmentVariables.get("AWS_LAMBDA_FUNCTION_NAME");
1164+
String val = ConfigHelper.getEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME");
11651165
return val != null && !val.isEmpty();
11661166
}
11671167

@@ -1248,7 +1248,7 @@ private static void configureLogger() {
12481248
} else {
12491249
logLevel = ddGetProperty("dd.log.level");
12501250
if (null == logLevel) {
1251-
logLevel = EnvironmentVariables.get("OTEL_LOG_LEVEL");
1251+
logLevel = ConfigHelper.getEnvironmentVariable("OTEL_LOG_LEVEL");
12521252
}
12531253
}
12541254

@@ -1462,7 +1462,7 @@ private static String getStableConfig(StableConfigSource source, final String sy
14621462

14631463
/** Looks for the "DD_" environment variable equivalent of the given "dd." system property. */
14641464
private static String ddGetEnv(final String sysProp) {
1465-
return EnvironmentVariables.get(toEnvVar(sysProp));
1465+
return ConfigHelper.getEnvironmentVariable(toEnvVar(sysProp));
14661466
}
14671467

14681468
private static boolean okHttpMayIndirectlyLoadJUL() {

0 commit comments

Comments
 (0)