mirror of
https://github.com/corda/corda.git
synced 2025-03-14 16:26:36 +00:00
[ENT-1843]: Not properly caught exception when node starts first time without migration (fix). (#879)
This commit is contained in:
parent
ee094ef129
commit
6ec394b6be
@ -6,6 +6,7 @@ release, see :doc:`upgrade-notes`.
|
||||
|
||||
Unreleased
|
||||
==========
|
||||
* Introduced a hierarchy of ``DatabaseMigrationException``s, allowing ``NodeStartup`` to gracefully inform users of problems related to database migrations before exiting with a non-zero code.
|
||||
|
||||
* ``WireTransaction.Companion.createComponentGroups`` has been marked as ``@CordaInternal``. It was never intended to be
|
||||
public and was already internal for Kotlin code.
|
||||
|
@ -23,7 +23,9 @@ import liquibase.resource.ClassLoaderResourceAccessor
|
||||
import net.corda.core.internal.MigrationHelpers.getMigrationResource
|
||||
import net.corda.core.schemas.MappedSchema
|
||||
import net.corda.core.utilities.contextLogger
|
||||
import java.io.*
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.InputStream
|
||||
import java.io.Writer
|
||||
import javax.sql.DataSource
|
||||
|
||||
class SchemaMigration(
|
||||
@ -85,9 +87,9 @@ class SchemaMigration(
|
||||
val resource = getMigrationResource(mappedSchema, classLoader)
|
||||
when {
|
||||
resource != null -> resource
|
||||
failOnMigrationMissing -> throw IllegalStateException("No migration defined for schema: ${mappedSchema.name} v${mappedSchema.version}")
|
||||
failOnMigrationMissing -> throw MissingMigrationException(mappedSchema)
|
||||
else -> {
|
||||
logger.warn("No migration defined for schema: ${mappedSchema.name} v${mappedSchema.version}")
|
||||
logger.warn(MissingMigrationException.errorMessageFor(mappedSchema))
|
||||
null
|
||||
}
|
||||
}
|
||||
@ -133,7 +135,7 @@ class SchemaMigration(
|
||||
check && !run -> {
|
||||
val unRunChanges = liquibase.listUnrunChangeSets(Contexts(), LabelExpression())
|
||||
if (unRunChanges.isNotEmpty()) {
|
||||
throw IllegalStateException("There are ${unRunChanges.size} outstanding database changes that need to be run. Please use the advanced migration tool. See: https://docs.corda.r3.com/database-migration.html")
|
||||
throw OutstandingDatabaseChangesException(unRunChanges.size)
|
||||
}
|
||||
}
|
||||
(outputWriter != null) && !check && !run -> liquibase.update(Contexts(), outputWriter)
|
||||
@ -161,3 +163,19 @@ class SchemaMigration(
|
||||
return if (liquibaseDbImplementation is MSSQLDatabase) AzureDatabase(conn) else liquibaseDbImplementation
|
||||
}
|
||||
}
|
||||
|
||||
open class DatabaseMigrationException(message: String) : IllegalArgumentException(message) {
|
||||
override val message: String = super.message!!
|
||||
}
|
||||
|
||||
class MissingMigrationException(@Suppress("MemberVisibilityCanBePrivate") val mappedSchema: MappedSchema) : DatabaseMigrationException(errorMessageFor(mappedSchema)) {
|
||||
internal companion object {
|
||||
fun errorMessageFor(mappedSchema: MappedSchema): String = "No migration defined for schema: ${mappedSchema.name} v${mappedSchema.version}"
|
||||
}
|
||||
}
|
||||
|
||||
class OutstandingDatabaseChangesException(@Suppress("MemberVisibilityCanBePrivate") private val count: Int) : DatabaseMigrationException(errorMessageFor(count)) {
|
||||
internal companion object {
|
||||
fun errorMessageFor(count: Int): String = "There are $count outstanding database changes that need to be run. Please use the advanced migration tool. See: https://docs.corda.r3.com/database-migration.html"
|
||||
}
|
||||
}
|
@ -12,8 +12,8 @@ package net.corda.node.internal
|
||||
|
||||
import com.jcabi.manifests.Manifests
|
||||
import io.netty.channel.unix.Errors
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.cordapp.Cordapp
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.internal.Emoji
|
||||
import net.corda.core.internal.concurrent.thenMatch
|
||||
import net.corda.core.internal.createDirectories
|
||||
@ -35,6 +35,7 @@ import net.corda.node.utilities.registration.HTTPNetworkRegistrationService
|
||||
import net.corda.node.utilities.registration.NodeRegistrationHelper
|
||||
import net.corda.nodeapi.internal.addShutdownHook
|
||||
import net.corda.nodeapi.internal.config.UnknownConfigurationKeysException
|
||||
import net.corda.nodeapi.internal.persistence.DatabaseMigrationException
|
||||
import net.corda.nodeapi.internal.persistence.oracleJdbcDriverSerialFilter
|
||||
import net.corda.tools.shell.InteractiveShell
|
||||
import org.fusesource.jansi.Ansi
|
||||
@ -134,6 +135,9 @@ open class NodeStartup(val args: Array<String>) {
|
||||
try {
|
||||
cmdlineOptions.baseDirectory.createDirectories()
|
||||
startNode(conf, versionInfo, startTime, cmdlineOptions)
|
||||
} catch (e: DatabaseMigrationException) {
|
||||
logger.error(e.message)
|
||||
return false
|
||||
} catch (e: Exception) {
|
||||
if (e is Errors.NativeIoException && e.message?.contains("Address already in use") == true) {
|
||||
logger.error("One of the ports required by the Corda node is already in use.")
|
||||
|
Loading…
x
Reference in New Issue
Block a user