Merge pull request #2018 from thschroeter/thomas-raft-notary-bootstrap

CORDA-768: Raft Notary: bootstrap command line flag
This commit is contained in:
Thomas Schroeter 2017-11-14 14:48:34 +00:00 committed by GitHub
commit 8a5bbe7cf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 4 deletions

View File

@ -28,3 +28,6 @@ For ``ValidatingNotaryService``, it is:
Setting up a Raft notary is currently slightly more involved and is not recommended for prototyping purposes. There is Setting up a Raft notary is currently slightly more involved and is not recommended for prototyping purposes. There is
work in progress to simplify it. To see it in action, however, you can try out the :ref:`notary-demo`. work in progress to simplify it. To see it in action, however, you can try out the :ref:`notary-demo`.
Use the `--bootstrap-raft-cluster` command line argument when starting the first node of a notary cluster for the first
time. When the flag is set, the node will act as a seed for the cluster that other members can join.

View File

@ -36,6 +36,7 @@ class ArgsParser {
private val isVersionArg = optionParser.accepts("version", "Print the version and exit") private val isVersionArg = optionParser.accepts("version", "Print the version and exit")
private val justGenerateNodeInfoArg = optionParser.accepts("just-generate-node-info", private val justGenerateNodeInfoArg = optionParser.accepts("just-generate-node-info",
"Perform the node start-up task necessary to generate its nodeInfo, save it to disk, then quit") "Perform the node start-up task necessary to generate its nodeInfo, save it to disk, then quit")
private val bootstrapRaftClusterArg = optionParser.accepts("bootstrap-raft-cluster", "Bootstraps Raft cluster. The node forms a single node cluster (ignoring otherwise configured peer addresses), acting as a seed for other nodes to join the cluster.")
private val helpArg = optionParser.accepts("help").forHelp() private val helpArg = optionParser.accepts("help").forHelp()
fun parse(vararg args: String): CmdLineOptions { fun parse(vararg args: String): CmdLineOptions {
@ -53,8 +54,9 @@ class ArgsParser {
val noLocalShell = optionSet.has(noLocalShellArg) val noLocalShell = optionSet.has(noLocalShellArg)
val sshdServer = optionSet.has(sshdServerArg) val sshdServer = optionSet.has(sshdServerArg)
val justGenerateNodeInfo = optionSet.has(justGenerateNodeInfoArg) val justGenerateNodeInfo = optionSet.has(justGenerateNodeInfoArg)
val bootstrapRaftCluster = optionSet.has(bootstrapRaftClusterArg)
return CmdLineOptions(baseDirectory, configFile, help, loggingLevel, logToConsole, isRegistration, isVersion, return CmdLineOptions(baseDirectory, configFile, help, loggingLevel, logToConsole, isRegistration, isVersion,
noLocalShell, sshdServer, justGenerateNodeInfo) noLocalShell, sshdServer, justGenerateNodeInfo, bootstrapRaftCluster)
} }
fun printHelp(sink: PrintStream) = optionParser.printHelpOn(sink) fun printHelp(sink: PrintStream) = optionParser.printHelpOn(sink)
@ -69,7 +71,8 @@ data class CmdLineOptions(val baseDirectory: Path,
val isVersion: Boolean, val isVersion: Boolean,
val noLocalShell: Boolean, val noLocalShell: Boolean,
val sshdServer: Boolean, val sshdServer: Boolean,
val justGenerateNodeInfo: Boolean) { val justGenerateNodeInfo: Boolean,
val bootstrapRaftCluster: Boolean) {
fun loadConfig(): NodeConfiguration { fun loadConfig(): NodeConfiguration {
val config = ConfigHelper.loadConfig(baseDirectory, configFile).parseAsNodeConfiguration() val config = ConfigHelper.loadConfig(baseDirectory, configFile).parseAsNodeConfiguration()
if (isRegistration) { if (isRegistration) {

View File

@ -8,6 +8,7 @@ import net.corda.core.internal.concurrent.thenMatch
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.node.* import net.corda.node.*
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.NodeConfigurationImpl
import net.corda.node.services.transactions.bftSMaRtSerialFilter import net.corda.node.services.transactions.bftSMaRtSerialFilter
import net.corda.node.shell.InteractiveShell import net.corda.node.shell.InteractiveShell
import net.corda.node.utilities.registration.HTTPNetworkRegistrationService import net.corda.node.utilities.registration.HTTPNetworkRegistrationService
@ -62,7 +63,21 @@ open class NodeStartup(val args: Array<String>) {
drawBanner(versionInfo) drawBanner(versionInfo)
Node.printBasicNodeInfo(LOGS_CAN_BE_FOUND_IN_STRING, System.getProperty("log-path")) Node.printBasicNodeInfo(LOGS_CAN_BE_FOUND_IN_STRING, System.getProperty("log-path"))
val conf = loadConfigFile(cmdlineOptions) val conf0 = loadConfigFile(cmdlineOptions)
val conf = if (cmdlineOptions.bootstrapRaftCluster) {
if (conf0 is NodeConfigurationImpl) {
println("Bootstrapping raft cluster (starting up as seed node).")
// Ignore the configured clusterAddresses to make the node bootstrap a cluster instead of joining.
conf0.copy(notary = conf0.notary?.copy(raft = conf0.notary?.raft?.copy(clusterAddresses = emptyList())))
} else {
println("bootstrap-raft-notaries flag not recognized, exiting...")
exitProcess(1)
}
} else {
conf0
}
banJavaSerialisation(conf) banJavaSerialisation(conf)
preNetworkRegistration(conf) preNetworkRegistration(conf)
maybeRegisterWithNetworkAndExit(cmdlineOptions, conf) maybeRegisterWithNetworkAndExit(cmdlineOptions, conf)

View File

@ -24,7 +24,8 @@ class ArgsParserTest {
isVersion = false, isVersion = false,
noLocalShell = false, noLocalShell = false,
sshdServer = false, sshdServer = false,
justGenerateNodeInfo = false)) justGenerateNodeInfo = false,
bootstrapRaftCluster = false))
} }
@Test @Test
@ -124,4 +125,10 @@ class ArgsParserTest {
val cmdLineOptions = parser.parse("--just-generate-node-info") val cmdLineOptions = parser.parse("--just-generate-node-info")
assertThat(cmdLineOptions.justGenerateNodeInfo).isTrue() assertThat(cmdLineOptions.justGenerateNodeInfo).isTrue()
} }
@Test
fun `bootstrap raft cluster`() {
val cmdLineOptions = parser.parse("--bootstrap-raft-cluster")
assertThat(cmdLineOptions.bootstrapRaftCluster).isTrue()
}
} }