Skip to content

Mhlidd/config inversion #9181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 41 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
fd62009
saving work
mhlidd Jul 14, 2025
a756eb2
init: adding System.getenv forbiddenAPI, ConfigHelper, ParseSupported…
mhlidd Jul 15, 2025
96e2546
Fixing java6 incompatibility with EnvironmentVariables component
mhlidd Jul 15, 2025
6a87970
parsing JSON at buildtime
mhlidd Jul 17, 2025
b062c96
fixing invocationtargetexception
mhlidd Jul 17, 2025
6769bda
spotless
mhlidd Jul 17, 2025
06ed2fd
updating linter to include OTEL_
mhlidd Jul 18, 2025
8dd50e0
adding EnvironmentVariables linter
mhlidd Jul 18, 2025
9660b1a
adding flag for strictness
mhlidd Jul 23, 2025
f8d2a8c
updating supported-configurations
mhlidd Jul 24, 2025
b68f0b2
updated all discoverable configs
mhlidd Jul 29, 2025
dc5d83b
updating jmxfetch configs
mhlidd Jul 30, 2025
fe2eeb9
fixing config helper
mhlidd Jul 31, 2025
229c38d
adding unit tests for ConfigHelper
mhlidd Aug 1, 2025
77ddecd
fixing tests pt 1
mhlidd Aug 5, 2025
eb6908a
adding configs and updating specific tests to TEST strictness
mhlidd Aug 5, 2025
972eef4
cleanup and removing system.getenv call
mhlidd Aug 5, 2025
81c12f4
adding more supported-configurations
mhlidd Aug 5, 2025
98c57b5
adding more configs
mhlidd Aug 5, 2025
990c0ce
adding configs and updating tests
mhlidd Aug 6, 2025
5bdd8cf
adding branch coverage
mhlidd Aug 6, 2025
52c05b4
updating code coverage again
mhlidd Aug 6, 2025
5192a8a
test
mhlidd Aug 7, 2025
f128de8
rebasing
mhlidd Aug 7, 2025
734f9c7
adding more configs post-rebase
mhlidd Aug 7, 2025
e9ce233
initialize GeneratedSupportedConfiguratons at buildtime
mhlidd Aug 12, 2025
90f536d
fixing buildtests
mhlidd Aug 12, 2025
7a1517e
adding ConfigInversionStrictStyle
mhlidd Aug 12, 2025
5ca61c0
refactor ConfigHelper to datadog.trace.api
mhlidd Aug 13, 2025
abc0b64
adding configs and updating gradle files to reflect ConfigHelper refa…
mhlidd Aug 13, 2025
97db41f
adding telemetry
mhlidd Aug 13, 2025
04bde01
reverting agent-bootstrap to directly invoke EnvironmentVariables com…
mhlidd Aug 14, 2025
9a764c9
Merge branch 'master' into mhlidd/config_inversion
mhlidd Aug 14, 2025
e10e0a9
updating ConfigHelper to use getAll()
mhlidd Aug 14, 2025
340eeef
adding classes to native build time and adding suppressforbidden
mhlidd Aug 14, 2025
ea83e25
Adding SupportedConfigurationsSource to buildtime
mhlidd Aug 14, 2025
4b602c1
testing
mhlidd Aug 14, 2025
4bdb960
attempt to fix native image
mhlidd Aug 14, 2025
962490d
attempt to fix native build
mhlidd Aug 15, 2025
7299531
cleanup pt1
mhlidd Aug 15, 2025
385a4a4
Merge branch 'master' into mhlidd/config_inversion
mhlidd Aug 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ with(extensions["spotlessPredeclare"] as SpotlessExtension) {
}
}
apply(from = rootDir.resolve("gradle/spotless.gradle"))
apply(from = rootDir.resolve("gradle/configInversionLinter.gradle"))

val compileTask = tasks.register("compile")

Expand Down
39 changes: 39 additions & 0 deletions components/environment/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,46 @@ plugins {
id("com.gradleup.shadow")
}

sourceSets {
create("generator") {
java.srcDir("src/generator/java")
}
val main by getting {
java {
srcDir("build/generated/sources/supported")
}
}
}

dependencies {
"generatorImplementation"("com.fasterxml.jackson.core:jackson-databind:2.15.2")
"generatorImplementation"("org.slf4j:slf4j-api:1.7.36")
implementation(project(":dd-trace-api"))
}

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

val compileGeneratorJava = tasks.named("compileGeneratorJava")

val generateSupportedConfigurations by tasks.registering(JavaExec::class) {
// We can run the generator with the main sourceSet runtimeClasspath
dependsOn(compileGeneratorJava)
mainClass.set("datadog.environment.ParseSupportedConfigurations")
classpath = sourceSets["generator"].runtimeClasspath

val outputFile = layout.buildDirectory.file("generated/sources/supported/GeneratedSupportedConfigurations.java")
args("supported-configurations.json", outputFile.get().asFile.absolutePath)

doFirst {
outputFile.get().asFile.parentFile.mkdirs()
}
}
// Ensure Java compilation depends on the generated sources
sourceSets["main"].java.srcDir(layout.buildDirectory.dir("generated/sources/supported"))

