mirror of
https://github.com/corda/corda.git
synced 2025-01-18 02:39:51 +00:00
[CORDA-1596] Improve error message when CorDapp schema changes (#4506)
* Raise schema exceptions with better error * Add test and use new exceptions
This commit is contained in:
parent
6b0b8b394c
commit
22462cc1e8
@ -4,6 +4,7 @@ import co.paralleluniverse.strands.Strand
|
||||
import net.corda.core.internal.NamedCacheFactory
|
||||
import net.corda.core.schemas.MappedSchema
|
||||
import net.corda.core.utilities.contextLogger
|
||||
import org.hibernate.tool.schema.spi.SchemaManagementException
|
||||
import rx.Observable
|
||||
import rx.Subscriber
|
||||
import rx.subjects.UnicastSubject
|
||||
@ -101,7 +102,14 @@ class CordaPersistence(
|
||||
private val defaultIsolationLevel = databaseConfig.transactionIsolationLevel
|
||||
val hibernateConfig: HibernateConfiguration by lazy {
|
||||
transaction {
|
||||
HibernateConfiguration(schemas, databaseConfig, attributeConverters, jdbcUrl, cacheFactory, customClassLoader)
|
||||
try {
|
||||
HibernateConfiguration(schemas, databaseConfig, attributeConverters, jdbcUrl, cacheFactory, customClassLoader)
|
||||
} catch (e: Exception) {
|
||||
when (e) {
|
||||
is SchemaManagementException -> throw HibernateSchemaChangeException("Incompatible schema change detected. Please run the node with database.initialiseSchema=true. Reason: ${e.message}", e)
|
||||
else -> throw HibernateConfigException("Could not create Hibernate configuration: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,3 +347,7 @@ private fun Throwable.hasSQLExceptionCause(): Boolean =
|
||||
}
|
||||
|
||||
class CouldNotCreateDataSourceException(override val message: String?, override val cause: Throwable? = null) : Exception()
|
||||
|
||||
class HibernateSchemaChangeException(override val message: String?, override val cause: Throwable? = null): Exception()
|
||||
|
||||
class HibernateConfigException(override val message: String?, override val cause: Throwable? = null): Exception()
|
||||
|
@ -39,6 +39,7 @@ import net.corda.node.services.vault.VaultSchemaV1
|
||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||
import net.corda.nodeapi.internal.persistence.HibernateConfiguration
|
||||
import net.corda.nodeapi.internal.persistence.HibernateSchemaChangeException
|
||||
import net.corda.testing.core.*
|
||||
import net.corda.testing.internal.configureDatabase
|
||||
import net.corda.testing.internal.rigorousMock
|
||||
@ -50,6 +51,7 @@ import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.hibernate.SessionFactory
|
||||
import org.junit.*
|
||||
import java.math.BigDecimal
|
||||
@ -963,4 +965,34 @@ class HibernateConfigurationTest {
|
||||
private fun toStateRef(pStateRef: PersistentStateRef): StateRef {
|
||||
return StateRef(SecureHash.parse(pStateRef.txId), pStateRef.index)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `schema change`() {
|
||||
fun createNewDB(schemas: Set<MappedSchema>, initialiseSchema: Boolean = true): CordaPersistence {
|
||||
val schemaService = NodeSchemaService(extraSchemas = schemas)
|
||||
val dataSourceProps = makeTestDataSourceProperties("aa")
|
||||
val identityService = mock<IdentityService>().also { mock ->
|
||||
doReturn(null).whenever(mock).wellKnownPartyFromAnonymous(any<AbstractParty>())
|
||||
listOf(dummyCashIssuer, dummyNotary).forEach {
|
||||
doReturn(it.party).whenever(mock).wellKnownPartyFromAnonymous(it.party)
|
||||
doReturn(it.party).whenever(mock).wellKnownPartyFromX500Name(it.name)
|
||||
}
|
||||
}
|
||||
database = configureDatabase(dataSourceProps, DatabaseConfig(initialiseSchema = initialiseSchema), identityService::wellKnownPartyFromX500Name, identityService::wellKnownPartyFromAnonymous, schemaService)
|
||||
return database
|
||||
}
|
||||
|
||||
createNewDB(setOf(CashSchemaV1, SampleCashSchemaV1)).apply {
|
||||
database.transaction {
|
||||
vaultFiller.fillWithSomeTestCash(100.DOLLARS, issuerServices, 4, issuer.ref(1), rng = Random(0L))
|
||||
}
|
||||
}
|
||||
createNewDB(setOf(CashSchemaV1, SampleCashSchemaV1, SampleCashSchemaV2), initialiseSchema = false).use {
|
||||
assertThatThrownBy {
|
||||
it.transaction {
|
||||
vaultFiller.fillWithSomeTestCash(100.DOLLARS, issuerServices, 4, issuer.ref(1), rng = Random(0L))
|
||||
}
|
||||
}.isInstanceOf(HibernateSchemaChangeException::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user