mirror of
https://github.com/corda/corda.git
synced 2024-12-21 05:53:23 +00:00
[CORDA-2627] Fail the custom vault state migration if any states were skipped (#4782)
* Fail the migration if any states were skipped * Update test case to check running a second time
This commit is contained in:
parent
626fa19769
commit
055aabe1bb
@ -50,8 +50,8 @@ class VaultStateMigration : CordaMigration() {
|
|||||||
// This should only happen if there was no attachment that could be used to deserialise the output states, and the state was
|
// This should only happen if there was no attachment that could be used to deserialise the output states, and the state was
|
||||||
// serialised such that the participants list cannot be accessed (participants is calculated and not marked as a
|
// serialised such that the participants list cannot be accessed (participants is calculated and not marked as a
|
||||||
// SerializableCalculatedProperty.
|
// SerializableCalculatedProperty.
|
||||||
throw VaultStateMigrationException("Cannot add state parties as state class is not on the classpath " +
|
throw VaultStateMigrationException("Cannot add state parties for state ${stateAndRef.ref} as state class is not on the " +
|
||||||
"and participants cannot be synthesised")
|
"classpath and participants cannot be synthesised")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,8 +71,8 @@ class VaultStateMigration : CordaMigration() {
|
|||||||
override fun execute(database: Database?) {
|
override fun execute(database: Database?) {
|
||||||
logger.info("Migrating vault state data to V4 tables")
|
logger.info("Migrating vault state data to V4 tables")
|
||||||
if (database == null) {
|
if (database == null) {
|
||||||
logger.warn("Cannot migrate vault states: Liquibase failed to provide a suitable database connection")
|
logger.error("Cannot migrate vault states: Liquibase failed to provide a suitable database connection")
|
||||||
return
|
throw VaultStateMigrationException("Cannot migrate vault states as liquibase failed to provide a suitable database connection")
|
||||||
}
|
}
|
||||||
initialiseNodeServices(database, setOf(VaultMigrationSchemaV1, VaultSchemaV1))
|
initialiseNodeServices(database, setOf(VaultMigrationSchemaV1, VaultSchemaV1))
|
||||||
var statesSkipped = 0
|
var statesSkipped = 0
|
||||||
@ -98,13 +98,16 @@ class VaultStateMigration : CordaMigration() {
|
|||||||
it.relevancyStatus = Vault.RelevancyStatus.NOT_RELEVANT
|
it.relevancyStatus = Vault.RelevancyStatus.NOT_RELEVANT
|
||||||
}
|
}
|
||||||
} catch (e: VaultStateMigrationException) {
|
} catch (e: VaultStateMigrationException) {
|
||||||
logger.warn("An error occurred while migrating a vault state: ${e.message}. Skipping", e)
|
logger.warn("An error occurred while migrating a vault state: ${e.message}. Skipping. This will cause the " +
|
||||||
|
"migration to fail.", e)
|
||||||
statesSkipped++
|
statesSkipped++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (statesSkipped > 0) {
|
if (statesSkipped > 0) {
|
||||||
logger.error("$statesSkipped states could not be migrated as there was no class available for them.")
|
logger.error("$statesSkipped states could not be migrated as there was no class available for them.")
|
||||||
|
throw VaultStateMigrationException("Failed to migrate $statesSkipped states in the vault. Check the logs for details of the " +
|
||||||
|
"error for each state.")
|
||||||
}
|
}
|
||||||
logger.info("Finished performing vault state data migration for ${persistentStates.numStates - statesSkipped} states")
|
logger.info("Finished performing vault state data migration for ${persistentStates.numStates - statesSkipped} states")
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ import java.time.Clock
|
|||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -431,15 +432,20 @@ class VaultStateMigrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `State with corresponding transaction missing is skipped`() {
|
fun `State with corresponding transaction missing fails migration`() {
|
||||||
val cash = Cash()
|
val cash = Cash()
|
||||||
val unknownTx = createCashTransaction(cash, 100.DOLLARS, BOB)
|
val unknownTx = createCashTransaction(cash, 100.DOLLARS, BOB)
|
||||||
createVaultStatesFromTransaction(unknownTx)
|
createVaultStatesFromTransaction(unknownTx)
|
||||||
|
|
||||||
addCashStates(10, BOB)
|
addCashStates(10, BOB)
|
||||||
val migration = VaultStateMigration()
|
val migration = VaultStateMigration()
|
||||||
migration.execute(liquibaseDB)
|
assertFailsWith<VaultStateMigrationException> { migration.execute(liquibaseDB) }
|
||||||
assertEquals(10, getStatePartyCount())
|
assertEquals(10, getStatePartyCount())
|
||||||
|
|
||||||
|
// Now add the missing transaction and ensure that the migration succeeds
|
||||||
|
storeTransaction(unknownTx)
|
||||||
|
migration.execute(liquibaseDB)
|
||||||
|
assertEquals(11, getStatePartyCount())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -453,8 +459,8 @@ class VaultStateMigrationTest {
|
|||||||
assertEquals(10, getVaultStateCount(Vault.RelevancyStatus.RELEVANT))
|
assertEquals(10, getVaultStateCount(Vault.RelevancyStatus.RELEVANT))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = VaultStateMigrationException::class)
|
||||||
fun `Null database causes migration to be ignored`() {
|
fun `Null database causes migration to fail`() {
|
||||||
val migration = VaultStateMigration()
|
val migration = VaultStateMigration()
|
||||||
// Just check this does not throw an exception
|
// Just check this does not throw an exception
|
||||||
migration.execute(null)
|
migration.execute(null)
|
||||||
|
Loading…
Reference in New Issue
Block a user