Skip to content

Support targeting services with configurations in stable configuration file #8526

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

Merged
merged 109 commits into from
Apr 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
a9d4400
Abstract away getVMArgumentsThroughReflection into a VMArgsCache class
mtoffl01 Mar 10, 2025
d688313
Change underlying data structure of VMArgsCache to HashSet
mtoffl01 Mar 11, 2025
d6344a8
Update internal-api/src/main/java/datadog/trace/bootstrap/config/prov…
mtoffl01 Mar 11, 2025
6aba3f8
Update internal-api/src/main/java/datadog/trace/bootstrap/config/prov…
mtoffl01 Mar 11, 2025
8afbec1
Update internal-api/src/main/java/datadog/trace/bootstrap/config/prov…
mtoffl01 Mar 11, 2025
d807b02
Clean up for initial review
mtoffl01 Mar 12, 2025
0603490
fix merge conflicts
mtoffl01 Mar 12, 2025
7ce4953
move VMArgsCache to components/cli
mtoffl01 Mar 14, 2025
7a9f694
fix datadog.cli import
mtoffl01 Mar 14, 2025
dd17ca2
nits: remove outdated comments
mtoffl01 Mar 14, 2025
2798bed
annotate initJvmArgs with @SuppressForbidden to allow Class.forName()…
mtoffl01 Mar 17, 2025
f5d89a3
initial implementation using snakeyaml + StableConfigYaml for parsing…
mtoffl01 Mar 7, 2025
0f54ff1
Clean up tests + expand selectorMatch to cover environment_variables …
mtoffl01 Mar 10, 2025
9826f0f
address [some] github codequality breaches
mtoffl01 Mar 10, 2025
63280ae
use config_id even if configs are empty/missing
mtoffl01 Mar 11, 2025
5859ec9
nits: refactor StableConfigParser for clarity
mtoffl01 Mar 11, 2025
4e8c0fa
Clean up for first review
mtoffl01 Mar 12, 2025
1bf6ccc
Amend StableConfigParserTest valid test to include multiple selector-…
mtoffl01 Mar 12, 2025
57762b1
nits/ cleanup
mtoffl01 Mar 13, 2025
fe843e1
nits/ cleanup
mtoffl01 Mar 13, 2025
55a798b
Fix Test Optimization init when repo root cannot be determined (#8533)
nikita-tkachenko-datadog Mar 11, 2025
cdd2010
Improve Baggage API (#8523)
PerfectSlayer Mar 11, 2025
9a4458a
Update system-tests to 5aee0ed598fd984344cf0da0048b27bdb2eb4da1 (#8537)
mhlidd Mar 11, 2025
89286d7
Introducing `DD_TRACE_EXPERIMENTAL_FEATURES_ENABLED` Config (#8536)
mhlidd Mar 11, 2025
4c2a2f5
Remove AgentScope.source() from instrumentation API (#8539)
mcculls Mar 12, 2025
fd8a076
Add smoke tests for java's concurrent API (#8438)
sarahchen6 Mar 12, 2025
f1da84c
Update capabilities tagging to use versioning (#8540)
daniel-mohedano Mar 12, 2025
7d5b034
Remove ScopeSource from instrumentation API (#8542)
mcculls Mar 12, 2025
c1d1693
Simplify activateSpan calls which use the default value for isAsyncPr…
mcculls Mar 12, 2025
5ae5655
Make the default config sources more robust when a security manager i…
mcculls Mar 12, 2025
dc70612
Support common config sources for user-provided git info (#8547)
nikita-tkachenko-datadog Mar 13, 2025
3765fd1
Allow login events SDK to be used with appsec disabled (#8464)
manuel-alvarez-alvarez Mar 13, 2025
b7656bd
Update system-tests to c208feb5b40cca543670870b9601509d6a69c65e (#8550)
manuel-alvarez-alvarez Mar 13, 2025
6eb11aa
Add missing address for signup event (#8469)
manuel-alvarez-alvarez Mar 13, 2025
0a8bc73
Remove unnecessary calls to setAsyncPropagationEnabled (#8551)
mcculls Mar 13, 2025
26c11f4
Be consistent when deciding when to do async propagation (#8555)
mcculls Mar 13, 2025
3c4876c
Add new parser for `DD_TAGS` and prioritizing `DD_SERVICE` (#8296)
mhlidd Mar 13, 2025
518cd4a
Async propagation is on by default, so HystrixThreadPoolInstrumentati…
mcculls Mar 13, 2025
8f2d28b
Ensure shaded helpers have unique names (#8559)
amarziali Mar 14, 2025
90c7cbe
ssi tests one-pipeline (#8558)
robertomonteromiguel Mar 14, 2025
d06699d
Fix ForkJoinPool.execute() instrumentation on Java 21+ (#8560)
PerfectSlayer Mar 14, 2025
12fe632
Simplify activateSpan API to not include async propagation flag (#8557)
mcculls Mar 14, 2025
7475368
Use internal artifact proxy for Gitlab jobs (#8554)
randomanderson Mar 14, 2025
f646940
Remove ScopeSource enum (#8565)
mcculls Mar 14, 2025
e8eb022
fix(ci): Mark tests as flaky (#8568)
PerfectSlayer Mar 17, 2025
7ff940b
Prevent before callsites targeting constructors in super calls (#8549)
manuel-alvarez-alvarez Mar 17, 2025
3d8d129
Add JDK built-in support for UDS on Java 16+ (#8314)
sarahchen6 Mar 17, 2025
8327a8f
Allow to manually set PR info (#8566)
nikita-tkachenko-datadog Mar 17, 2025
9a78dd7
Nits: Update comments and include exception in log messages
mtoffl01 Mar 17, 2025
630c61f
Vendor snakeyaml
mcculls Mar 18, 2025
11b01da
Fix PlayNettySmokeTest logging config (#8576)
smola Mar 17, 2025
888cbd4
Expose Context.empty() as building block for creating custom root con…
mcculls Mar 17, 2025
b5b31c3
RASP capabilities for LFI is not sent when RASP is not fully enabled…
jandro996 Mar 17, 2025
6473621
Minor test changes to avoid deprecated API (#8574)
mcculls Mar 18, 2025
84ba99a
internal tests for stable config use snakeyaml to build test files
mcculls Mar 18, 2025
a920812
Fix test
mcculls Mar 18, 2025
f07ed11
Fix instrumentation test+muzzle
mcculls Mar 18, 2025
e624538
Inherited decision maker is a meta (#8578)
amarziali Mar 18, 2025
f7a339e
Simplification: Context.root() is always empty (#8580)
mcculls Mar 18, 2025
1e1ef67
Support and test kafka-clients 4 (#8581)
amarziali Mar 18, 2025
3f336db
List components:yaml in the dependencies to exclude outside of shared…
mcculls Mar 18, 2025
0c2b8e2
fix muzzle on CI
mcculls Mar 18, 2025
c9d4c10
Improve StableConfig exception logging
mtoffl01 Mar 18, 2025
7a8fabe
Include StableConfigYaml in java-agent shadowJar
mtoffl01 Mar 18, 2025
d1fc580
Change in selectorMatch switch to return false
mtoffl01 Mar 19, 2025
f1fdaaf
Make selectorMatch case insensitive
mtoffl01 Mar 19, 2025
e94a06a
fix null ptr exceptions in selectorMatch
mtoffl01 Mar 19, 2025
a52a393
convert underlying datastructure to hashmap; split jvm args into key …
mtoffl01 Mar 21, 2025
dab2bbb
write CLIHelper Test
mtoffl01 Mar 21, 2025
e9fec18
Update javaagent logic inside of AgentBootstrap
mtoffl01 Mar 21, 2025
f04424e
merge with base branch mtoff/jvm-args
mtoffl01 Mar 21, 2025
1ac75d9
Rebase with mtoff/jvm-args
mtoffl01 Mar 24, 2025
1d30309
Merge branch 'master' into mtoff/jvm-args
mtoffl01 Mar 24, 2025
ca2ae42
merge in mtoff/jvm-args
mtoffl01 Mar 24, 2025
94c6d53
remove unused components/cli test dir
mtoffl01 Mar 24, 2025
73af087
Cleanup
mtoffl01 Mar 24, 2025
4ab687f
nits/cleanup
mtoffl01 Mar 24, 2025
2ca8d98
Merge remote-tracking branch 'origin/master' into mtoff/jvm-args
mcculls Mar 25, 2025
253e5e4
Fix package directory
mcculls Mar 25, 2025
e67ae7a
Cleanup code:
mcculls Mar 25, 2025
b844607
Remove warning when reflection fails
mcculls Mar 25, 2025
8837a21
Expose components:cli from internal-api
mcculls Mar 25, 2025
46f0902
Merge branch 'mtoff/jvm-args' into mtoff/stable_cfg_2
mcculls Mar 25, 2025
2a2012c
Fix package directory
mcculls Mar 25, 2025
f00b0f4
Expose components:yaml from internal-api
mcculls Mar 25, 2025
e3ad995
Domain classes should not exist in component module
mcculls Mar 25, 2025
8324c3a
Cleanup relocation
mcculls Mar 25, 2025
83b2f7e
Fix
mcculls Mar 25, 2025
b0f4c55
Cleanup
mcculls Mar 25, 2025
e2ef0ef
Merge branch 'master' into mtoff/stable_cfg_2
mtoffl01 Mar 25, 2025
f085baf
Remove unused ConfigurationValue.toString; hopefully pass Jacoco test…
mtoffl01 Mar 26, 2025
3b86143
reset to f085bafeed
mtoffl01 Mar 27, 2025
1a48f84
manually remove testImplementation snakeyaml 1.33 changes in dd-smoke…
mtoffl01 Mar 27, 2025
a99d016
exclude org.yaml.snakeyaml dependency from dd-smoke-tests
mtoffl01 Mar 27, 2025
a62edd3
Merge branch 'master' into mtoff/stable_cfg_2
mtoffl01 Mar 27, 2025
8389804
Merge branch 'master' into mtoff/stable_cfg_2
mtoffl01 Mar 28, 2025
1a8cee4
Remove unused ConfigurationValue.toString (again..)
mtoffl01 Mar 28, 2025
679c4ca
Attempt to fix muzzle
mcculls Mar 29, 2025
9e905b5
Attempt to fix muzzle
mcculls Mar 29, 2025
29c1925
comment
mcculls Mar 29, 2025
6f28159
Merge remote-tracking branch 'origin/master' into mtoff/stable_cfg_2
mcculls Mar 29, 2025
10a1028
cleanup
mcculls Mar 29, 2025
d9b6836
log when we find stable config. rather than when we don't (also reduc…
mcculls Mar 29, 2025
65b4cb7
Merge branch 'master' into mtoff/stable_cfg_2
mtoffl01 Mar 31, 2025
b8283a9
Update internal-api/src/main/java/datadog/trace/bootstrap/config/prov…
mtoffl01 Apr 2, 2025
dd40811
Update internal-api/src/main/java/datadog/trace/bootstrap/config/prov…
mtoffl01 Apr 2, 2025
ccc18c6
Make selector match package-private
mtoffl01 Apr 2, 2025
cffcc17
remove comment reminder about process_arguments test
mtoffl01 Apr 3, 2025
23f1013
Merge branch 'master' into mtoff/stable_cfg_2
mtoffl01 Apr 3, 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
14 changes: 14 additions & 0 deletions components/yaml/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id("me.champeau.jmh")
}

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

jmh {
version = "1.28"
}

// https://repo1.maven.org/maven2/org/yaml/snakeyaml/2.4/snakeyaml-2.4.pom
dependencies {
implementation("org.yaml", "snakeyaml", "2.4")
}
19 changes: 19 additions & 0 deletions components/yaml/src/main/java/datadog/yaml/YamlParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package datadog.yaml;

import java.io.FileInputStream;
import java.io.IOException;
import org.yaml.snakeyaml.Yaml;

public class YamlParser {
// Supports clazz == null for default yaml parsing
public static <T> T parse(String filePath, Class<T> clazz) throws IOException {
Yaml yaml = new Yaml();
try (FileInputStream fis = new FileInputStream(filePath)) {
if (clazz == null) {
return yaml.load(fis);
} else {
return yaml.loadAs(fis, clazz);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public final class Constants {
public static final String[] BOOTSTRAP_PACKAGE_PREFIXES = {
"datadog.slf4j",
"datadog.json",
"datadog.yaml",
"datadog.context",
"datadog.cli",
"datadog.appsec.api",
Expand Down
3 changes: 2 additions & 1 deletion dd-java-agent/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ ext.generalShadowJarConfig = {

final String projectName = "${project.name}"

// Prevents conflict with other OkHttp instances, but don't relocate instrumentation
// Prevents conflict with other instances, but doesn't relocate instrumentation
if (!projectName.equals('instrumentation')) {
relocate 'org.yaml.snakeyaml', 'datadog.snakeyaml'
relocate 'okhttp3', 'datadog.okhttp3'
relocate 'okio', 'datadog.okio'
}
Expand Down
3 changes: 3 additions & 0 deletions dd-java-agent/instrumentation/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ subprojects { Project subProj ->
def name = "java$version.majorVersion"
jdkCompile = "main_${name}Implementation"
}
configurations.muzzleBootstrap {
exclude group: 'org.yaml', module : 'snakeyaml' // we vendor this in the agent jar
}
dependencies {
// Apply common dependencies for instrumentation.
implementation project(':dd-trace-api')
Expand Down
8 changes: 7 additions & 1 deletion dd-java-agent/instrumentation/snakeyaml/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ addTestSuiteForDir('latestDepTest', 'test')

dependencies {
compileOnly group: 'org.yaml', name: 'snakeyaml', version: '1.33'
testImplementation group: 'org.yaml', name: 'snakeyaml', version: '1.33'

testImplementation('org.yaml:snakeyaml') {
version {
strictly "[1.4, 2.0)"
prefer '1.33'
}
}

latestDepTestImplementation group: 'org.yaml', name: 'snakeyaml', version: '1.+'
}
4 changes: 4 additions & 0 deletions dd-java-agent/testing/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ excludedClassesCoverage += [
'datadog.trace.agent.test.TestProfilingContextIntegration.TestQueueTiming'
]

configurations.api {
exclude group: 'org.yaml', module: 'snakeyaml' // we vendor this in the agent jar
}

dependencies {
api libs.bytebuddy
api libs.bytebuddyagent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class SpockRunner extends JUnitPlatform {
public static final String[] BOOTSTRAP_PACKAGE_PREFIXES_COPY = {
"datadog.slf4j",
"datadog.json",
"datadog.yaml",
"datadog.context",
"datadog.cli",
"datadog.appsec.api",
Expand Down
4 changes: 4 additions & 0 deletions gradle/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ final class CachedData {
exclude(project(':communication'))
exclude(project(':components:context'))
exclude(project(':components:json'))
exclude(project(':components:yaml'))
exclude(project(':components:cli'))
exclude(project(':remote-config:remote-config-api'))
exclude(project(':remote-config:remote-config-core'))
Expand Down Expand Up @@ -49,6 +50,9 @@ final class CachedData {

// cafe_crypto and its transitives
exclude(dependency('cafe.cryptography::'))

// snakeyaml and its transitives
exclude(dependency('org.yaml:snakeyaml'))
}
]
}
Expand Down
3 changes: 2 additions & 1 deletion internal-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -239,21 +239,22 @@ dependencies {
api project(':dd-trace-api')
api libs.slf4j
api project(':components:context')
api project(':components:yaml')
api project(':components:cli')
api project(":utils:time-utils")

// has to be loaded by system classloader:
// it contains annotations that are also present in the instrumented application classes
api "com.datadoghq:dd-javac-plugin-client:0.2.2"

testImplementation("org.yaml:snakeyaml:2.4")
testImplementation project(":utils:test-utils")
testImplementation("org.assertj:assertj-core:3.20.2")
testImplementation libs.bundles.junit5
testImplementation group: 'org.junit.vintage', name: 'junit-vintage-engine', version: libs.versions.junit5.get()
testImplementation libs.commons.math
testImplementation libs.bundles.mockito
testImplementation libs.truth
testImplementation 'org.yaml:snakeyaml:2.0'
}

jmh {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,77 +1,179 @@
package datadog.trace.bootstrap.config.provider;

import java.io.File;
import datadog.cli.CLIHelper;
import datadog.trace.bootstrap.config.provider.stableconfigyaml.ConfigurationMap;
import datadog.trace.bootstrap.config.provider.stableconfigyaml.Rule;
import datadog.trace.bootstrap.config.provider.stableconfigyaml.Selector;
import datadog.trace.bootstrap.config.provider.stableconfigyaml.StableConfigYaml;
import datadog.yaml.YamlParser;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiPredicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class StableConfigParser {
private static final Logger log = LoggerFactory.getLogger(StableConfigParser.class);
// Match config_id:<value>
private static final Pattern idPattern = Pattern.compile("^config_id\\s*:(.*)$");
// Match 'apm_configuration_default:'
private static final Pattern apmConfigPattern = Pattern.compile("^apm_configuration_default:$");
// Match indented (2 spaces) key-value pairs, either with double quotes or without
private static final Pattern keyValPattern =
Pattern.compile("^\\s{2}([^:]+):\\s*(\"[^\"]*\"|[^\"\\n]*)$");;

private static final Set<String> VM_ARGS = new HashSet<>(CLIHelper.getVmArgs());

/**
* Parses a configuration file and returns a stable configuration object.
*
* <p>This method reads a configuration file from the given file path, parses the YAML content,
* and identifies configurations for the process using a combination of apm_configuration_default
* and apm_configuration_rules. If a matching rule is found in apm_configuration_rules, it returns
* a {@link StableConfigSource.StableConfig} object with the merged configuration. If no matching
* rule is found, it returns the default configuration. If neither a matching rule nor a default
* configuration is found, an empty configuration is returned.
*
* @param filePath The path to the YAML configuration file to be parsed.
* @return A {@link StableConfigSource.StableConfig} object containing the stable configuration.
* @throws IOException If there is an error reading the file or parsing the YAML content.
*/
public static StableConfigSource.StableConfig parse(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
log.debug("Stable configuration file not available at specified path: {}", file);
return StableConfigSource.StableConfig.EMPTY;
try {
StableConfigYaml data = YamlParser.parse(filePath, StableConfigYaml.class);

String configId = data.getConfig_id();
ConfigurationMap configMap = data.getApm_configuration_default();
List<Rule> rules = data.getApm_configuration_rules();

if (!rules.isEmpty()) {
for (Rule rule : rules) {
// Use the first matching rule
if (doesRuleMatch(rule)) {
// Merge configs found in apm_configuration_rules with those found in
// apm_configuration_default
configMap.putAll(rule.getConfiguration());
return createStableConfig(configId, configMap);
}
}
}
// If configs were found in apm_configuration_default, use them
if (!configMap.isEmpty()) {
return createStableConfig(configId, configMap);
}

// If there's a configId but no configMap, use configId but return an empty map
if (configId != null) {
return new StableConfigSource.StableConfig(configId, Collections.emptyMap());
}

} catch (IOException e) {
log.debug(
"Stable configuration file either not found or not readable at filepath {}", filePath);
}
return StableConfigSource.StableConfig.EMPTY;
}

/**
* Checks if the rule's selectors match the current process. All must match for a "true" return
* value.
*/
private static boolean doesRuleMatch(Rule rule) {
for (Selector selector : rule.getSelectors()) {
if (!selectorMatch(
selector.getOrigin(), selector.getMatches(), selector.getOperator(), selector.getKey())) {
return false; // Return false immediately if any selector doesn't match
}
}
return true; // Return true if all selectors match
}

/** Creates a StableConfig object from the provided configId and configMap. */
private static StableConfigSource.StableConfig createStableConfig(
String configId, ConfigurationMap configMap) {
return new StableConfigSource.StableConfig(configId, new HashMap<>(configMap));
}

private static boolean validOperatorForLanguageOrigin(String operator) {
operator = operator.toLowerCase();
// "exists" is not valid
switch (operator) {
case "equals":
case "starts_with":
case "ends_with":
case "contains":
return true;
default:
return false;
}
}

private static boolean checkEnvMatches(
List<String> values, List<String> matches, BiPredicate<String, String> compareFunc) {
// envValue shouldn't be null, but doing an extra check to avoid NullPointerException on
// compareFunc.test
if (values == null) {
return false;
}
Map<String, String> configMap = new HashMap<>();
String[] configId = new String[1];
try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
int apmConfigNotFound = -1, apmConfigStarted = 0, apmConfigComplete = 1;
int[] apmConfigFound = {apmConfigNotFound};
lines.forEach(
line -> {
Matcher matcher = idPattern.matcher(line);
if (matcher.find()) {
// Do not allow duplicate config_id keys
if (configId[0] != null) {
throw new RuntimeException("Duplicate config_id keys found; file may be malformed");
}
configId[0] = trimQuotes(matcher.group(1).trim());
return; // go to next line
}
// TODO: Do not allow duplicate apm_configuration_default keys; and/or return early once
// apmConfigFound[0] == apmConfigComplete
if (apmConfigFound[0] == apmConfigNotFound
&& apmConfigPattern.matcher(line).matches()) {
apmConfigFound[0] = apmConfigStarted;
return; // go to next line
}
if (apmConfigFound[0] == apmConfigStarted) {
Matcher keyValueMatcher = keyValPattern.matcher(line);
if (keyValueMatcher.matches()) {
configMap.put(
keyValueMatcher.group(1).trim(),
trimQuotes(keyValueMatcher.group(2).trim())); // Store key-value pair in map
} else {
// If we encounter a non-indented or non-key-value line, stop processing
apmConfigFound[0] = apmConfigComplete;
}
}
});
return new StableConfigSource.StableConfig(configId[0], configMap);
for (String match : matches) {
if (match == null) {
continue;
}
for (String value : values) {
if (compareFunc.test(value, match.toLowerCase())) {
return true;
}
}
}
return false;
}

private static String trimQuotes(String value) {
if (value.length() > 1 && (value.startsWith("'") && value.endsWith("'"))
|| (value.startsWith("\"") && value.endsWith("\""))) {
return value.substring(1, value.length() - 1);
// We do all of the case insensitivity modifications in this function, because each selector will
// be viewed just once
static boolean selectorMatch(String origin, List<String> matches, String operator, String key) {
switch (origin.toLowerCase()) {
case "language":
if (!validOperatorForLanguageOrigin(operator)) {
return false;
}
for (String entry : matches) {
// loose match on any reference to "*java*"
if (entry.toLowerCase().contains("java")) {
return true;
}
}
case "environment_variables":
if (key == null) {
return false;
}
String envValue = System.getenv(key.toUpperCase());
if (envValue == null) {
return false;
}
envValue = envValue.toLowerCase();
switch (operator.toLowerCase()) {
case "exists":
// We don't care about the value
return true;
case "equals":
return checkEnvMatches(
Collections.singletonList(envValue), matches, String::equalsIgnoreCase);
case "starts_with":
return checkEnvMatches(
Collections.singletonList(envValue), matches, String::startsWith);
case "ends_with":
return checkEnvMatches(Collections.singletonList(envValue), matches, String::endsWith);
case "contains":
return checkEnvMatches(Collections.singletonList(envValue), matches, String::contains);
default:
return false;
}
case "process_arguments":
// For now, always return true if `key` exists in the JVM Args
// TODO: flesh out the meaning of each operator for process_arguments
return VM_ARGS.contains(key);
case "tags":
// TODO: Support this down the line (Must define the source of "tags" first)
return false;
default:
return false;
}
return value;
}
}
Loading