diff --git a/CHANGELOG.md b/CHANGELOG.md index f1dec4779..b8f3dcbdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Hashicorp connection properties can now override http protocol to HTTP/1.1 from the default of HTTP/2. [#817](https://github.com/ConsenSys/web3signer/pull/817) ### Bugs fixed +- Support long name aliases in environment variables and YAML configuration [#825](https://github.com/Consensys/web3signer/pull/825) --- ## 23.6.0 diff --git a/commandline/src/main/java/tech/pegasys/web3signer/commandline/valueprovider/EnvironmentVariableDefaultProvider.java b/commandline/src/main/java/tech/pegasys/web3signer/commandline/valueprovider/EnvironmentVariableDefaultProvider.java index 8b983380a..5dd708bb4 100644 --- a/commandline/src/main/java/tech/pegasys/web3signer/commandline/valueprovider/EnvironmentVariableDefaultProvider.java +++ b/commandline/src/main/java/tech/pegasys/web3signer/commandline/valueprovider/EnvironmentVariableDefaultProvider.java @@ -33,9 +33,15 @@ public String defaultValue(final ArgSpec argSpec) { final OptionSpec optionSpec = (OptionSpec) argSpec; final String qualifiedPrefix = optionSpec.command().qualifiedName("_").replace("-", "_").toUpperCase(); - final String key = stripPrefix(optionSpec.longestName()).replace("-", "_").toUpperCase(); - final String qualifiedKey = qualifiedPrefix + "_" + key; - return environment.get(qualifiedKey); + + for (final String alias : optionSpec.names()) { + final String key = stripPrefix(alias).replace("-", "_").toUpperCase(); + final String qualifiedKey = qualifiedPrefix + "_" + key; + final String value = environment.get(qualifiedKey); + if (value != null) { + return value; + } + } } return null; // currently not supporting positional parameters diff --git a/commandline/src/main/java/tech/pegasys/web3signer/commandline/valueprovider/YamlConfigFileDefaultProvider.java b/commandline/src/main/java/tech/pegasys/web3signer/commandline/valueprovider/YamlConfigFileDefaultProvider.java index a8de27e02..a091f0b9f 100644 --- a/commandline/src/main/java/tech/pegasys/web3signer/commandline/valueprovider/YamlConfigFileDefaultProvider.java +++ b/commandline/src/main/java/tech/pegasys/web3signer/commandline/valueprovider/YamlConfigFileDefaultProvider.java @@ -13,15 +13,16 @@ package tech.pegasys.web3signer.commandline.valueprovider; import static java.util.function.Predicate.not; -import static tech.pegasys.web3signer.commandline.valueprovider.PrefixUtil.stripPrefix; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.NoSuchFileException; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; @@ -107,14 +108,14 @@ private void checkUnknownOptions(final Map result) { // parent command options final Set mainCommandOptions = commandLine.getCommandSpec().options().stream() - .map(YamlConfigFileDefaultProvider::buildOptionName) + .flatMap(YamlConfigFileDefaultProvider::buildOptionNames) .collect(Collectors.toSet()); // subcommands options final Set subCommandsOptions = subCommandValues(commandLine) .flatMap(YamlConfigFileDefaultProvider::allSubCommandOptions) - .map(YamlConfigFileDefaultProvider::buildQualifiedOptionName) + .flatMap(YamlConfigFileDefaultProvider::buildQualifiedOptionNames) .collect(Collectors.toSet()); picoCliOptionsKeys.addAll(mainCommandOptions); @@ -142,15 +143,16 @@ private void checkConfigurationValidity(final boolean isEmpty) { } private String getConfigurationValue(final OptionSpec optionSpec) { - final String keyName; + final Stream keyAliases; if (commandLine.getCommandName().equals(optionSpec.command().name())) { - keyName = buildOptionName(optionSpec); + keyAliases = buildOptionNames(optionSpec); } else { // subcommand option - keyName = buildQualifiedOptionName(optionSpec); + keyAliases = buildQualifiedOptionNames(optionSpec); } - final Object value = result.get(keyName); + final Object value = + keyAliases.map(k -> result.get(k)).filter(Objects::nonNull).findFirst().orElse(null); if (value == null) { return null; @@ -173,13 +175,13 @@ private static Stream allSubCommandOptions(final CommandLine subcomm subCommandValues(subcommand).flatMap(YamlConfigFileDefaultProvider::allSubCommandOptions)); } - private static String buildQualifiedOptionName(final OptionSpec optionSpec) { + private static Stream buildQualifiedOptionNames(final OptionSpec optionSpec) { final String cmdPrefix = optionSpec.command().qualifiedName("."); final String prefixWithoutWeb3Signer = cmdPrefix.replaceFirst(WEB3SIGNER_CMD_PREFIX, ""); - return prefixWithoutWeb3Signer + "." + buildOptionName(optionSpec); + return buildOptionNames(optionSpec).map(s -> prefixWithoutWeb3Signer + "." + s); } - private static String buildOptionName(final OptionSpec optionSpec) { - return stripPrefix(optionSpec.longestName()); + private static Stream buildOptionNames(final OptionSpec optionSpec) { + return Arrays.stream(optionSpec.names()).map(PrefixUtil::stripPrefix); } } diff --git a/commandline/src/test-support/java/tech/pegasys/web3signer/CmdlineHelpers.java b/commandline/src/test-support/java/tech/pegasys/web3signer/CmdlineHelpers.java index 968d7f04f..351080319 100644 --- a/commandline/src/test-support/java/tech/pegasys/web3signer/CmdlineHelpers.java +++ b/commandline/src/test-support/java/tech/pegasys/web3signer/CmdlineHelpers.java @@ -28,9 +28,14 @@ public static String validBaseYamlOptions() { return "http-listen-port: 6001\n" + "http-listen-host: \"localhost\"\n" + "key-store-path: \"./keys_yaml\"\n" + + "metrics-categories: \"HTTP\"\n" + "logging: \"INFO\"\n"; } + public static String validBaseYamlAliasOptions() { + return "metrics-category: \"HTTP\"\n" + "l: \"INFO\"\n"; + } + public static Map validBaseEnvironmentVariableOptions() { return Map.of( "WEB3SIGNER_HTTP_LISTEN_PORT", diff --git a/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/DemoCommand.java b/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/DemoCommand.java index 92a5f9ac4..65b83524c 100644 --- a/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/DemoCommand.java +++ b/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/DemoCommand.java @@ -32,9 +32,19 @@ public class DemoCommand { @Option(names = "--name", description = "Name") String name; + @Option( + names = {"--alias", "--aliases"}, + description = "Aliases") + String alias; + @Command(name = "country", description = "Country Codes") static class SubCommand { @Option(names = "--codes", split = ",") List countryCodes; + + @Option( + names = {"--subalias", "--subaliases"}, + description = "Subcommand Alias") + String subalias; } } diff --git a/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/EnvironmentVariableDefaultProviderTest.java b/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/EnvironmentVariableDefaultProviderTest.java index b83b9ed46..ef6bbf151 100644 --- a/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/EnvironmentVariableDefaultProviderTest.java +++ b/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/EnvironmentVariableDefaultProviderTest.java @@ -83,6 +83,29 @@ void emptyEnvironmentVariablesResultsNullValues() { assertThat(subCommand.countryCodes).isNullOrEmpty(); } + @Test + void environmentVariablesAreCreatedForAliases() { + + assertAliasCreated("DEMO_ALIAS", "testValue"); + assertAliasCreated("DEMO_ALIASES", "testValue2"); + assertAliasCreated("DEMO_COUNTRY_SUBALIAS", "testValue3", "country"); + assertAliasCreated("DEMO_COUNTRY_SUBALIASES", "testValue4", "country"); + } + + private void assertAliasCreated(String envKey, String envValue, String... subCommandName) { + final EnvironmentVariableDefaultProvider defaultProvider = + new EnvironmentVariableDefaultProvider(Map.of(envKey, envValue)); + + commandLine.setDefaultValueProvider(defaultProvider); + commandLine.parseArgs(subCommandName); + + if (subCommandName.length > 0) { + assertThat(subCommand.subalias).isEqualTo(envValue); + } else { + assertThat(demoCommand.alias).isEqualTo(envValue); + } + } + private Map validEnvMap() { return Map.of( "DEMO_X", "10", "DEMO_Y", "20", "DEMO_NAME", "test name", "DEMO_COUNTRY_CODES", "AU,US"); diff --git a/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/YamlConfigFileDefaultProviderTest.java b/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/YamlConfigFileDefaultProviderTest.java index 4d701fc69..5f5a52199 100644 --- a/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/YamlConfigFileDefaultProviderTest.java +++ b/commandline/src/test/java/tech/pegasys/web3signer/commandline/valueprovider/YamlConfigFileDefaultProviderTest.java @@ -21,11 +21,13 @@ import tech.pegasys.web3signer.CmdlineHelpers; import tech.pegasys.web3signer.commandline.Web3SignerBaseCommand; import tech.pegasys.web3signer.commandline.valueprovider.DemoCommand.SubCommand; +import tech.pegasys.web3signer.common.Web3SignerMetricCategory; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Set; import org.apache.logging.log4j.Level; import org.junit.jupiter.api.Test; @@ -51,13 +53,21 @@ void valuesFromConfigFileArePopulated(@TempDir final Path tempDir) throws IOExce assertThat(web3SignerBaseCommand.getHttpListenPort()).isEqualTo(6001); assertThat(web3SignerBaseCommand.getKeyConfigPath()).isEqualTo(Path.of("./keys_yaml")); + assertThat(web3SignerBaseCommand.getMetricCategories()) + .isEqualTo(Set.of(Web3SignerMetricCategory.HTTP)); + assertThat(web3SignerBaseCommand.getLogLevel()).isEqualTo(Level.INFO); } @Test void valuesFromConfigFileWithSubcommandArePopulated(@TempDir final Path tempDir) throws IOException { final String subcommandOptions = - String.join(lineSeparator(), "demo.x: 10", "demo.y: 2", "demo.name: \"test name\""); + String.join( + lineSeparator(), + "demo.x: 10", + "demo.y: 2", + "demo.name: \"test name\"", + "demo.aliases: \"test alias\""); final String config = CmdlineHelpers.validBaseYamlOptions() + subcommandOptions; final File configFile = Files.writeString(tempDir.resolve("config.yaml"), config).toFile(); @@ -74,6 +84,26 @@ void valuesFromConfigFileWithSubcommandArePopulated(@TempDir final Path tempDir) assertThat(subCommand.x).isEqualTo(10); assertThat(subCommand.y).isEqualTo(2); assertThat(subCommand.name).isEqualTo("test name"); + assertThat(subCommand.alias).isEqualTo("test alias"); + } + + @Test + void aliasesFromConfigFileArePopulated(@TempDir final Path tempDir) throws IOException { + final String subcommandOptions = String.join(lineSeparator(), "demo.alias: \"test alias\""); + final String config = CmdlineHelpers.validBaseYamlAliasOptions() + subcommandOptions; + final File configFile = Files.writeString(tempDir.resolve("config.yaml"), config).toFile(); + final Web3SignerBaseCommand web3SignerBaseCommand = new Web3SignerBaseCommand(); + final DemoCommand subCommand = new DemoCommand(); + final CommandLine commandLine = new CommandLine(web3SignerBaseCommand); + commandLine.registerConverter(Level.class, Level::valueOf); + commandLine.addSubcommand("demo", subCommand); + commandLine.setDefaultValueProvider(new YamlConfigFileDefaultProvider(commandLine, configFile)); + commandLine.parseArgs("demo"); + + assertThat(web3SignerBaseCommand.getMetricCategories()) + .isEqualTo(Set.of(Web3SignerMetricCategory.HTTP)); + assertThat(web3SignerBaseCommand.getLogLevel()).isEqualTo(Level.INFO); + assertThat(subCommand.alias).isEqualTo("test alias"); } @Test diff --git a/gradle/versions.gradle b/gradle/versions.gradle index fd065f5e1..a3df10814 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -119,9 +119,9 @@ dependencyManagement { entry 'besu' entry ('core') { exclude group: 'com.github.jnr', name: 'jnr-unixsocket' + exclude group: 'org.bouncycastle', name: 'bcprov-jdk15on' } - entry 'crypto' - entry ('utils') { + entry ('crypto') { exclude group: 'org.bouncycastle', name: 'bcprov-jdk15on' } }