mirror of
https://github.com/corda/corda.git
synced 2025-01-29 15:43:55 +00:00
CORDA-3200 Use PersistentIdentityMigrationBuilder instead of schema a… (#5449)
* CORDA-3200 Use PersistentIdentityMigrationBuilder instead of schema and correctly name table using node prefix * CORDA-3200 Remove hacky test migration from PersistentIdentityMigrationNewTable into a unit test to fix postgres failure
This commit is contained in:
parent
eece19cce0
commit
4fb1787f1e
@ -44,26 +44,14 @@ class PersistentIdentityMigrationNewTable : CordaMigration() {
|
||||
logger.error("Cannot migrate persistent states: Liquibase failed to provide a suitable database connection")
|
||||
throw PersistentIdentitiesMigrationException("Cannot migrate persistent states as liquibase failed to provide a suitable database connection")
|
||||
}
|
||||
initialiseNodeServices(database, setOf(PersistentIdentitiesMigrationSchemaV1))
|
||||
initialiseNodeServices(database, setOf(PersistentIdentitiesMigrationSchemaBuilder.getMappedSchema()))
|
||||
|
||||
val connection = database.connection as JdbcConnection
|
||||
|
||||
doAndTestMigration(connection)
|
||||
}
|
||||
|
||||
private fun doAndTestMigration(connection: JdbcConnection) {
|
||||
val alice = TestIdentity(CordaX500Name("Alice Corp", "Madrid", "ES"), 70)
|
||||
val pkHash = addTestMapping(connection, alice)
|
||||
|
||||
// Extract data from old table needed to populate the new table
|
||||
val keyPartiesMap = extractKeyParties(connection)
|
||||
|
||||
keyPartiesMap.forEach {
|
||||
insertEntry(connection, it)
|
||||
}
|
||||
|
||||
verifyTestMigration(connection, pkHash, alice.name.toString())
|
||||
deleteTestMapping(connection, pkHash)
|
||||
}
|
||||
|
||||
private fun extractKeyParties(connection: JdbcConnection): Map<String, CordaX500Name> {
|
||||
@ -104,41 +92,6 @@ class PersistentIdentityMigrationNewTable : CordaMigration() {
|
||||
override fun validate(database: Database?): ValidationErrors? {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun addTestMapping(connection: JdbcConnection, testIdentity: TestIdentity): String {
|
||||
val pkHash = UUID.randomUUID().toString()
|
||||
val cert = testIdentity.identity.certPath.encoded
|
||||
|
||||
connection.prepareStatement("INSERT INTO node_identities (pk_hash, identity_value) VALUES (?,?)").use {
|
||||
it.setString(1, pkHash)
|
||||
it.setBytes(2, cert)
|
||||
it.executeUpdate()
|
||||
}
|
||||
return pkHash
|
||||
}
|
||||
|
||||
private fun deleteTestMapping(connection: JdbcConnection, pkHash: String) {
|
||||
connection.prepareStatement("DELETE FROM node_identities WHERE pk_hash = ?").use {
|
||||
it.setString(1, pkHash)
|
||||
it.executeUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
private fun verifyTestMigration(connection: JdbcConnection, pk: String, name: String) {
|
||||
connection.createStatement().use {
|
||||
try {
|
||||
val rs = it.executeQuery("SELECT (pk_hash, name) FROM node_identities_no_cert")
|
||||
while (rs.next()) {
|
||||
val result = rs.getString(1)
|
||||
require(result.contains(pk))
|
||||
require(result.contains(name))
|
||||
}
|
||||
rs.close()
|
||||
} catch (e: Exception) {
|
||||
logger.error(e.localizedMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,49 +103,17 @@ class PersistentIdentityMigrationNewTable : CordaMigration() {
|
||||
*/
|
||||
object PersistentIdentitiesMigrationSchema
|
||||
|
||||
object PersistentIdentitiesMigrationSchemaV1 : MappedSchema(schemaFamily = PersistentIdentitiesMigrationSchema.javaClass, version = 1,
|
||||
mappedTypes = listOf(
|
||||
DBTransactionStorage.DBTransaction::class.java,
|
||||
PersistentIdentityService.PersistentPublicKeyHashToCertificate::class.java,
|
||||
PersistentIdentityService.PersistentPartyToPublicKeyHash::class.java,
|
||||
PersistentIdentityService.PersistentPublicKeyHashToParty::class.java,
|
||||
BasicHSMKeyManagementService.PersistentKey::class.java,
|
||||
NodeAttachmentService.DBAttachment::class.java,
|
||||
DBNetworkParametersStorage.PersistentNetworkParameters::class.java
|
||||
)
|
||||
)
|
||||
|
||||
class PersistentIdentitiesMigrationException(msg: String, cause: Exception? = null) : Exception(msg, cause)
|
||||
|
||||
/**
|
||||
* A class that encapsulates a test identity containing a [CordaX500Name] and a [KeyPair]. Duplicate of [net.corda.testing.core.TestIdentity]
|
||||
* to avoid circular dependencies.
|
||||
*/
|
||||
private class TestIdentity(val name: CordaX500Name, val keyPair: KeyPair) {
|
||||
|
||||
/** Creates an identity with a deterministic [keyPair] i.e. same [entropy] same keyPair. */
|
||||
@JvmOverloads
|
||||
constructor(name: CordaX500Name, entropy: Long, signatureScheme: SignatureScheme = Crypto.DEFAULT_SIGNATURE_SCHEME)
|
||||
: this(name, Crypto.deriveKeyPairFromEntropy(signatureScheme, BigInteger.valueOf(entropy)))
|
||||
|
||||
val publicKey: PublicKey get() = keyPair.public
|
||||
val party: Party = Party(name, publicKey)
|
||||
val identity: PartyAndCertificate by lazy { getTestPartyAndCertificate(party) } // Often not needed.
|
||||
|
||||
fun getTestPartyAndCertificate(party: Party): PartyAndCertificate {
|
||||
val trustRoot: X509Certificate = DEV_ROOT_CA.certificate
|
||||
val intermediate: CertificateAndKeyPair = DEV_INTERMEDIATE_CA
|
||||
|
||||
val (nodeCaCert, nodeCaKeyPair) = createDevNodeCa(intermediate, party.name)
|
||||
|
||||
val identityCert = X509Utilities.createCertificate(
|
||||
CertificateType.LEGAL_IDENTITY,
|
||||
nodeCaCert,
|
||||
nodeCaKeyPair,
|
||||
party.name.x500Principal,
|
||||
party.owningKey)
|
||||
|
||||
val certPath = X509Utilities.buildCertPath(identityCert, nodeCaCert, intermediate.certificate, trustRoot)
|
||||
return PartyAndCertificate(certPath)
|
||||
}
|
||||
}
|
||||
object PersistentIdentitiesMigrationSchemaBuilder {
|
||||
fun getMappedSchema() =
|
||||
MappedSchema(schemaFamily = PersistentIdentitiesMigrationSchema.javaClass, version = 1,
|
||||
mappedTypes = listOf(
|
||||
DBTransactionStorage.DBTransaction::class.java,
|
||||
PersistentIdentityService.PersistentPublicKeyHashToCertificate::class.java,
|
||||
PersistentIdentityService.PersistentPartyToPublicKeyHash::class.java,
|
||||
PersistentIdentityService.PersistentPublicKeyHashToParty::class.java,
|
||||
BasicHSMKeyManagementService.PersistentKey::class.java,
|
||||
NodeAttachmentService.DBAttachment::class.java,
|
||||
DBNetworkParametersStorage.PersistentNetworkParameters::class.java
|
||||
))
|
||||
}
|
||||
class PersistentIdentitiesMigrationException(msg: String, cause: Exception? = null) : Exception(msg, cause)
|
@ -5,7 +5,7 @@
|
||||
logicalFilePath="migration/node-services.changelog-init.xml">
|
||||
|
||||
<changeSet author="R3.Corda" id="add-new-persistence-table">
|
||||
<createTable tableName="identities_no_cert">
|
||||
<createTable tableName="node_identities_no_cert">
|
||||
<column name="pk_hash" type="NVARCHAR(130)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
|
@ -27,8 +27,10 @@ import org.junit.ClassRule
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito
|
||||
import java.security.KeyPair
|
||||
import java.sql.Connection
|
||||
import java.time.Clock
|
||||
import java.time.Duration
|
||||
import java.util.*
|
||||
|
||||
class PersistentIdentityMigrationNewTableTest{
|
||||
companion object {
|
||||
@ -83,15 +85,9 @@ class PersistentIdentityMigrationNewTableTest{
|
||||
|
||||
@Test
|
||||
fun `migrate identities to new table`() {
|
||||
/**
|
||||
* TODO - We have to mock every statement/ result to test this properly.
|
||||
*
|
||||
* The workaround for now is the [PersistentIdentitiesMigration.addTestMapping] and
|
||||
* [PersistentIdentitiesMigration.deleteTestMapping] methods that allow us to see the migration occur properly during debugging.
|
||||
*
|
||||
* Since [PersistentIdentitiesMigration] implements [CordaMigration] the migration will run when the DB is setup.
|
||||
*/
|
||||
PersistentIdentityMigrationNewTable()
|
||||
val pkHash = addTestMapping(cordaDB.dataSource.connection, alice)
|
||||
PersistentIdentityMigrationNewTable()
|
||||
verifyTestMigration(cordaDB.dataSource.connection, pkHash, alice.name.toString())
|
||||
}
|
||||
|
||||
private fun saveAllIdentities(identities: List<PartyAndCertificate>) {
|
||||
@ -137,4 +133,39 @@ class PersistentIdentityMigrationNewTableTest{
|
||||
session.save(persistentParams)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addTestMapping(connection: Connection, testIdentity: TestIdentity): String {
|
||||
val pkHash = UUID.randomUUID().toString()
|
||||
val cert = testIdentity.identity.certPath.encoded
|
||||
|
||||
connection.prepareStatement("INSERT INTO node_identities (pk_hash, identity_value) VALUES (?,?)").use {
|
||||
it.setString(1, pkHash)
|
||||
it.setBytes(2, cert)
|
||||
it.executeUpdate()
|
||||
}
|
||||
return pkHash
|
||||
}
|
||||
|
||||
// private fun deleteTestMapping(connection: Connection, pkHash: String) {
|
||||
// connection.prepareStatement("DELETE FROM node_identities WHERE pk_hash = ?").use {
|
||||
// it.setString(1, pkHash)
|
||||
// it.executeUpdate()
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun verifyTestMigration(connection: Connection, pk: String, name: String) {
|
||||
connection.createStatement().use {
|
||||
try {
|
||||
val rs = it.executeQuery("SELECT (pk_hash, name) FROM node_identities_no_cert")
|
||||
while (rs.next()) {
|
||||
val result = rs.getString(1)
|
||||
require(result.contains(pk))
|
||||
require(result.contains(name))
|
||||
}
|
||||
rs.close()
|
||||
} catch (e: Exception) {
|
||||
println(e.localizedMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +1,25 @@
|
||||
package net.corda.node.services.persistence
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.KeyManagementService
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.finance.DOLLARS
|
||||
import net.corda.finance.`issued by`
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.finance.flows.AbstractCashFlow
|
||||
import net.corda.finance.issuedBy
|
||||
import net.corda.node.migration.VaultStateMigrationTest.Companion.bankOfCorda
|
||||
import net.corda.node.services.identity.PersistentIdentityService
|
||||
import net.corda.node.services.keys.BasicHSMKeyManagementService
|
||||
import net.corda.node.services.keys.E2ETestKeyManagementService
|
||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||
import net.corda.testing.common.internal.testNetworkParameters
|
||||
import net.corda.testing.core.BOC_NAME
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
import net.corda.testing.core.TestIdentity
|
||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.MockNetworkParameters
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.StartedMockNode
|
||||
import net.corda.testing.node.internal.FINANCE_CORDAPPS
|
||||
import net.corda.testing.node.internal.InternalMockNetwork
|
||||
import net.corda.testing.node.internal.TestStartedNode
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.util.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class HibernateColumnConverterTests {
|
||||
|
Loading…
x
Reference in New Issue
Block a user