CORDA-1979 Cleanup NodeStartup for better readability ()

This commit is contained in:
Konstantinos Chalkias 2018-09-15 23:17:10 +01:00 committed by GitHub
parent 7e4c5d4bb0
commit 0b2e0b04ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -67,64 +67,87 @@ open class NodeStartup: CordaCliWrapper("corda", "Runs a Corda Node") {
*/
override fun runProgram(): Int {
val startTime = System.currentTimeMillis()
if (!canNormalizeEmptyPath()) {
println("You are using a version of Java that is not supported (${System.getProperty("java.version")}). Please upgrade to the latest supported version.")
println("Corda will now exit...")
return ExitCodes.FAILURE
}
// Step 1. Check for supported Java version.
if (!isValidJavaVersion()) return ExitCodes.FAILURE
val registrationMode = checkRegistrationMode()
// TODO: Reconsider if automatic re-registration should be applied when something failed during initial registration.
// There might be cases where the node user should investigate what went wrong before registering again.
if (registrationMode && !cmdLineOptions.isRegistration) {
println("Node was started before with `--initial-registration`, but the registration was not completed.\nResuming registration.")
// Pretend that the node was started with `--initial-registration` to help prevent user error.
cmdLineOptions.isRegistration = true
}
// We do the single node check before we initialise logging so that in case of a double-node start it
// Step 2. We do the single node check before we initialise logging so that in case of a double-node start it
// doesn't mess with the running node's logs.
enforceSingleNodeIsRunning(cmdLineOptions.baseDirectory)
// Step 3. Initialise logging.
initLogging()
// Register all cryptography [Provider]s.
// Step 4. Register all cryptography [Provider]s.
// Required to install our [SecureRandom] before e.g., UUID asks for one.
// This needs to go after initLogging(netty clashes with our logging).
Crypto.registerProviders()
// Step 5. Print banner and basic node info.
val versionInfo = getVersionInfo()
drawBanner(versionInfo)
Node.printBasicNodeInfo(LOGS_CAN_BE_FOUND_IN_STRING, System.getProperty("log-path"))
// Step 6. Load and validate node configuration.
val configuration = (attempt { loadConfiguration() }.doOnException(handleConfigurationLoadingError(cmdLineOptions.configFile)) as? Try.Success)?.let(Try.Success<NodeConfiguration>::value) ?: return ExitCodes.FAILURE
val errors = configuration.validate()
if (errors.isNotEmpty()) {
logger.error("Invalid node configuration. Errors were:${System.lineSeparator()}${errors.joinToString(System.lineSeparator())}")
return ExitCodes.FAILURE
}
// Step 7. Configuring special serialisation requirements, i.e., bft-smart relies on Java serialization.
attempt { banJavaSerialisation(configuration) }.doOnException { error -> error.logAsUnexpected("Exception while configuring serialisation") } as? Try.Success ?: return ExitCodes.FAILURE
// Step 8. Any actions required before starting up the Corda network layer.
attempt { preNetworkRegistration(configuration) }.doOnException(handleRegistrationError) as? Try.Success ?: return ExitCodes.FAILURE
cmdLineOptions.nodeRegistrationOption?.let {
// Null checks for [compatibilityZoneURL], [rootTruststorePath] and [rootTruststorePassword] has been done in [CmdLineOptions.loadConfig]
attempt { registerWithNetwork(configuration, versionInfo, it) }.doOnException(handleRegistrationError) as? Try.Success ?: return ExitCodes.FAILURE
// At this point the node registration was successful. We can delete the marker file.
deleteNodeRegistrationMarker(cmdLineOptions.baseDirectory)
return ExitCodes.SUCCESS
// Step 9. Check if in registration mode.
checkAndRunRegistrationMode(configuration, versionInfo)?.let {
return if (it) ExitCodes.SUCCESS
else ExitCodes.FAILURE
}
// Step 10. Log startup info.
logStartupInfo(versionInfo, configuration)
// Step 11. Start node: create the node, check for other command-line options, add extra logging etc.
attempt { startNode(configuration, versionInfo, startTime) }.doOnSuccess { logger.info("Node exiting successfully") }.doOnException(handleStartError) as? Try.Success ?: return ExitCodes.FAILURE
return ExitCodes.SUCCESS
}
private fun checkAndRunRegistrationMode(configuration: NodeConfiguration, versionInfo: VersionInfo): Boolean? {
checkUnfinishedRegistration()
cmdLineOptions.nodeRegistrationOption?.let {
// Null checks for [compatibilityZoneURL], [rootTruststorePath] and [rootTruststorePassword] has been done in [CmdLineOptions.loadConfig]
attempt { registerWithNetwork(configuration, versionInfo, it) }.doOnException(handleRegistrationError) as? Try.Success
?: return false
// At this point the node registration was successful. We can delete the marker file.
deleteNodeRegistrationMarker(cmdLineOptions.baseDirectory)
return true
}
return null
}
private fun isValidJavaVersion(): Boolean {
if (!canNormalizeEmptyPath()) {
println("You are using a version of Java that is not supported (${System.getProperty("java.version")}). Please upgrade to the latest supported version.")
println("Corda will now exit...")
return false
}
return true
}
// TODO: Reconsider if automatic re-registration should be applied when something failed during initial registration.
// There might be cases where the node user should investigate what went wrong before registering again.
private fun checkUnfinishedRegistration() {
if (checkRegistrationMode() && !cmdLineOptions.isRegistration) {
println("Node was started before with `--initial-registration`, but the registration was not completed.\nResuming registration.")
// Pretend that the node was started with `--initial-registration` to help prevent user error.
cmdLineOptions.isRegistration = true
}
}
private fun <RESULT> attempt(action: () -> RESULT): Try<RESULT> = Try.on(action)
private fun Exception.isExpectedWhenStartingNode() = startNodeExpectedErrors.any { error -> error.isInstance(this) }
@ -272,6 +295,7 @@ open class NodeStartup: CordaCliWrapper("corda", "Runs a Corda Node") {
logLoadedCorDapps(node.services.cordappProvider.cordapps)
node.nodeReadyFuture.thenMatch({
// Elapsed time in seconds. We used 10 / 100.0 and not directly / 1000.0 to only keep two decimal digits.
val elapsed = (System.currentTimeMillis() - startTime) / 10 / 100.0
val name = nodeInfo.legalIdentitiesAndCerts.first().name.organisation
Node.printBasicNodeInfo("Node for \"$name\" started up and registered in $elapsed sec")