mirror of
https://github.com/corda/corda.git
synced 2024-12-26 16:11:12 +00:00
ENT-1661 Doorman crashes ungracefully when started with incorrect or … (#747)
* ENT-1661 Doorman crashes ungracefully when started with incorrect or no program arguments. Should display a meaningful message instead.
This commit is contained in:
parent
b3a4e3907f
commit
57291c435c
@ -68,6 +68,8 @@ publish {
|
||||
|
||||
dependencies {
|
||||
compile project(':node')
|
||||
// TODO: remove this when ArgsParser is moved into corda.
|
||||
compile project(':network-management')
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile "org.assertj:assertj-core:${assertj_version}"
|
||||
}
|
||||
|
@ -1,75 +1,61 @@
|
||||
package com.r3.corda.networkmanage.registration
|
||||
|
||||
import com.r3.corda.networkmanage.common.utils.ArgsParser
|
||||
import com.r3.corda.networkmanage.registration.ToolOption.KeyCopierOption
|
||||
import com.r3.corda.networkmanage.registration.ToolOption.RegistrationOption
|
||||
import joptsimple.OptionParser
|
||||
import joptsimple.OptionSet
|
||||
import joptsimple.OptionSpecBuilder
|
||||
import joptsimple.util.PathConverter
|
||||
import joptsimple.util.PathProperties
|
||||
import net.corda.core.crypto.Crypto
|
||||
import java.nio.file.Path
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
Crypto.registerProviders() // Required to register Providers first thing on boot.
|
||||
val options = try {
|
||||
parseOptions(*args)
|
||||
} catch (e: ShowHelpException) {
|
||||
e.errorMessage?.let(::println)
|
||||
e.parser.printHelpOn(System.out)
|
||||
exitProcess(0)
|
||||
}
|
||||
val options = ToolArgsParser().parseOrExit(*args, printHelpOn = System.out)
|
||||
when (options) {
|
||||
is RegistrationOption -> options.runRegistration()
|
||||
is KeyCopierOption -> options.copyKeystore()
|
||||
}
|
||||
}
|
||||
|
||||
fun parseOptions(vararg args: String): ToolOption {
|
||||
val optionParser = OptionParser()
|
||||
val helpOption = optionParser.acceptsAll(listOf("h", "help"), "show help").forHelp()
|
||||
class ToolArgsParser : ArgsParser<ToolOption>() {
|
||||
private val importKeyStoreArg = optionParser.accepts("importkeystore")
|
||||
|
||||
val importKeyStoreArg = optionParser.accepts("importkeystore")
|
||||
|
||||
val configFileArg = optionParser
|
||||
private val configFileArg = optionParser
|
||||
.accepts("config-file", "Path to the registration config file")
|
||||
.availableUnless(importKeyStoreArg)
|
||||
.requiredUnless(importKeyStoreArg)
|
||||
.withRequiredArg()
|
||||
.withValuesConvertedBy(PathConverter(PathProperties.FILE_EXISTING))
|
||||
|
||||
// key copy tool args
|
||||
val destKeystorePathArg = optionParser.accepts("destkeystore", "Path to the destination keystore which the private key should be copied to")
|
||||
private val destKeystorePathArg = optionParser.accepts("destkeystore", "Path to the destination keystore which the private key should be copied to")
|
||||
.requireOnlyIf(importKeyStoreArg)
|
||||
.withRequiredArg()
|
||||
.withValuesConvertedBy(PathConverter(PathProperties.FILE_EXISTING))
|
||||
|
||||
val srcKeystorePathArg = optionParser.accepts("srckeystore", "Path to the source keystore containing the private key")
|
||||
private val srcKeystorePathArg = optionParser.accepts("srckeystore", "Path to the source keystore containing the private key")
|
||||
.requireOnlyIf(importKeyStoreArg)
|
||||
.withRequiredArg()
|
||||
.withValuesConvertedBy(PathConverter(PathProperties.FILE_EXISTING))
|
||||
|
||||
val destPasswordArg = optionParser.accepts("deststorepass", "Source keystore password. Read in from the console if not specified.")
|
||||
private val destPasswordArg = optionParser.accepts("deststorepass", "Source keystore password. Read in from the console if not specified.")
|
||||
.availableIf(importKeyStoreArg)
|
||||
.withRequiredArg()
|
||||
|
||||
val srcPasswordArg = optionParser.accepts("srcstorepass", "Destination keystore password. Read in from the console if not specified.")
|
||||
private val srcPasswordArg = optionParser.accepts("srcstorepass", "Destination keystore password. Read in from the console if not specified.")
|
||||
.availableIf(importKeyStoreArg)
|
||||
.withRequiredArg()
|
||||
|
||||
val destAliasArg = optionParser.accepts("destalias", "The alias under which the private key will be stored in the destination key store. If not provided then [srcalias] is used.")
|
||||
private val destAliasArg = optionParser.accepts("destalias", "The alias under which the private key will be stored in the destination key store. If not provided then [srcalias] is used.")
|
||||
.availableIf(importKeyStoreArg)
|
||||
.withRequiredArg()
|
||||
|
||||
val srcAliasArg = optionParser.accepts("srcalias", "The alias under which the private key resides in the source key store")
|
||||
private val srcAliasArg = optionParser.accepts("srcalias", "The alias under which the private key resides in the source key store")
|
||||
.requireOnlyIf(importKeyStoreArg)
|
||||
.withRequiredArg()
|
||||
|
||||
val optionSet = optionParser.parse(*args)
|
||||
if (optionSet.has(helpOption)) {
|
||||
throw ShowHelpException(optionParser)
|
||||
}
|
||||
|
||||
override fun parse(optionSet: OptionSet): ToolOption {
|
||||
val isCopyKey = optionSet.has(importKeyStoreArg)
|
||||
return if (isCopyKey) {
|
||||
val srcKeystorePath = optionSet.valueOf(srcKeystorePathArg)
|
||||
@ -83,6 +69,7 @@ fun parseOptions(vararg args: String): ToolOption {
|
||||
val configFile = optionSet.valueOf(configFileArg)
|
||||
RegistrationOption(configFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun OptionSpecBuilder.requireOnlyIf(option: OptionSpecBuilder): OptionSpecBuilder = requiredIf(option).availableIf(option)
|
||||
@ -97,8 +84,6 @@ sealed class ToolOption {
|
||||
val destinationAlias: String?) : ToolOption()
|
||||
}
|
||||
|
||||
class ShowHelpException(val parser: OptionParser, val errorMessage: String? = null) : Exception()
|
||||
|
||||
fun readPassword(fmt: String): String {
|
||||
return if (System.console() != null) {
|
||||
String(System.console().readPassword(fmt))
|
||||
|
@ -27,7 +27,7 @@ class OptionParserTest {
|
||||
|
||||
@Test
|
||||
fun `parse registration args correctly`() {
|
||||
val options = parseOptions("--config-file", "${tempDir / "test.file"}") as ToolOption.RegistrationOption
|
||||
val options = ToolArgsParser().parseOrExit("--config-file", "${tempDir / "test.file"}") as ToolOption.RegistrationOption
|
||||
assertThat(options.configFile).isEqualTo(tempDir / "test.file")
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ class OptionParserTest {
|
||||
"--destkeystore", "${tempDir / "target.jks"}",
|
||||
"--deststorepass", "password2",
|
||||
"--srcalias", "testalias")
|
||||
assertThatThrownBy { parseOptions(*keyCopyArgs, "--config-file", "test.file") }
|
||||
assertThatThrownBy { ToolArgsParser().parseOrExit(*keyCopyArgs, "--config-file", "test.file", printHelpOn = null) }
|
||||
.isInstanceOf(OptionException::class.java)
|
||||
.hasMessageContaining("Option(s) [config-file] are unavailable given other options on the command line")
|
||||
}
|
||||
@ -48,7 +48,7 @@ class OptionParserTest {
|
||||
@Test
|
||||
fun `key copy args should be unavailable in registration mode`() {
|
||||
assertThatThrownBy {
|
||||
parseOptions("--config-file", "${tempDir / "test.file"}", "--srckeystore", "${tempDir / "source.jks"}")
|
||||
ToolArgsParser().parseOrExit("--config-file", "${tempDir / "test.file"}", "--srckeystore", "${tempDir / "source.jks"}", printHelpOn = null)
|
||||
}.isInstanceOf(OptionException::class.java)
|
||||
.hasMessageContaining("Option(s) [srckeystore] are unavailable given other options on the command line")
|
||||
}
|
||||
@ -63,7 +63,7 @@ class OptionParserTest {
|
||||
"--deststorepass", "password2",
|
||||
"--srcalias", "testalias",
|
||||
"--destalias", "testalias2")
|
||||
assertThat(parseOptions(*keyCopyArgs)).isEqualTo(ToolOption.KeyCopierOption(
|
||||
assertThat(ToolArgsParser().parseOrExit(*keyCopyArgs)).isEqualTo(ToolOption.KeyCopierOption(
|
||||
sourceFile = tempDir / "source.jks",
|
||||
destinationFile = tempDir / "target.jks",
|
||||
sourcePassword = "password1",
|
||||
@ -80,7 +80,7 @@ class OptionParserTest {
|
||||
"--srckeystore", "${tempDir / "source.jks"}",
|
||||
"--destkeystore", "${tempDir / "target.jks"}",
|
||||
"--srcalias", "testalias")
|
||||
assertThat(parseOptions(*keyCopyArgs)).isEqualTo(ToolOption.KeyCopierOption(
|
||||
assertThat(ToolArgsParser().parseOrExit(*keyCopyArgs)).isEqualTo(ToolOption.KeyCopierOption(
|
||||
sourceFile = tempDir / "source.jks",
|
||||
destinationFile = tempDir / "target.jks",
|
||||
sourcePassword = null,
|
||||
|
@ -0,0 +1,23 @@
|
||||
package com.r3.corda.networkmanage.common.configuration
|
||||
|
||||
import com.r3.corda.networkmanage.common.utils.ArgsParser
|
||||
import joptsimple.OptionSet
|
||||
import joptsimple.util.PathConverter
|
||||
import joptsimple.util.PathProperties
|
||||
import java.nio.file.Path
|
||||
|
||||
/**
|
||||
* Parses key generator command line options.
|
||||
*/
|
||||
class ConfigFilePathArgsParser : ArgsParser<Path>() {
|
||||
private val configFileArg = optionParser
|
||||
.accepts("config-file", "The path to the config file")
|
||||
.withRequiredArg()
|
||||
.required()
|
||||
.describedAs("filepath")
|
||||
.withValuesConvertedBy(PathConverter(PathProperties.FILE_EXISTING))
|
||||
|
||||
override fun parse(optionSet: OptionSet): Path {
|
||||
return optionSet.valueOf(configFileArg).toAbsolutePath()
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.r3.corda.networkmanage.common.configuration
|
||||
|
||||
import com.r3.corda.networkmanage.common.utils.ShowHelpException
|
||||
import joptsimple.OptionParser
|
||||
import joptsimple.util.PathConverter
|
||||
import joptsimple.util.PathProperties
|
||||
import java.nio.file.Path
|
||||
|
||||
/**
|
||||
* Parses key generator command line options.
|
||||
*/
|
||||
fun parseCommandLine(vararg args: String): Path {
|
||||
val optionParser = OptionParser()
|
||||
val configFileArg = optionParser
|
||||
.accepts("config-file", "The path to the config file")
|
||||
.withRequiredArg()
|
||||
.required()
|
||||
.describedAs("filepath")
|
||||
.withValuesConvertedBy(PathConverter(PathProperties.FILE_EXISTING))
|
||||
val helpOption = optionParser.acceptsAll(listOf("h", "help"), "show help").forHelp()
|
||||
|
||||
val optionSet = optionParser.parse(*args)
|
||||
// Print help and exit on help option or if there are missing options.
|
||||
if (optionSet.has(helpOption) || !optionSet.has(configFileArg)) {
|
||||
throw ShowHelpException(optionParser)
|
||||
}
|
||||
return optionSet.valueOf(configFileArg).toAbsolutePath()
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.r3.corda.networkmanage.common.utils
|
||||
|
||||
import joptsimple.OptionException
|
||||
import joptsimple.OptionParser
|
||||
import joptsimple.OptionSet
|
||||
import java.io.PrintStream
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
// TODO: This class could be useful for the rest of the codebase.
|
||||
abstract class ArgsParser<out T : Any> {
|
||||
protected val optionParser = OptionParser()
|
||||
private val helpOption = optionParser.acceptsAll(listOf("h", "help"), "show help").forHelp()
|
||||
|
||||
/**
|
||||
If [printHelpOn] output stream is not null, this method will print help message and exit process
|
||||
when encountered any error during args parsing, or when help flag is set.
|
||||
*/
|
||||
fun parseOrExit(vararg args: String, printHelpOn: PrintStream? = System.out): T {
|
||||
val optionSet = try {
|
||||
optionParser.parse(*args)
|
||||
} catch (e: OptionException) {
|
||||
printHelpOn?.let {
|
||||
it.println(e.message ?: "Unable to parse arguments.")
|
||||
optionParser.printHelpOn(it)
|
||||
exitProcess(-1)
|
||||
}
|
||||
throw e
|
||||
}
|
||||
if (optionSet.has(helpOption)) {
|
||||
printHelpOn?.let(optionParser::printHelpOn)
|
||||
exitProcess(0)
|
||||
}
|
||||
return parse(optionSet)
|
||||
}
|
||||
|
||||
protected abstract fun parse(optionSet: OptionSet): T
|
||||
}
|
@ -13,9 +13,7 @@ package com.r3.corda.networkmanage.common.utils
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.typesafe.config.ConfigParseOptions
|
||||
import com.typesafe.config.ConfigRenderOptions
|
||||
import joptsimple.OptionParser
|
||||
import net.corda.core.CordaOID
|
||||
import net.corda.core.crypto.sha256
|
||||
import net.corda.core.internal.CertRole
|
||||
import net.corda.core.serialization.internal.SerializationEnvironmentImpl
|
||||
import net.corda.core.serialization.internal.nodeSerializationEnv
|
||||
@ -34,7 +32,6 @@ import org.slf4j.LoggerFactory
|
||||
import java.nio.file.Path
|
||||
import java.security.KeyPair
|
||||
import java.security.PrivateKey
|
||||
import java.security.PublicKey
|
||||
import java.security.cert.CertPath
|
||||
import java.security.cert.X509Certificate
|
||||
|
||||
@ -52,8 +49,6 @@ inline fun <reified T : Any> parseConfig(file: Path): T {
|
||||
return config.parseAs(strict = false)
|
||||
}
|
||||
|
||||
class ShowHelpException(val parser: OptionParser, val errorMessage: String? = null) : Exception()
|
||||
|
||||
fun buildCertPath(certPathBytes: ByteArray): CertPath = X509CertificateFactory().delegate.generateCertPath(certPathBytes.inputStream())
|
||||
|
||||
fun X509KeyStore.getCertPathAndKey(alias: String, privateKeyPassword: String): CertPathAndKey {
|
||||
|
@ -38,8 +38,7 @@ fun parseParameters(configFile: Path?): GeneratorConfiguration {
|
||||
return if (configFile == null) {
|
||||
GeneratorConfiguration()
|
||||
} else {
|
||||
ConfigFactory
|
||||
.parseFile(configFile.toFile(), ConfigParseOptions.defaults().setAllowMissing(true))
|
||||
ConfigFactory.parseFile(configFile.toFile(), ConfigParseOptions.defaults().setAllowMissing(true))
|
||||
.resolve()
|
||||
.parseAs()
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
package com.r3.corda.networkmanage.dev
|
||||
|
||||
import com.r3.corda.networkmanage.common.configuration.parseCommandLine
|
||||
import com.r3.corda.networkmanage.common.configuration.ConfigFilePathArgsParser
|
||||
import com.r3.corda.networkmanage.doorman.CORDA_X500_BASE
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.internal.createDirectories
|
||||
@ -34,7 +34,7 @@ private val logger = LogManager.getLogger("com.r3.corda.networkmanage.dev.Main")
|
||||
* Look for the 'certificates' directory.
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
run(parseParameters(parseCommandLine(*args)))
|
||||
run(parseParameters(ConfigFilePathArgsParser().parseOrExit(*args)))
|
||||
}
|
||||
|
||||
fun run(configuration: GeneratorConfiguration) {
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.r3.corda.networkmanage.doorman
|
||||
|
||||
import com.google.common.primitives.Booleans
|
||||
import com.r3.corda.networkmanage.common.utils.ShowHelpException
|
||||
import com.r3.corda.networkmanage.common.utils.ArgsParser
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.typesafe.config.ConfigParseOptions
|
||||
import joptsimple.OptionParser
|
||||
import joptsimple.OptionSet
|
||||
import joptsimple.util.EnumConverter
|
||||
import joptsimple.util.PathConverter
|
||||
import joptsimple.util.PathProperties
|
||||
@ -14,9 +14,7 @@ import net.corda.nodeapi.internal.config.parseAs
|
||||
import java.nio.file.Path
|
||||
import java.time.Instant
|
||||
|
||||
class DoormanArgsParser {
|
||||
private val optionParser = OptionParser()
|
||||
private val helpOption = optionParser.acceptsAll(listOf("h", "help"), "show help").forHelp()
|
||||
class DoormanArgsParser : ArgsParser<DoormanCmdLineOptions>() {
|
||||
private val configFileArg = optionParser
|
||||
.accepts("config-file", "The path to the config file")
|
||||
.withRequiredArg()
|
||||
@ -37,11 +35,7 @@ class DoormanArgsParser {
|
||||
.accepts("trust-store-password", "Password for the generated network root trust store. Only applicable when operating in ${Mode.ROOT_KEYGEN} mode.")
|
||||
.withRequiredArg()
|
||||
|
||||
fun parse(vararg args: String): DoormanCmdLineOptions {
|
||||
val optionSet = optionParser.parse(*args)
|
||||
if (optionSet.has(helpOption)) {
|
||||
throw ShowHelpException(optionParser)
|
||||
}
|
||||
override fun parse(optionSet: OptionSet): DoormanCmdLineOptions {
|
||||
val configFile = optionSet.valueOf(configFileArg)
|
||||
val mode = optionSet.valueOf(modeArg)
|
||||
val setNetworkParametersFile = optionSet.valueOf(setNetworkParametersArg)
|
||||
|
@ -31,13 +31,7 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
|
||||
initialiseSerialization()
|
||||
val cmdLineOptions = try {
|
||||
DoormanArgsParser().parse(*args)
|
||||
} catch (e: ShowHelpException) {
|
||||
e.errorMessage?.let(::println)
|
||||
e.parser.printHelpOn(System.out)
|
||||
exitProcess(0)
|
||||
}
|
||||
val cmdLineOptions = DoormanArgsParser().parseOrExit(*args)
|
||||
|
||||
val config = parseConfig<NetworkManagementServerConfig>(cmdLineOptions.configFile)
|
||||
|
||||
|
@ -12,7 +12,6 @@ package com.r3.corda.networkmanage.hsm
|
||||
|
||||
import com.jcabi.manifests.Manifests
|
||||
import com.r3.corda.networkmanage.common.persistence.configureDatabase
|
||||
import com.r3.corda.networkmanage.common.utils.ShowHelpException
|
||||
import com.r3.corda.networkmanage.common.utils.initialiseSerialization
|
||||
import com.r3.corda.networkmanage.common.utils.parseConfig
|
||||
import com.r3.corda.networkmanage.hsm.configuration.ManualMode
|
||||
@ -25,7 +24,6 @@ import org.apache.logging.log4j.LogManager
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import java.security.Security
|
||||
import javax.crypto.Cipher
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
private val logger = LogManager.getLogger("com.r3.corda.networkmanage.hsm.Main")
|
||||
|
||||
@ -34,13 +32,7 @@ fun main(args: Array<String>) {
|
||||
println("Signing Service Version: ${Manifests.read("Signing-Service-Version")}")
|
||||
}
|
||||
|
||||
val cmdLineOptions = try {
|
||||
SigningServiceArgsParser().parse(*args)
|
||||
} catch (e: ShowHelpException) {
|
||||
e.errorMessage?.let(::println)
|
||||
e.parser.printHelpOn(System.out)
|
||||
exitProcess(0)
|
||||
}
|
||||
val cmdLineOptions = SigningServiceArgsParser().parseOrExit(*args)
|
||||
|
||||
val config = parseConfig<SigningServiceConfig>(cmdLineOptions.configFile)
|
||||
|
||||
|
@ -11,20 +11,15 @@
|
||||
package com.r3.corda.networkmanage.hsm.configuration
|
||||
|
||||
import com.google.common.primitives.Booleans
|
||||
import com.r3.corda.networkmanage.common.utils.ShowHelpException
|
||||
import com.r3.corda.networkmanage.common.utils.ArgsParser
|
||||
import com.r3.corda.networkmanage.hsm.authentication.AuthMode
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.typesafe.config.ConfigParseOptions
|
||||
import com.typesafe.config.ConfigRenderOptions
|
||||
import joptsimple.OptionParser
|
||||
import joptsimple.OptionSet
|
||||
import joptsimple.util.PathConverter
|
||||
import joptsimple.util.PathProperties
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.nodeapi.internal.config.parseAs
|
||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||
import java.net.InetAddress
|
||||
import java.net.URL
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
@ -61,7 +56,7 @@ data class DoormanCertificateConfig(val crlDistributionPoint: URL,
|
||||
val crlServerSocketAddress: NetworkHostAndPort,
|
||||
val crlUpdatePeriod: Long,
|
||||
val mode: ManualMode,
|
||||
val keyGroup:String,
|
||||
val keyGroup: String,
|
||||
val validDays: Int,
|
||||
val rootKeyStoreFile: Path,
|
||||
val rootKeyStorePassword: String,
|
||||
@ -84,9 +79,7 @@ data class AuthParametersConfig(val mode: AuthMode,
|
||||
val keyFilePath: Path? = null,
|
||||
val threshold: Int)
|
||||
|
||||
class SigningServiceArgsParser {
|
||||
private val optionParser = OptionParser()
|
||||
private val helpOption = optionParser.acceptsAll(listOf("h", "help"), "show help").forHelp()
|
||||
class SigningServiceArgsParser : ArgsParser<SigningServiceCmdLineOptions>() {
|
||||
private val baseDirArg = optionParser
|
||||
.accepts("basedir", "Overriding configuration filepath, default to current directory.")
|
||||
.withRequiredArg()
|
||||
@ -97,11 +90,7 @@ class SigningServiceArgsParser {
|
||||
.withRequiredArg()
|
||||
.withValuesConvertedBy(PathConverter(PathProperties.FILE_EXISTING))
|
||||
|
||||
fun parse(vararg args: String): SigningServiceCmdLineOptions {
|
||||
val optionSet = optionParser.parse(*args)
|
||||
if (optionSet.has(helpOption)) {
|
||||
throw ShowHelpException(optionParser)
|
||||
}
|
||||
override fun parse(optionSet: OptionSet): SigningServiceCmdLineOptions {
|
||||
val baseDir = optionSet.valueOf(baseDirArg)
|
||||
val configFile = optionSet.valueOf(configFileArg) ?: baseDir / "signing_service.conf"
|
||||
return SigningServiceCmdLineOptions(baseDir, configFile)
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
package com.r3.corda.networkmanage.hsm.generator
|
||||
|
||||
import com.r3.corda.networkmanage.common.configuration.parseCommandLine
|
||||
import com.r3.corda.networkmanage.common.configuration.ConfigFilePathArgsParser
|
||||
import com.r3.corda.networkmanage.hsm.authentication.CryptoServerProviderConfig
|
||||
import com.r3.corda.networkmanage.hsm.utils.mapCryptoServerException
|
||||
import net.corda.nodeapi.internal.crypto.CertificateType.ROOT_CA
|
||||
@ -19,7 +19,7 @@ import org.apache.logging.log4j.LogManager
|
||||
private val logger = LogManager.getLogger("com.r3.corda.networkmanage.hsm.generator.Main")
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
run(parseParameters(parseCommandLine(*args)))
|
||||
run(parseParameters(ConfigFilePathArgsParser().parseOrExit(*args)))
|
||||
}
|
||||
|
||||
fun run(parameters: GeneratorParameters) {
|
||||
|
@ -0,0 +1,16 @@
|
||||
package com.r3.corda.networkmanage.tools.crr.submission
|
||||
|
||||
import com.r3.corda.networkmanage.common.utils.ArgsParser
|
||||
import joptsimple.OptionSet
|
||||
import java.net.URL
|
||||
|
||||
class CRRToolArgsParser : ArgsParser<URL>() {
|
||||
private val submissionUrlArg = optionParser
|
||||
.accepts("submission-url", "CRR submission endpoint.")
|
||||
.withRequiredArg()
|
||||
.required()
|
||||
|
||||
override fun parse(optionSet: OptionSet): URL {
|
||||
return URL(optionSet.valueOf(submissionUrlArg))
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.r3.corda.networkmanage.tools.crr.submission
|
||||
|
||||
import com.r3.corda.networkmanage.common.utils.ShowHelpException
|
||||
import joptsimple.OptionParser
|
||||
import java.net.URL
|
||||
|
||||
fun parseSubmissionUrl(vararg args: String): URL {
|
||||
val optionParser = OptionParser()
|
||||
val submissionUrlArg = optionParser
|
||||
.accepts("submission-url", "CRR submission endpoint.")
|
||||
.withRequiredArg()
|
||||
.required()
|
||||
val helpOption = optionParser.acceptsAll(listOf("h", "help"), "show help").forHelp()
|
||||
|
||||
val optionSet = optionParser.parse(*args)
|
||||
// Print help and exit on help option or if there are missing options.
|
||||
if (optionSet.has(helpOption) || !optionSet.has(submissionUrlArg)) {
|
||||
throw ShowHelpException(optionParser)
|
||||
}
|
||||
return URL(optionSet.valueOf(submissionUrlArg))
|
||||
}
|
@ -17,7 +17,7 @@ private val logger = LogManager.getLogger("com.r3.corda.networkmanage.common.too
|
||||
fun main(args: Array<String>) {
|
||||
initialiseSerialization()
|
||||
try {
|
||||
submit(parseSubmissionUrl(*args))
|
||||
submit(CRRToolArgsParser().parseOrExit(*args))
|
||||
} catch (e: Exception) {
|
||||
logger.error("Error when submitting a certificate revocation request.", e)
|
||||
throw e
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
package com.r3.corda.networkmanage.dev
|
||||
|
||||
import com.r3.corda.networkmanage.common.configuration.parseCommandLine
|
||||
import com.r3.corda.networkmanage.common.configuration.ConfigFilePathArgsParser
|
||||
import net.corda.nodeapi.internal.DEV_CA_KEY_STORE_FILE
|
||||
import net.corda.nodeapi.internal.DEV_CA_KEY_STORE_PASS
|
||||
import net.corda.nodeapi.internal.DEV_CA_TRUST_STORE_FILE
|
||||
@ -31,7 +31,7 @@ class GeneratorConfigurationTest {
|
||||
|
||||
@Test
|
||||
fun `config file is parsed correctly`() {
|
||||
val config = parseParameters(parseCommandLine("--config-file", configPath))
|
||||
val config = parseParameters(ConfigFilePathArgsParser().parseOrExit("--config-file", configPath))
|
||||
assertEquals(GeneratorConfiguration.DEFAULT_DIRECTORY, config.directory)
|
||||
assertEquals(DEV_CA_KEY_STORE_FILE, config.keyStoreFileName)
|
||||
assertEquals(DEV_CA_KEY_STORE_PASS, config.keyStorePass)
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
package com.r3.corda.networkmanage.doorman
|
||||
|
||||
import com.r3.corda.networkmanage.common.utils.ShowHelpException
|
||||
import joptsimple.OptionException
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.junit.Test
|
||||
@ -26,39 +25,32 @@ class DoormanArgsParserTest {
|
||||
@Test
|
||||
fun `should fail when network parameters file is missing`() {
|
||||
assertThatThrownBy {
|
||||
argsParser.parse("--config-file", validConfigPath, "--set-network-parameters", "not-here")
|
||||
argsParser.parseOrExit("--config-file", validConfigPath, "--set-network-parameters", "not-here")
|
||||
}.hasMessageContaining("not-here")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should fail when config file is missing`() {
|
||||
assertThatThrownBy {
|
||||
argsParser.parse("--config-file", "not-existing-file")
|
||||
argsParser.parseOrExit("--config-file", "not-existing-file")
|
||||
}.hasMessageContaining("not-existing-file")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should throw ShowHelpException when help option is passed on the command line`() {
|
||||
assertFailsWith<ShowHelpException> {
|
||||
argsParser.parse("-h")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should parse trust store password correctly`() {
|
||||
val parameter = argsParser.parse("--config-file", validConfigPath, "--mode", "ROOT_KEYGEN", "--trust-store-password", "testPassword")
|
||||
val parameter = argsParser.parseOrExit("--config-file", validConfigPath, "--mode", "ROOT_KEYGEN", "--trust-store-password", "testPassword")
|
||||
assertEquals("testPassword", parameter.trustStorePassword)
|
||||
|
||||
assertFailsWith<OptionException> {
|
||||
argsParser.parse("--trust-store-password")
|
||||
argsParser.parseOrExit("--trust-store-password", printHelpOn = null)
|
||||
}
|
||||
|
||||
// Should fail if password is provided in mode other then root keygen.
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
argsParser.parse("--config-file", validConfigPath, "--trust-store-password", "testPassword")
|
||||
argsParser.parseOrExit("--config-file", validConfigPath, "--trust-store-password", "testPassword")
|
||||
}
|
||||
|
||||
// trust store password is optional.
|
||||
assertNull(argsParser.parse("--config-file", validConfigPath).trustStorePassword)
|
||||
assertNull(argsParser.parseOrExit("--config-file", validConfigPath).trustStorePassword)
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ class SigningServiceArgsParserTest : TestBase() {
|
||||
|
||||
@Test
|
||||
fun `doorman-based config file is parsed correctly`() {
|
||||
val cmdLineOptions = argsParser.parse("--config-file", doormanConfigPath)
|
||||
val cmdLineOptions = argsParser.parseOrExit("--config-file", doormanConfigPath)
|
||||
val config = parseConfig<SigningServiceConfig>(cmdLineOptions.configFile)
|
||||
assertEquals("3001@192.168.0.1", config.device)
|
||||
val doormanCertParameters = config.doorman!!
|
||||
@ -37,7 +37,7 @@ class SigningServiceArgsParserTest : TestBase() {
|
||||
|
||||
@Test
|
||||
fun `networkmap-based config file is parsed correctly`() {
|
||||
val cmdLineOptions = argsParser.parse("--config-file", networkMapConfigPath)
|
||||
val cmdLineOptions = argsParser.parseOrExit("--config-file", networkMapConfigPath)
|
||||
val config = parseConfig<SigningServiceConfig>(cmdLineOptions.configFile)
|
||||
assertEquals("3001@192.168.0.1", config.device)
|
||||
val networkMapConfig = config.networkMap!!
|
||||
@ -51,7 +51,7 @@ class SigningServiceArgsParserTest : TestBase() {
|
||||
@Test
|
||||
fun `should fail when config file is missing`() {
|
||||
assertThatThrownBy {
|
||||
argsParser.parse("--config-file", "not-existing-file")
|
||||
argsParser.parseOrExit("--config-file", "not-existing-file")
|
||||
}.hasMessageContaining("not-existing-file")
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,7 @@
|
||||
|
||||
package com.r3.corda.networkmanage.hsm.generator
|
||||
|
||||
import com.r3.corda.networkmanage.common.configuration.parseCommandLine
|
||||
import com.r3.corda.networkmanage.common.utils.ShowHelpException
|
||||
import com.r3.corda.networkmanage.common.configuration.ConfigFilePathArgsParser
|
||||
import com.typesafe.config.ConfigException
|
||||
import joptsimple.OptionException
|
||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||
@ -31,22 +30,15 @@ class GeneratorParametersTest {
|
||||
@Test
|
||||
fun `should fail when config file is missing`() {
|
||||
val message = assertFailsWith<OptionException> {
|
||||
parseCommandLine("--config-file", "not-existing-file")
|
||||
ConfigFilePathArgsParser().parseOrExit("--config-file", "not-existing-file")
|
||||
}.message
|
||||
Assertions.assertThat(message).contains("not-existing-file")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should throw ShowHelpException when help option is passed on the command line`() {
|
||||
assertFailsWith<ShowHelpException> {
|
||||
parseCommandLine("-h")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should fail when config is invalid`() {
|
||||
assertFailsWith<ConfigException.Missing> {
|
||||
parseParameters(parseCommandLine("--config-file", invalidConfigPath))
|
||||
parseParameters(ConfigFilePathArgsParser().parseOrExit("--config-file", invalidConfigPath))
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,6 +63,6 @@ class GeneratorParametersTest {
|
||||
}
|
||||
|
||||
private fun parseCommandLineAndGetParameters(): GeneratorParameters {
|
||||
return parseParameters(parseCommandLine(*validArgs))
|
||||
return parseParameters(ConfigFilePathArgsParser().parseOrExit(*validArgs))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user