Removed basedir from the config file as it's always overwritten by the --base-directory cmd line arg

This commit is contained in:
Shams Asari
2017-01-06 19:38:48 +00:00
parent d87c9eb9d2
commit 7cd281364f
39 changed files with 260 additions and 208 deletions

View File

@ -52,7 +52,7 @@ class P2PSecurityTest : NodeBasedTest() {
private fun startSimpleNode(legalName: String): SimpleNode {
val config = TestNodeConfiguration(
basedir = tempFolder.root.toPath() / legalName,
baseDirectory = tempFolder.root.toPath() / legalName,
myLegalName = legalName,
networkMapService = NetworkMapInfo(networkMapNode.configuration.artemisAddress, networkMapNode.info.legalIdentity.name))
config.configureWithDevSSLCertificate() // This creates the node's TLS cert with the CN as the legal name

View File

@ -0,0 +1,43 @@
package net.corda.node
import com.typesafe.config.Config
import joptsimple.OptionParser
import net.corda.core.div
import net.corda.node.services.config.ConfigHelper
import java.io.PrintStream
import java.nio.file.Path
import java.nio.file.Paths
class ArgsParser {
private val optionParser = OptionParser()
// The intent of allowing a command line configurable directory and config path is to allow deployment flexibility.
// Other general configuration should live inside the config file unless we regularly need temporary overrides on the command line
private val baseDirectoryArg = optionParser
.accepts("base-directory", "The node working directory where all the files are kept")
.withRequiredArg()
.defaultsTo(".")
private val configFileArg = optionParser
.accepts("config-file", "The path to the config file")
.withRequiredArg()
.defaultsTo("node.conf")
private val logToConsoleArg = optionParser.accepts("log-to-console", "If set, prints logging to the console as well as to a file.")
private val helpArg = optionParser.accepts("help").forHelp()
fun parse(vararg args: String): CmdLineOptions {
val optionSet = optionParser.parse(*args)
require(!optionSet.has(baseDirectoryArg) || !optionSet.has(configFileArg)) {
"${baseDirectoryArg.options()[0]} and ${configFileArg.options()[0]} cannot be specified together"
}
val baseDirectory = Paths.get(optionSet.valueOf(baseDirectoryArg)).normalize().toAbsolutePath()
val configFile = baseDirectory / optionSet.valueOf(configFileArg)
return CmdLineOptions(baseDirectory, configFile, optionSet.has(helpArg), optionSet.has(logToConsoleArg))
}
fun printHelp(sink: PrintStream) = optionParser.printHelpOn(sink)
}
data class CmdLineOptions(val baseDirectory: Path, val configFile: Path?, val help: Boolean, val logToConsole: Boolean) {
fun loadConfig(allowMissingConfig: Boolean = false, configOverrides: Map<String, Any?> = emptyMap()): Config {
return ConfigHelper.loadConfig(baseDirectory, configFile, allowMissingConfig, configOverrides)
}
}

View File

@ -1,11 +1,9 @@
package net.corda.node
import com.typesafe.config.ConfigException
import joptsimple.OptionParser
import net.corda.core.*
import net.corda.core.utilities.Emoji
import net.corda.node.internal.Node
import net.corda.node.services.config.ConfigHelper
import net.corda.node.services.config.FullNodeConfiguration
import net.corda.node.utilities.ANSIProgressObserver
import org.fusesource.jansi.Ansi
@ -14,7 +12,6 @@ import org.slf4j.LoggerFactory
import java.lang.management.ManagementFactory
import java.net.InetAddress
import java.nio.file.Paths
import java.time.LocalDate
import kotlin.system.exitProcess
private var renderBasicInfoToConsole = true
@ -31,33 +28,26 @@ fun printBasicNodeInfo(description: String, info: String? = null) {
}
fun main(args: Array<String>) {
val startTime = System.currentTimeMillis()
checkJavaVersion()
val startTime = System.currentTimeMillis()
val parser = OptionParser()
// The intent of allowing a command line configurable directory and config path is to allow deployment flexibility.
// Other general configuration should live inside the config file unless we regularly need temporary overrides on the command line
val baseDirectoryArg = parser.accepts("base-directory", "The directory to put all files under").withOptionalArg()
val configFileArg = parser.accepts("config-file", "The path to the config file").withOptionalArg()
val logToConsoleArg = parser.accepts("log-to-console", "If set, prints logging to the console as well as to a file.")
val helpArg = parser.accepts("help").forHelp()
val argsParser = ArgsParser()
val cmdlineOptions = try {
parser.parse(*args)
argsParser.parse(*args)
} catch (ex: Exception) {
println("Unknown command line arguments: ${ex.message}")
exitProcess(1)
}
// Maybe render command line help.
if (cmdlineOptions.has(helpArg)) {
parser.printHelpOn(System.out)
if (cmdlineOptions.help) {
argsParser.printHelp(System.out)
exitProcess(0)
}
// Set up logging.
if (cmdlineOptions.has(logToConsoleArg)) {
if (cmdlineOptions.logToConsole) {
// This property is referenced from the XML config file.
System.setProperty("consoleLogLevel", "info")
renderBasicInfoToConsole = false
@ -65,19 +55,17 @@ fun main(args: Array<String>) {
drawBanner()
val baseDirectoryPath = if (cmdlineOptions.has(baseDirectoryArg)) Paths.get(cmdlineOptions.valueOf(baseDirectoryArg)) else Paths.get(".").normalize()
System.setProperty("log-path", (baseDirectoryPath / "logs").toAbsolutePath().toString())
System.setProperty("log-path", (cmdlineOptions.baseDirectory / "logs").toString())
val log = LoggerFactory.getLogger("Main")
printBasicNodeInfo("Logs can be found in", System.getProperty("log-path"))
val configFile = if (cmdlineOptions.has(configFileArg)) Paths.get(cmdlineOptions.valueOf(configFileArg)) else null
val conf = try {
FullNodeConfiguration(ConfigHelper.loadConfig(baseDirectoryPath, configFile))
FullNodeConfiguration(cmdlineOptions.baseDirectory, cmdlineOptions.loadConfig())
} catch (e: ConfigException) {
println("Unable to load the configuration file: ${e.rootCause.message}")
exitProcess(2)
}
val dir = conf.basedir.toAbsolutePath().normalize()
log.info("Main class: ${FullNodeConfiguration::class.java.protectionDomain.codeSource.location.toURI().path}")
val info = ManagementFactory.getRuntimeMXBean()
@ -87,13 +75,12 @@ fun main(args: Array<String>) {
log.info("classpath: ${info.classPath}")
log.info("VM ${info.vmName} ${info.vmVendor} ${info.vmVersion}")
log.info("Machine: ${InetAddress.getLocalHost().hostName}")
log.info("Working Directory: $dir")
log.info("Working Directory: ${cmdlineOptions.baseDirectory}")
try {
dir.createDirectories()
cmdlineOptions.baseDirectory.createDirectories()
val node = conf.createNode()
node.start()
printPluginsAndServices(node)
@ -121,8 +108,8 @@ private fun checkJavaVersion() {
Paths.get("").normalize()
} catch (e: ArrayIndexOutOfBoundsException) {
println("""
You are using a version of Java that is not supported (${System.getProperty("java.version")}). Please upgrade to the latest version.
Corda will now exit...""")
You are using a version of Java that is not supported (${System.getProperty("java.version")}). Please upgrade to the latest version.
Corda will now exit...""")
exitProcess(1)
}
}
@ -138,13 +125,6 @@ private fun printPluginsAndServices(node: Node) {
}
private fun messageOfTheDay(): Pair<String, String> {
// TODO: Remove this next year.
val today = LocalDate.now()
if (today.isAfter(LocalDate.of(2016, 12, 20)) && today.isBefore(LocalDate.of(2017, 1, 3))) {
val claus = if (Emoji.hasEmojiTerminal) Emoji.santaClaus else ""
return Pair("The Corda team wishes you a very merry", "christmas and a happy new year! $claus")
}
val messages = arrayListOf(
"The only distributed ledger that pays\nhomage to Pac Man in its logo.",
"You know, I was a banker once ...\nbut I lost interest. ${Emoji.bagOfCash}",
@ -153,7 +133,6 @@ private fun messageOfTheDay(): Pair<String, String> {
"\"It's OK computer, I go to sleep after\ntwenty minutes of inactivity too!\"",
"It's kind of like a block chain but\ncords sounded healthier than chains.",
"Computer science and finance together.\nYou should see our crazy Christmas parties!"
)
if (Emoji.hasEmojiTerminal)
messages +=
@ -177,5 +156,3 @@ private fun drawBanner() {
"""\____/ /_/ \__,_/\__,_/""").reset().newline().newline().fgBrightDefault().bold().
a("--- DEVELOPER SNAPSHOT ------------------------------------------------------------").newline().reset())
}

View File

@ -155,7 +155,7 @@ fun <A> driver(
driverDsl = DriverDSL(
portAllocation = portAllocation,
debugPortAllocation = debugPortAllocation,
driverDirectory = driverDirectory,
driverDirectory = driverDirectory.toAbsolutePath(),
useTestClock = useTestClock,
isDebug = isDebug
),
@ -349,7 +349,6 @@ open class DriverDSL(
val baseDirectory = driverDirectory / name
val configOverrides = mapOf(
"myLegalName" to name,
"basedir" to baseDirectory.normalize().toString(),
"artemisAddress" to messagingAddress.toString(),
"webAddress" to apiAddress.toString(),
"extraAdvertisedServiceIds" to advertisedServices.joinToString(","),
@ -367,11 +366,14 @@ open class DriverDSL(
}
) + customOverrides
val configuration = FullNodeConfiguration(ConfigHelper.loadConfig(
baseDirectoryPath = baseDirectory,
allowMissingConfig = true,
configOverrides = configOverrides
))
val configuration = FullNodeConfiguration(
baseDirectory,
ConfigHelper.loadConfig(
baseDirectory = baseDirectory,
allowMissingConfig = true,
configOverrides = configOverrides
)
)
val startNode = startNode(executorService, configuration, quasarJarPath, debugPort)
registerProcess(startNode)
@ -421,11 +423,10 @@ open class DriverDSL(
val baseDirectory = driverDirectory / networkMapLegalName
val config = ConfigHelper.loadConfig(
baseDirectoryPath = baseDirectory,
baseDirectory = baseDirectory,
allowMissingConfig = true,
configOverrides = mapOf(
"myLegalName" to networkMapLegalName,
"basedir" to baseDirectory.normalize().toString(),
"artemisAddress" to networkMapAddress.toString(),
"webAddress" to apiAddress.toString(),
"extraAdvertisedServiceIds" to "",
@ -434,7 +435,7 @@ open class DriverDSL(
)
log.info("Starting network-map-service")
val startNode = startNode(executorService, FullNodeConfiguration(config), quasarJarPath, debugPort)
val startNode = startNode(executorService, FullNodeConfiguration(baseDirectory, config), quasarJarPath, debugPort)
registerProcess(startNode)
return startNode
}
@ -456,7 +457,7 @@ open class DriverDSL(
debugPort: Int?
): ListenableFuture<Process> {
// Write node.conf
writeConfig(nodeConf.basedir, "node.conf", nodeConf.config)
writeConfig(nodeConf.baseDirectory, "node.conf", nodeConf.config)
val className = "net.corda.node.MainKt" // cannot directly get class for this, so just use string
val separator = System.getProperty("file.separator")
@ -471,11 +472,11 @@ open class DriverDSL(
val javaArgs = listOf(path) +
listOf("-Dname=${nodeConf.myLegalName}", "-javaagent:$quasarJarPath") + debugPortArg +
listOf("-cp", classpath, className) +
"--base-directory=${nodeConf.basedir}"
"--base-directory=${nodeConf.baseDirectory}"
val builder = ProcessBuilder(javaArgs)
builder.redirectError(Paths.get("error.$className.log").toFile())
builder.inheritIO()
builder.directory(nodeConf.basedir.toFile())
builder.directory(nodeConf.baseDirectory.toFile())
val process = builder.start()
return Futures.allAsList(
addressMustBeBound(executorService, nodeConf.artemisAddress),

View File

@ -203,7 +203,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
// Do all of this in a database transaction so anything that might need a connection has one.
initialiseDatabasePersistence {
val storageServices = initialiseStorageService(configuration.basedir)
val storageServices = initialiseStorageService(configuration.baseDirectory)
storage = storageServices.first
checkpointStorage = storageServices.second
netMapCache = InMemoryNetworkMapCache()
@ -285,7 +285,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
return advertisedServices.map {
val serviceId = it.type.id
val serviceName = it.name ?: "$serviceId|${configuration.myLegalName}"
val identity = obtainKeyPair(configuration.basedir, serviceId + "-private-key", serviceId + "-public", serviceName).first
val identity = obtainKeyPair(configuration.baseDirectory, serviceId + "-private-key", serviceId + "-public", serviceName).first
ServiceEntry(it, identity)
}
}
@ -495,8 +495,8 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage) =
StorageServiceImpl(attachments, transactionStorage, stateMachineRecordedTransactionMappingStorage)
protected fun obtainLegalIdentity(): Party = obtainKeyPair(configuration.basedir, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME).first
protected fun obtainLegalIdentityKey(): KeyPair = obtainKeyPair(configuration.basedir, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME).second
protected fun obtainLegalIdentity(): Party = obtainKeyPair(configuration.baseDirectory, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME).first
protected fun obtainLegalIdentityKey(): KeyPair = obtainKeyPair(configuration.baseDirectory, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME).second
private fun obtainKeyPair(dir: Path, privateKeyFileName: String, publicKeyFileName: String, serviceName: String? = null): Pair<Party, KeyPair> {
// Load the private identity key, creating it if necessary. The identity key is a long term well known key that
@ -545,6 +545,6 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
}
protected fun createNodeDir() {
configuration.basedir.createDirectories()
configuration.baseDirectory.createDirectories()
}
}

View File

@ -270,7 +270,7 @@ class Node(override val configuration: FullNodeConfiguration,
override fun makeUniquenessProvider(type: ServiceType): UniquenessProvider {
return when (type) {
RaftValidatingNotaryService.type -> with(configuration) {
RaftUniquenessProvider(basedir, notaryNodeAddress!!, notaryClusterAddresses, database, configuration)
RaftUniquenessProvider(baseDirectory, notaryNodeAddress!!, notaryClusterAddresses, database, configuration)
}
else -> PersistentUniquenessProvider()
}
@ -393,7 +393,7 @@ class Node(override val configuration: FullNodeConfiguration,
// file that we'll do our best to delete on exit. But if we don't, it'll be overwritten next time. If it already
// exists, we try to take the file lock first before replacing it and if that fails it means we're being started
// twice with the same directory: that's a user error and we should bail out.
val pidPath = configuration.basedir / "process-id"
val pidPath = configuration.baseDirectory / "process-id"
val file = pidPath.toFile()
if (!file.exists()) {
file.createNewFile()
@ -402,7 +402,7 @@ class Node(override val configuration: FullNodeConfiguration,
val f = RandomAccessFile(file, "rw")
val l = f.channel.tryLock()
if (l == null) {
log.error("It appears there is already a node running with the specified data directory ${configuration.basedir}")
log.error("It appears there is already a node running with the specified data directory ${configuration.baseDirectory}")
log.error("Shut that other node down and try again. It may have process ID ${file.readText()}")
System.exit(1)
}

View File

@ -25,27 +25,28 @@ import kotlin.reflect.KProperty
import kotlin.reflect.jvm.javaType
object ConfigHelper {
val log = loggerFor<ConfigHelper>()
private val log = loggerFor<ConfigHelper>()
fun loadConfig(baseDirectoryPath: Path,
fun loadConfig(baseDirectory: Path,
configFileOverride: Path? = null,
allowMissingConfig: Boolean = false,
configOverrides: Map<String, Any?> = emptyMap()): Config {
val defaultConfig = ConfigFactory.parseResources("reference.conf", ConfigParseOptions.defaults().setAllowMissing(false))
val normalisedBaseDir = baseDirectoryPath.normalize()
val configFile = (configFileOverride?.normalize() ?: normalisedBaseDir / "node.conf").toFile()
val appConfig = ConfigFactory.parseFile(configFile, ConfigParseOptions.defaults().setAllowMissing(allowMissingConfig))
val configFile = configFileOverride ?: baseDirectory / "node.conf"
val appConfig = ConfigFactory.parseFile(configFile.toFile(), ConfigParseOptions.defaults().setAllowMissing(allowMissingConfig))
val overridesMap = HashMap<String, Any?>() // If we do require a few other command line overrides eg for a nicer development experience they would go inside this map.
overridesMap.putAll(configOverrides)
overridesMap["basedir"] = normalisedBaseDir.toAbsolutePath().toString()
val overrideConfig = ConfigFactory.parseMap(overridesMap)
val overrideConfig = ConfigFactory.parseMap(configOverrides + mapOf(
// Add substitution values here
"basedir" to baseDirectory.toString())
)
val mergedAndResolvedConfig = overrideConfig.withFallback(appConfig).withFallback(defaultConfig).resolve()
log.info("Config:\n ${mergedAndResolvedConfig.root().render(ConfigRenderOptions.defaults())}")
return mergedAndResolvedConfig
val finalConfig = overrideConfig
.withFallback(appConfig)
.withFallback(defaultConfig)
.resolve()
log.info("Config:\n${finalConfig.root().render(ConfigRenderOptions.defaults())}")
return finalConfig
}
}
@ -74,12 +75,9 @@ class OptionalConfig<out T>(val conf: Config, val lambda: () -> T) {
operator fun getValue(receiver: Any, metadata: KProperty<*>): T {
return if (conf.hasPath(metadata.name)) conf.getValue(receiver, metadata) else lambda()
}
}
fun <T> Config.getOrElse(lambda: () -> T): OptionalConfig<T> {
return OptionalConfig(this, lambda)
}
fun <T> Config.getOrElse(lambda: () -> T): OptionalConfig<T> = OptionalConfig(this, lambda)
fun Config.getProperties(path: String): Properties {
val obj = this.getObject(path)
@ -106,7 +104,7 @@ inline fun <reified T : Any> Config.getListOrElse(path: String, default: Config.
fun NodeConfiguration.configureWithDevSSLCertificate() = configureDevKeyAndTrustStores(myLegalName)
private fun NodeSSLConfiguration.configureDevKeyAndTrustStores(myLegalName: String) {
certificatesPath.createDirectories()
certificatesDirectory.createDirectories()
if (!trustStorePath.exists()) {
javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordatruststore.jks").copyTo(trustStorePath)
}
@ -121,7 +119,7 @@ private fun NodeSSLConfiguration.configureDevKeyAndTrustStores(myLegalName: Stri
// TODO Move this to CoreTestUtils.kt once we can pry this from the explorer
@JvmOverloads
fun configureTestSSL(legalName: String = "Mega Corp."): NodeSSLConfiguration = object : NodeSSLConfiguration {
override val certificatesPath = Files.createTempDirectory("certs")
override val certificatesDirectory = Files.createTempDirectory("certs")
override val keyStorePassword: String get() = "cordacadevpass"
override val trustStorePassword: String get() = "trustpass"

View File

@ -13,17 +13,20 @@ import net.corda.node.utilities.TestClock
import java.nio.file.Path
import java.util.*
// TODO Rename this to SSLConfiguration as it's also used by non-node components
interface NodeSSLConfiguration {
val keyStorePassword: String
val trustStorePassword: String
val certificatesPath: Path
val keyStorePath: Path get() = certificatesPath / "sslkeystore.jks"
val trustStorePath: Path get() = certificatesPath / "truststore.jks"
val certificatesDirectory: Path
// TODO Rename to keyStoreFile
val keyStorePath: Path get() = certificatesDirectory / "sslkeystore.jks"
// TODO Rename to trustStoreFile
val trustStorePath: Path get() = certificatesDirectory / "truststore.jks"
}
interface NodeConfiguration : NodeSSLConfiguration {
val basedir: Path
override val certificatesPath: Path get() = basedir / "certificates"
val baseDirectory: Path
override val certificatesDirectory: Path get() = baseDirectory / "certificates"
val myLegalName: String
val networkMapService: NetworkMapInfo?
val nearestCity: String
@ -34,8 +37,10 @@ interface NodeConfiguration : NodeSSLConfiguration {
val devMode: Boolean
}
class FullNodeConfiguration(val config: Config) : NodeConfiguration {
override val basedir: Path by config
/**
* [baseDirectory] is not retrieved from the config file but rather from a command line argument.
*/
class FullNodeConfiguration(override val baseDirectory: Path, val config: Config) : NodeConfiguration {
override val myLegalName: String by config
override val nearestCity: String by config
override val emailAddress: String by config

View File

@ -103,7 +103,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
private var networkChangeHandle: Subscription? = null
init {
config.basedir.expectedOnDefaultFileSystem()
config.baseDirectory.expectedOnDefaultFileSystem()
}
/**
@ -143,7 +143,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
}
private fun createArtemisConfig(): Configuration = ConfigurationImpl().apply {
val artemisDir = config.basedir / "artemis"
val artemisDir = config.baseDirectory / "artemis"
bindingsDirectory = (artemisDir / "bindings").toString()
journalDirectory = (artemisDir / "journal").toString()
largeMessagesDirectory = (artemisDir / "large-messages").toString()

View File

@ -1,6 +1,5 @@
package net.corda.node.utilities.certsigning
import joptsimple.OptionParser
import net.corda.core.*
import net.corda.core.crypto.X509Utilities
import net.corda.core.crypto.X509Utilities.CORDA_CLIENT_CA
@ -9,12 +8,12 @@ import net.corda.core.crypto.X509Utilities.CORDA_ROOT_CA
import net.corda.core.crypto.X509Utilities.addOrReplaceCertificate
import net.corda.core.crypto.X509Utilities.addOrReplaceKey
import net.corda.core.utilities.loggerFor
import net.corda.node.services.config.ConfigHelper
import net.corda.node.ArgsParser
import net.corda.node.services.config.FullNodeConfiguration
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.getValue
import net.corda.node.utilities.certsigning.CertificateSigner.Companion.log
import java.net.URL
import java.nio.file.Paths
import java.security.KeyPair
import java.security.cert.Certificate
import kotlin.system.exitProcess
@ -32,7 +31,7 @@ class CertificateSigner(val config: NodeConfiguration, val certService: Certific
}
fun buildKeyStore() {
config.certificatesPath.createDirectories()
config.certificatesDirectory.createDirectories()
val caKeyStore = X509Utilities.loadOrCreateKeyStore(config.keyStorePath, config.keyStorePassword)
@ -97,7 +96,7 @@ class CertificateSigner(val config: NodeConfiguration, val certService: Certific
* @return Request ID return from the server.
*/
private fun submitCertificateSigningRequest(keyPair: KeyPair): String {
val requestIdStore = config.certificatesPath / "certificate-request-id.txt"
val requestIdStore = config.certificatesDirectory / "certificate-request-id.txt"
// Retrieve request id from file if exists, else post a request to server.
return if (!requestIdStore.exists()) {
val request = X509Utilities.createCertificateSigningRequest(config.myLegalName, config.nearestCity, config.emailAddress, keyPair)
@ -112,30 +111,21 @@ class CertificateSigner(val config: NodeConfiguration, val certService: Certific
}
}
object ParamsSpec {
val parser = OptionParser()
val baseDirectoryArg = parser.accepts("base-dir", "Working directory of Corda Node.").withRequiredArg().defaultsTo(".")
val configFileArg = parser.accepts("config-file", "The path to the config file.").withRequiredArg()
}
fun main(args: Array<String>) {
val argsParser = ArgsParser()
val cmdlineOptions = try {
ParamsSpec.parser.parse(*args)
argsParser.parse(*args)
} catch (ex: Exception) {
CertificateSigner.log.error("Unable to parse args", ex)
ParamsSpec.parser.printHelpOn(System.out)
log.error("Unable to parse args", ex)
argsParser.printHelp(System.out)
exitProcess(1)
}
val baseDirectoryPath = Paths.get(cmdlineOptions.valueOf(ParamsSpec.baseDirectoryArg))
val configFile = if (cmdlineOptions.has(ParamsSpec.configFileArg)) Paths.get(cmdlineOptions.valueOf(ParamsSpec.configFileArg)) else null
val config = ConfigHelper.loadConfig(baseDirectoryPath, configFile, allowMissingConfig = true).let { config ->
object : NodeConfiguration by FullNodeConfiguration(config) {
val certificateSigningService: URL by config
}
val config = cmdlineOptions.loadConfig(allowMissingConfig = true)
val configuration = object : NodeConfiguration by FullNodeConfiguration(cmdlineOptions.baseDirectory, config) {
val certificateSigningService: URL by config
}
// TODO: Use HTTPS instead
CertificateSigner(config, HTTPCertificateSigningService(config.certificateSigningService)).buildKeyStore()
CertificateSigner(configuration, HTTPCertificateSigningService(configuration.certificateSigningService)).buildKeyStore()
}

View File

@ -0,0 +1,86 @@
package net.corda.node
import joptsimple.OptionException
import net.corda.core.div
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Test
import java.nio.file.Paths
class ArgsParserTest {
private val parser = ArgsParser()
private val workingDirectory = Paths.get(".").normalize().toAbsolutePath()
@Test
fun `no command line arguments`() {
assertThat(parser.parse()).isEqualTo(CmdLineOptions(
baseDirectory = workingDirectory,
configFile = workingDirectory / "node.conf",
help = false,
logToConsole = false))
}
@Test
fun `just base-directory with relative path`() {
val expectedBaseDir = Paths.get("tmp").normalize().toAbsolutePath()
val cmdLineOptions = parser.parse("--base-directory", "tmp")
assertThat(cmdLineOptions).isEqualTo(CmdLineOptions(
baseDirectory = expectedBaseDir,
configFile = expectedBaseDir / "node.conf",
help = false,
logToConsole = false))
}
@Test
fun `just base-directory with absolute path`() {
val baseDirectory = Paths.get("tmp").normalize().toAbsolutePath()
val cmdLineOptions = parser.parse("--base-directory", baseDirectory.toString())
assertThat(cmdLineOptions).isEqualTo(CmdLineOptions(
baseDirectory = baseDirectory,
configFile = baseDirectory / "node.conf",
help = false,
logToConsole = false))
}
@Test
fun `just config-file with relative path`() {
val cmdLineOptions = parser.parse("--config-file", "different.conf")
assertThat(cmdLineOptions).isEqualTo(CmdLineOptions(
baseDirectory = workingDirectory,
configFile = workingDirectory / "different.conf",
help = false,
logToConsole = false))
}
@Test
fun `just config-file with absolute path`() {
val configFile = Paths.get("tmp", "a.conf").normalize().toAbsolutePath()
val cmdLineOptions = parser.parse("--config-file", configFile.toString())
assertThat(cmdLineOptions).isEqualTo(CmdLineOptions(
baseDirectory = workingDirectory,
configFile = configFile,
help = false,
logToConsole = false))
}
@Test
fun `both base-directory and config-file`() {
assertThatExceptionOfType(IllegalArgumentException::class.java).isThrownBy {
parser.parse("--base-directory", "base", "--config-file", "conf")
}.withMessageContaining("base-directory").withMessageContaining("config-file")
}
@Test
fun `base-directory without argument`() {
assertThatExceptionOfType(OptionException::class.java).isThrownBy {
parser.parse("--base-directory")
}.withMessageContaining("base-directory")
}
@Test
fun `config-file without argument`() {
assertThatExceptionOfType(OptionException::class.java).isThrownBy {
parser.parse("--config-file")
}.withMessageContaining("config-file")
}
}

View File

@ -5,6 +5,7 @@ import net.corda.node.services.config.FullNodeConfiguration
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test
import java.nio.file.Paths
class RPCUserServiceImplTest {
@ -69,6 +70,6 @@ class RPCUserServiceImplTest {
}
private fun loadWithContents(configString: String): RPCUserServiceImpl {
return RPCUserServiceImpl(FullNodeConfiguration(ConfigFactory.parseString(configString)))
return RPCUserServiceImpl(FullNodeConfiguration(Paths.get("."), ConfigFactory.parseString(configString)))
}
}

View File

@ -4,7 +4,7 @@ import com.google.common.net.HostAndPort
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.SettableFuture
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigFactory.empty
import net.corda.core.crypto.composite
import net.corda.core.crypto.generateKeyPair
import net.corda.core.messaging.Message
@ -67,9 +67,10 @@ class ArtemisMessagingTests {
@Before
fun setUp() {
userService = RPCUserServiceImpl(FullNodeConfiguration(ConfigFactory.empty()))
val baseDirectory = temporaryFolder.root.toPath()
userService = RPCUserServiceImpl(FullNodeConfiguration(baseDirectory, empty()))
config = TestNodeConfiguration(
basedir = temporaryFolder.newFolder().toPath(),
baseDirectory = baseDirectory,
myLegalName = "me",
networkMapService = null)
LogHelper.setLevel(PersistentUniquenessProvider::class)

View File

@ -35,7 +35,7 @@ class CertificateSignerTest {
}
val config = TestNodeConfiguration(
basedir = tempFolder.root.toPath(),
baseDirectory = tempFolder.root.toPath(),
myLegalName = "me",
networkMapService = null)
@ -65,6 +65,6 @@ class CertificateSignerTest {
assertFalse(containsAlias(X509Utilities.CORDA_ROOT_CA_PRIVATE_KEY))
}
assertEquals(id, (config.certificatesPath / "certificate-request-id.txt").readLines { it.findFirst().get() })
assertEquals(id, (config.certificatesDirectory / "certificate-request-id.txt").readLines { it.findFirst().get() })
}
}