tasks.named("compileJava") {
dependsOn(generateSupportedConfigurations)
}
/*
* Add an addition gradle configuration to be consumed by bootstrap only.
* "datadog.trace." prefix is required to be excluded from Jacoco instrumentation.
Expand All @@ -20,6 +58,7 @@ tasks.shadowJar {
extra.set("minimumInstructionCoverage", 0.7)
val excludedClassesCoverage by extra {
listOf(
"datadog.environment.GeneratedSupportedConfigurations", // generated static file
"datadog.environment.JavaVirtualMachine", // depends on OS and JVM vendor
"datadog.environment.JavaVirtualMachine.JvmOptionsHolder", // depends on OS and JVM vendor
"datadog.environment.JvmOptions", // depends on OS and JVM vendor
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package datadog.environment;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ParseSupportedConfigurations {

public static void main(String[] args) {
String supportedConfigurationsFilename =
args[0]; // e.g., "resources/supported-configurations.json"
String generatedMappingPath = args[1]; // e.g.,
// "build/generated-sources/datadog/environment/GeneratedSupportedConfigurations.java"

String jsonString;
try {

InputStream in =
ParseSupportedConfigurations.class
.getClassLoader()
.getResourceAsStream(supportedConfigurationsFilename);
if (in == null) {
throw new IllegalArgumentException(
"Resource not found: " + supportedConfigurationsFilename);
}

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> fileData = mapper.readValue(in, Map.class);

Map<String, List<String>> supported =
(Map<String, List<String>>) fileData.get("supportedConfigurations");
Map<String, List<String>> aliases = (Map<String, List<String>>) fileData.get("aliases");
Map<String, String> deprecated = (Map<String, String>) fileData.get("deprecations");

Map<String, String> aliasMapping = new HashMap<>();
for (Map.Entry<String, List<String>> entry : aliases.entrySet()) {
for (String alias : entry.getValue()) {
aliasMapping.put(alias, entry.getKey());
}
}
generateJavaFile(generatedMappingPath, supported.keySet(), aliases, aliasMapping, deprecated);
} catch (IOException e) {
throw new RuntimeException("Failed to read " + supportedConfigurationsFilename, e);
}
}

private static void generateJavaFile(
String outputPath,
Set<String> supported,
Map<String, List<String>> aliases,
Map<String, String> aliasMapping,
Map<String, String> deprecated)
throws IOException {
try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(Paths.get(outputPath)))) {
out.println("package datadog.environment;");
out.println();
out.println("import java.util.*;");
out.println();
out.println("public final class GeneratedSupportedConfigurations {");

// Supported set using Arrays.asList and HashSet
out.println(" public static final Set<String> SUPPORTED;");
out.println();

// ALIASES map
out.println(" public static final Map<String, List<String>> ALIASES;");
out.println();

// ALIAS_MAPPING map
out.println(" public static final Map<String, String> ALIAS_MAPPING;");
out.println();

// DEPRECATED map
out.println(" public static final Map<String, String> DEPRECATED;");
out.println();

// Static initializer block
out.println(" static {");

// Initialize SUPPORTED
out.print(" Set<String> supportedSet = new HashSet<>(Arrays.asList(");
Iterator<String> supportedIter = supported.iterator();
while (supportedIter.hasNext()) {
String key = supportedIter.next();
out.print("\"" + key + "\"");
if (supportedIter.hasNext()) {
out.print(", ");
}
}
out.println("));");
out.println(" SUPPORTED = Collections.unmodifiableSet(supportedSet);");
out.println();

// Initialize ALIASES
out.println(" Map<String, List<String>> aliasesMap = new HashMap<>();");
for (Map.Entry<String, List<String>> entry : aliases.entrySet()) {
out.printf(
" aliasesMap.put(\"%s\", Collections.unmodifiableList(Arrays.asList(%s)));\n",
entry.getKey(), quoteList(entry.getValue()));
}
out.println(" ALIASES = Collections.unmodifiableMap(aliasesMap);");
out.println();

// Initialize ALIAS_MAPPING
out.println(" Map<String, String> aliasMappingMap = new HashMap<>();");
for (Map.Entry<String, String> entry : aliasMapping.entrySet()) {
out.printf(" aliasMappingMap.put(\"%s\", \"%s\");\n", entry.getKey(), entry.getValue());
}
out.println(" ALIAS_MAPPING = Collections.unmodifiableMap(aliasMappingMap);");
out.println();

// Initialize DEPRECATED
out.println(" Map<String, String> deprecatedMap = new HashMap<>();");
for (Map.Entry<String, String> entry : deprecated.entrySet()) {
out.printf(" deprecatedMap.put(\"%s\", \"%s\");\n", entry.getKey(), entry.getValue());
}
out.println(" DEPRECATED = Collections.unmodifiableMap(deprecatedMap);");

out.println(" }"); // end static block
out.println("}"); // end class
}
}

private static String quoteList(List<String> list) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
sb.append("\"").append(list.get(i)).append("\"");
if (i < list.size() - 1) {
sb.append(", ");
}
}
return sb.toString();
}
}
Loading