Integrate db migration tool - liquibase (#150)

[ENT-996]: integrate Liquibase for data migration
This commit is contained in:
Tudor Malene 2017-12-16 15:58:12 +00:00 committed by GitHub
parent af596cfdde
commit f2194fcfd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
103 changed files with 1594 additions and 152 deletions

View File

@ -52,6 +52,7 @@ buildscript {
ext.spring_jdbc_version ='5.0.0.RELEASE'
ext.shiro_version = '1.4.0'
ext.artifactory_plugin_version = constants.getProperty('artifactoryPluginVersion')
ext.liquibase_version = '3.5.3'
// Update 121 is required for ObjectInputFilter and at time of writing 131 was latest:
ext.java8_minUpdateVersion = '131'

View File

@ -33,7 +33,7 @@ class IdentitySyncFlowTests {
mockNet = MockNetwork(
networkSendManuallyPumped = false,
threadPerNode = true,
cordappPackages = listOf("net.corda.finance.contracts.asset")
cordappPackages = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas")
)
}

View File

@ -19,6 +19,9 @@ object NodeInfoSchemaV1 : MappedSchema(
version = 1,
mappedTypes = listOf(PersistentNodeInfo::class.java, DBPartyAndCertificate::class.java, DBHostAndPort::class.java)
) {
override val migrationResource = "node-info.changelog-master"
@Entity
@Table(name = "node_infos")
class PersistentNodeInfo(

View File

@ -4,9 +4,7 @@ import net.corda.core.contracts.*
import net.corda.core.identity.AbstractParty
import org.hibernate.annotations.Type
import java.util.*
import javax.persistence.Column
import javax.persistence.ElementCollection
import javax.persistence.MappedSuperclass
import javax.persistence.*
/**
* JPA representation of the common schema entities
@ -18,6 +16,8 @@ object CommonSchema
*/
object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, version = 1, mappedTypes = emptyList()) {
override val migrationResource = "common.changelog-master"
@MappedSuperclass
open class LinearState(
/** [ContractState] attributes */
@ -25,6 +25,9 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
/** X500Name of participant parties **/
@ElementCollection
@Column(name = "participants")
@CollectionTable(name="state_participants",joinColumns = arrayOf(
JoinColumn(name = "output_index", referencedColumnName = "output_index"),
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")))
var participants: MutableSet<AbstractParty>? = null,
/**
@ -34,6 +37,7 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
var externalId: String?,
@Column(name = "uuid", nullable = false)
@Type(type = "uuid-char")
var uuid: UUID
) : PersistentState() {
@ -50,6 +54,9 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
/** X500Name of participant parties **/
@ElementCollection
@Column(name = "participants")
@CollectionTable(name="state_participants",joinColumns = arrayOf(
JoinColumn(name = "output_index", referencedColumnName = "output_index"),
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")))
var participants: MutableSet<AbstractParty>? = null,
/** [OwnableState] attributes */

View File

@ -38,9 +38,16 @@ interface QueryableState : ContractState {
* @param mappedTypes The JPA entity classes that the ORM layer needs to be configure with for this schema.
*/
open class MappedSchema(schemaFamily: Class<*>,
val version: Int,
val mappedTypes: Iterable<Class<*>>) {
val version: Int,
val mappedTypes: Iterable<Class<*>>) {
val name: String = schemaFamily.name
/**
* Points to a classpath resource containing the database changes for the [mappedTypes]
*/
protected open val migrationResource: String? = null
internal fun getMigrationResource(): String = migrationResource!!
override fun toString(): String = "${this.javaClass.simpleName}(name=$name, version=$version)"
}
//DOCEND MappedSchema
@ -69,4 +76,6 @@ data class PersistentStateRef(
/**
* Marker interface to denote a persistable Corda state entity that will always have a transaction id and index
*/
interface StatePersistable
interface StatePersistable
fun getMigrationResource(schema: MappedSchema): String = schema.getMigrationResource()

View File

@ -49,7 +49,7 @@ class ContractUpgradeFlowTest {
@Before
fun setup() {
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows"))
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows", "net.corda.finance.schemas"))
aliceNode = mockNet.createPartyNode(ALICE_NAME)
bobNode = mockNet.createPartyNode(BOB_NAME)
notary = mockNet.defaultNotaryIdentity

View File

@ -144,3 +144,94 @@ which is then referenced within a custom flow:
:start-after: DOCSTART TopupIssuer
:end-before: DOCEND TopupIssuer
Database Migration
==================
As a database migration tool, we use the open source library liquibase <http://www.liquibase.org/>.
If migration is enabled, the database state is checked (and updated) during node startup. (After deploying a new version of the code that contains database migrations, they are executed at that point).
Possible database changes range from schema changes to data changes.
Liquibase will create a table called ``DATABASECHANGELOG``, that will store useful information about each change ( like timestamp, description, user, md5 hash so it can't be changed, etc)
We can also "tag" the database at each release to make rollback easier.
Database changes are maintained in several xml files per ``MappedSchema``, so that only migrations corresponding to the nodes configured schemas are run.
For example, on the node-info schema, if there are any database changes for release 12, the changes will be added to a new file called: ``node-info.changelog-v12.xml`` which has to be included in ``node-info.changelog-master.xml``.
Example:
--------
Let's suppose that at some point, at version 12, there is a need to add a new column: ``contentSize`` to the ``DBAttachment`` entity.
This means we have to:
- In the source code, add the ``contentSize`` property and map it to a new column.
- create the column in the ``node_attachments`` table.
- Run an update to set the size of all existing attachments, to not break the code that uses the new property
.. code-block:: kotlin
class DBAttachment(
...
@Column(name = "content")
@Lob
var content: ByteArray,
//newly added column
@Column(name = "content_size")
var contentSize: Int,
...
)
The ``DBAttachment`` entity is included in the ``NodeServicesV1`` schema, so we create a file ``node-services.changelog-v12.xml`` with this changeset:
.. code-block:: xml
<changeSet author="developer_name" id="add content_size column">
<addColumn tableName="node_attachments">
<column name="content_size" type="INT"/>
</addColumn>
<update tableName="node_attachments">
<column name="content_size" valueComputed="length(content)"/>
</update>
<rollback>
<dropColumn tableName="node_attachments" columnName="content_size"/>
</rollback>
</changeSet>
And include it in `node-services.changelog-master.xml`:
.. code-block:: xml
<databaseChangeLog>
<!--the original schema-->
<include file="migration/node-services.changelog-init.xml"/>
<!--migrations from previous releases-->
<include file="migration/node-services.changelog-v4.xml"/>
<include file="migration/node-services.changelog-v7.xml"/>
<!--added now-->
<include file="migration/node-services.changelog-v12.xml"/>
</databaseChangeLog>
By adding the rollback script, we give users the option to revert to an older version of the software.
An easy way to manage the db version is to tag it on every release (or on every release that has migrations)
<http://www.liquibase.org/documentation/changes/tag_database.html>
Usage:
------
Configurations:
- To enable migration at startup, set:
- database.runMigration = true // true by default
Command line arguments:
- To export the migration to a file use `—just-generate-database-migration outputSqlFile`. This will generate the delta from the last release, and will output the resulting sql into the outputSqlFile. It will not write to the db. It will not start the node! ( default value for `outputSqlFile` is a `.sql` file with the current date )
- To run the migration without starting the node: `--just-run-db-migration`

View File

@ -6,6 +6,13 @@ from the previous milestone release.
UNRELEASED
----------
* Integrate database migration tool: http://www.liquibase.org/ :
* The migration files are split per ``MappedSchemas``. (added new property: migrationResource used to point to the resource file containing the db changes corresponding to the JPA entities)
* config flag ``database.initialiseSchema`` was renamed to: ``database.runMigration`` (if true then the migration is run during startup just before hibernate is initialised.)
* config flag: ``database.serverNameTablePrefix`` was removed as we no longer need table prefixes
* New command line argument: “—just-generate-database-migration outputSqlFile”: This will generate the delta from the last release, and will output the resulting sql into the outputSqlFile. It will not write to the db. It will not start the node!
* New command line argument: “--just-run-db-migration”: This will only run the db migration. It will not start the node!
* Exporting additional JMX metrics (artemis, hibernate statistics) and loading Jolokia agent at JVM startup when using
DriverDSL and/or cordformation node runner.

View File

@ -70,7 +70,6 @@ path to the node's base directory.
:database: Database configuration:
:serverNameTablePrefix: Prefix string to apply to all the database tables. The default is no prefix.
:transactionIsolationLevel: Transaction isolation level as defined by the ``TRANSACTION_`` constants in
``java.sql.Connection``, but without the "TRANSACTION_" prefix. Defaults to REPEATABLE_READ.
:exportHibernateJMXStatistics: Whether to export Hibernate JMX statistics (caution: expensive run-time overhead)
@ -81,13 +80,13 @@ path to the node's base directory.
:database: This section is used to configure JDBC and Hibernate related properties:
:serverNameTablePrefix: Prefix string to apply to all the database tables. The default is no prefix.
:transactionIsolationLevel: Transaction isolation level as defined by the ``TRANSACTION_`` constants in
``java.sql.Connection``, but without the "TRANSACTION_" prefix. Defaults to REPEATABLE_READ.
:exportHibernateJMXStatistics: Whether to export Hibernate JMX statistics (caution: expensive run-time overhead)
:runMigration: Boolean on whether to run the database migration scripts. Defaults to true.
:schema: (optional) some database providers require a schema name when generating DDL and SQL statements.
(the value is passed to Hibernate property 'hibernate.hbm2ddl.auto').

View File

@ -19,7 +19,11 @@ object CashSchema
* at the time of writing.
*/
@CordaSerializable
object CashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCashState::class.java)) {
object CashSchemaV1 : MappedSchema(
schemaFamily = CashSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCashState::class.java)) {
override val migrationResource = "cash.changelog-master"
@Entity
@Table(name = "contract_cash_states",
indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"),

View File

@ -22,7 +22,11 @@ object CommercialPaperSchema
* as it stood at the time of writing.
*/
@CordaSerializable
object CommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCommercialPaperState::class.java)) {
object CommercialPaperSchemaV1 : MappedSchema(
schemaFamily = CommercialPaperSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCommercialPaperState::class.java)) {
override val migrationResource = "commercial-paper.changelog-master"
@Entity
@Table(name = "cp_states",
indexes = arrayOf(Index(name = "ccy_code_index", columnList = "ccy_code"),

View File

@ -0,0 +1,31 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd" >
<changeSet author="tudormalene (generated)" id="1511451595465-2">
<createTable tableName="contract_cash_states">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="ccy_code" type="VARCHAR(3)"/>
<column name="issuer_key_hash" type="VARCHAR(130)"/>
<column name="issuer_ref" type="varbinary(512)"/>
<column name="owner_name" type="VARCHAR(255)"/>
<column name="pennies" type="BIGINT"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-28">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="contract_cash_states_pkey" tableName="contract_cash_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-51">
<createIndex indexName="ccy_code_idx" tableName="contract_cash_states">
<column name="ccy_code"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-57">
<createIndex indexName="pennies_idx" tableName="contract_cash_states">
<column name="pennies"/>
</createIndex>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd" >
<include file="migration/cash.changelog-init.xml"/>
</databaseChangeLog>

View File

@ -0,0 +1,39 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1511451595465-3">
<createTable tableName="cp_states">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="ccy_code" type="VARCHAR(3)"/>
<column name="face_value" type="BIGINT"/>
<column name="face_value_issuer_key_hash" type="VARCHAR(130)"/>
<column name="face_value_issuer_ref" type="varbinary(512)"/>
<column name="issuance_key_hash" type="VARCHAR(130)"/>
<column name="issuance_ref" type="varbinary(255)"/>
<column name="maturity_instant" type="timestamp"/>
<column name="owner_key_hash" type="VARCHAR(130)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-29">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="cp_states_pkey" tableName="cp_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-52">
<createIndex indexName="ccy_code_index" tableName="cp_states">
<column name="ccy_code"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-54">
<createIndex indexName="face_value_index" tableName="cp_states">
<column name="face_value"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-56">
<createIndex indexName="maturity_index" tableName="cp_states">
<column name="maturity_instant"/>
</createIndex>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<include file="migration/commercial-paper.changelog-init.xml"/>
</databaseChangeLog>

View File

@ -261,14 +261,14 @@ class CommercialPaperTestsGeneric {
private lateinit var aliceVaultService: VaultService
private lateinit var alicesVault: Vault<ContractState>
private val notaryServices = MockServices(rigorousMock(), MEGA_CORP.name, dummyNotary.key)
private val issuerServices = MockServices(listOf("net.corda.finance.contracts"), rigorousMock(), MEGA_CORP.name, dummyCashIssuer.key)
private val issuerServices = MockServices(listOf("net.corda.finance.contracts", "net.corda.finance.schemas"), rigorousMock(), MEGA_CORP.name, dummyCashIssuer.key)
private lateinit var moveTX: SignedTransaction
@Test
fun `issue move and then redeem`() {
val aliceDatabaseAndServices = makeTestDatabaseAndMockServices(
listOf(ALICE_KEY),
makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)),
listOf("net.corda.finance.contracts"),
listOf("net.corda.finance.contracts", "net.corda.finance.schemas"),
MEGA_CORP.name)
val databaseAlice = aliceDatabaseAndServices.first
aliceServices = aliceDatabaseAndServices.second
@ -281,7 +281,7 @@ class CommercialPaperTestsGeneric {
val bigCorpDatabaseAndServices = makeTestDatabaseAndMockServices(
listOf(BIG_CORP_KEY),
makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)),
listOf("net.corda.finance.contracts"),
listOf("net.corda.finance.contracts", "net.corda.finance.schemas"),
MEGA_CORP.name)
val databaseBigCorp = bigCorpDatabaseAndServices.first
bigCorpServices = bigCorpDatabaseAndServices.second

View File

@ -93,15 +93,15 @@ class CashTests {
@Before
fun setUp() {
LogHelper.setLevel(NodeVaultService::class)
megaCorpServices = MockServices(listOf("net.corda.finance.contracts.asset"), rigorousMock(), MEGA_CORP.name, MEGA_CORP_KEY)
miniCorpServices = MockServices(listOf("net.corda.finance.contracts.asset"), rigorousMock<IdentityServiceInternal>().also {
megaCorpServices = MockServices(listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"), rigorousMock(), MEGA_CORP.name, MEGA_CORP_KEY)
miniCorpServices = MockServices(listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"), rigorousMock<IdentityServiceInternal>().also {
doNothing().whenever(it).justVerifyAndRegisterIdentity(argThat { name == MINI_CORP.name })
}, MINI_CORP.name, MINI_CORP_KEY)
val notaryServices = MockServices(listOf("net.corda.finance.contracts.asset"), rigorousMock(), DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
val databaseAndServices = makeTestDatabaseAndMockServices(
listOf(generateKeyPair()),
makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)),
listOf("net.corda.finance.contracts.asset"),
listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"),
CordaX500Name("Me", "London", "GB"))
database = databaseAndServices.first
ourServices = databaseAndServices.second

View File

@ -8,9 +8,9 @@ import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState
import net.corda.core.transactions.LedgerTransaction
import net.corda.finance.schemas.SampleCashSchemaV1
import net.corda.finance.schemas.SampleCashSchemaV2
import net.corda.finance.schemas.SampleCashSchemaV3
import net.corda.finance.sampleschemas.SampleCashSchemaV1
import net.corda.finance.sampleschemas.SampleCashSchemaV2
import net.corda.finance.sampleschemas.SampleCashSchemaV3
import net.corda.finance.utils.sumCash
import net.corda.finance.utils.sumCashOrNull
import net.corda.finance.utils.sumCashOrZero

View File

@ -17,7 +17,7 @@ import org.junit.Test
import java.util.Collections.nCopies
class CashSelectionH2ImplTest {
private val mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance"))
private val mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance", "net.corda.core.schemas", "net.corda.finance.sampleschemas"))
@After
fun cleanUp() {

View File

@ -29,7 +29,7 @@ class CashExitFlowTests {
@Before
fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("net.corda.finance.contracts.asset"))
cordappPackages = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
notary = mockNet.defaultNotaryIdentity

View File

@ -26,7 +26,9 @@ class CashIssueFlowTests {
@Before
fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset"))
mockNet = MockNetwork(
servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
notary = mockNet.defaultNotaryIdentity

View File

@ -31,7 +31,7 @@ class CashPaymentFlowTests {
@Before
fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset"))
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
aliceNode = mockNet.createPartyNode(ALICE_NAME)

View File

@ -1,4 +1,4 @@
package net.corda.finance.schemas
package net.corda.finance.sampleschemas
import net.corda.core.contracts.MAX_ISSUER_REF_SIZE
import net.corda.core.schemas.MappedSchema
@ -20,8 +20,11 @@ object CashSchema
* at the time of writing.
*/
object SampleCashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCashState::class.java)) {
override val migrationResource = "sample-cash-v1.changelog-init"
@Entity
@Table(name = "contract_cash_states",
@Table(name = "contract_cash_states_v1",
indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"),
Index(name = "pennies_idx", columnList = "pennies")))
class PersistentCashState(

View File

@ -1,4 +1,4 @@
package net.corda.finance.schemas
package net.corda.finance.sampleschemas
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.CommonSchemaV1
@ -15,6 +15,9 @@ import javax.persistence.Table
*/
object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 2,
mappedTypes = listOf(PersistentCashState::class.java)) {
override val migrationResource = "sample-cash-v2.changelog-init"
@Entity
@Table(name = "cash_states_v2",
indexes = arrayOf(Index(name = "ccy_code_idx2", columnList = "ccy_code")))

View File

@ -1,14 +1,11 @@
package net.corda.finance.schemas
package net.corda.finance.sampleschemas
import net.corda.core.contracts.MAX_ISSUER_REF_SIZE
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import org.hibernate.annotations.Type
import javax.persistence.Column
import javax.persistence.ElementCollection
import javax.persistence.Entity
import javax.persistence.Table
import javax.persistence.*
/**
* First version of a cash contract ORM schema that maps all fields of the [Cash] contract state as it stood
@ -16,6 +13,9 @@ import javax.persistence.Table
*/
object SampleCashSchemaV3 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 3,
mappedTypes = listOf(PersistentCashState::class.java)) {
override val migrationResource = "sample-cash-v3.changelog-init"
@Entity
@Table(name = "cash_states_v3")
class PersistentCashState(
@ -23,6 +23,9 @@ object SampleCashSchemaV3 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
/** X500Name of participant parties **/
@ElementCollection
@CollectionTable(name="state_participants", joinColumns = arrayOf(
JoinColumn(name = "output_index", referencedColumnName = "output_index"),
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")))
var participants: MutableSet<AbstractParty>? = null,
/** X500Name of owner party **/

View File

@ -1,4 +1,4 @@
package net.corda.finance.schemas
package net.corda.finance.sampleschemas
import net.corda.core.contracts.MAX_ISSUER_REF_SIZE
import net.corda.core.schemas.MappedSchema
@ -21,8 +21,11 @@ object CommercialPaperSchema
* as it stood at the time of writing.
*/
object SampleCommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCommercialPaperState::class.java)) {
override val migrationResource = "sample-cp-v1.changelog-init"
@Entity
@Table(name = "cp_states",
@Table(name = "cp_states_v1",
indexes = arrayOf(Index(name = "ccy_code_index", columnList = "ccy_code"),
Index(name = "maturity_index", columnList = "maturity_instant"),
Index(name = "face_value_index", columnList = "face_value")))

View File

@ -1,4 +1,4 @@
package net.corda.finance.schemas
package net.corda.finance.sampleschemas
import net.corda.core.contracts.MAX_ISSUER_REF_SIZE
import net.corda.core.identity.AbstractParty
@ -19,6 +19,9 @@ import javax.persistence.Table
*/
object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1,
mappedTypes = listOf(PersistentCommercialPaperState::class.java)) {
override val migrationResource = "sample-cp-v2.changelog-init"
@Entity
@Table(name = "cp_states_v2",
indexes = arrayOf(Index(name = "ccy_code_index2", columnList = "ccy_code"),

View File

@ -0,0 +1,35 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1511451595465-2">
<createTable tableName="contract_cash_states_v1">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="ccy_code" type="VARCHAR(3)"/>
<column name="issuer_key_hash" type="VARCHAR(130)"/>
<column name="issuer_ref" type="varbinary(512)"/>
<column name="owner_key_hash" type="VARCHAR(130)"/>
<column name="pennies" type="BIGINT"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-28">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="contract_cash_states_v1_pkey"
tableName="contract_cash_states_v1"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-51">
<createIndex indexName="ccy_code_v1_idx" tableName="contract_cash_states_v1">
<column name="ccy_code"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-57">
<createIndex indexName="pennies_v1_idx" tableName="contract_cash_states_v1">
<column name="pennies"/>
</createIndex>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,31 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1512743551377-1">
<createTable tableName="cash_states_v2">
<column name="output_index" type="INT(10)">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="issuer_name" type="VARCHAR(255)"/>
<column name="issuer_ref" type="VARBINARY(512)"/>
<column name="owner_name" type="VARCHAR(255)"/>
<column name="quantity" type="BIGINT(19)"/>
<column name="ccy_code" type="VARCHAR(3)"/>
</createTable>
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="CONSTRAINT_D"
tableName="cash_states_v2"/>
<createIndex indexName="ccy_code_idx2" tableName="cash_states_v2">
<column name="ccy_code"/>
</createIndex>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,27 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1512743551377-2">
<createTable tableName="cash_states_v3">
<column name="output_index" type="INT(10)">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="ccy_code" type="VARCHAR(3)"/>
<column name="issuer_name" type="VARCHAR(255)"/>
<column name="issuer_ref" type="VARBINARY(512)"/>
<column name="owner_name" type="VARCHAR(255)"/>
<column name="pennies" type="BIGINT(19)"/>
</createTable>
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="CONSTRAINT_DC"
tableName="cash_states_v3"/>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,29 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1511451595465-3">
<createTable tableName="cp_states_v1">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="ccy_code" type="VARCHAR(3)"/>
<column name="face_value" type="BIGINT"/>
<column name="face_value_issuer_key_hash" type="VARCHAR(130)"/>
<column name="face_value_issuer_ref" type="varbinary(512)"/>
<column name="issuance_key_hash" type="VARCHAR(130)"/>
<column name="issuance_ref" type="varbinary(255)"/>
<column name="maturity_instant" type="timestamp"/>
<column name="owner_key_hash" type="VARCHAR(130)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-29">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="cp_states_v1_pkey"
tableName="cp_states_v1"/>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,32 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1512743551377-4">
<createTable tableName="cp_states_v2">
<column name="output_index" type="INT(10)">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="issuer_name" type="VARCHAR(255)"/>
<column name="issuer_ref" type="VARBINARY(512)"/>
<column name="owner_name" type="VARCHAR(255)"/>
<column name="quantity" type="BIGINT(19)"/>
<column name="ccy_code" type="VARCHAR(3)"/>
<column name="face_value_issuer_key_hash" type="VARCHAR(130)"/>
<column name="face_value_issuer_ref" type="VARBINARY(512)"/>
<column name="maturity_instant" type="TIMESTAMP"/>
</createTable>
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="CONSTRAINT_5"
tableName="cp_states_v2"/>
<createIndex indexName="ccy_code_index2" tableName="cp_states_v2">
<column name="ccy_code"/>
</createIndex>
</changeSet>
</databaseChangeLog>

View File

@ -190,4 +190,4 @@ private fun makeTestDataSourceProperties(): Properties {
return props
}
internal fun makeNotInitialisingTestDatabaseProperties() = DatabaseConfig(initialiseSchema = false)
internal fun makeNotInitialisingTestDatabaseProperties() = DatabaseConfig(runMigration = false)

View File

@ -7,6 +7,7 @@ import net.corda.core.schemas.MappedSchema
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.DatabaseTransaction
import net.corda.nodeapi.internal.persistence.SchemaMigration
import java.util.*
import javax.persistence.LockModeType
import javax.persistence.criteria.CriteriaBuilder
@ -35,7 +36,13 @@ fun configureDatabase(dataSourceProperties: Properties,
databaseConfig: DatabaseConfig = DatabaseConfig()): CordaPersistence {
val config = HikariConfig(dataSourceProperties)
val dataSource = HikariDataSource(config)
return CordaPersistence(dataSource, databaseConfig, setOf(NetworkManagementSchemaServices.SchemaV1), emptyList())
val schemas = setOf(NetworkManagementSchemaServices.SchemaV1)
if (databaseConfig.runMigration) {
SchemaMigration(schemas, dataSource).runMigration()
}
return CordaPersistence(dataSource, databaseConfig, schemas, emptyList())
}
sealed class NetworkManagementSchemaServices {
@ -45,5 +52,7 @@ sealed class NetworkManagementSchemaServices {
CertificateDataEntity::class.java,
NodeInfoEntity::class.java,
NetworkParametersEntity::class.java,
NetworkMapEntity::class.java))
NetworkMapEntity::class.java)) {
override val migrationResource = "network-manager.changelog-master"
}
}

View File

@ -0,0 +1,176 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1513267683777-1">
<createSequence sequenceName="HIBERNATE_SEQUENCE"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-2">
<createTable tableName="certificatesigningrequestentity_modifiedby">
<column name="certificatesigningrequestentity_request_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="modified_by" type="VARCHAR(512)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-3">
<createTable tableName="certificatesigningrequestentity_modifiedby_aud">
<column name="REV" type="INT(10)">
<constraints nullable="false"/>
</column>
<column name="certificatesigningrequestentity_request_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="modified_by" type="VARCHAR(512)">
<constraints nullable="false"/>
</column>
<column name="revtype" type="TINYINT(3)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-4">
<createTable tableName="certificate_data">
<column name="ID" type="BIGINT(19)">
<constraints nullable="false"/>
</column>
<column name="certificate_path_bytes" type="BLOB"/>
<column name="certificate_status" type="INT(10)"/>
<column name="public_key_hash" type="VARCHAR(64)"/>
<column name="certificate_signing_request" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-5">
<createTable tableName="certificate_signing_request">
<column name="request_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="legal_name" type="VARCHAR(256)">
<constraints nullable="false"/>
</column>
<column name="modified_at" type="TIMESTAMP">
<constraints nullable="false"/>
</column>
<column name="remark" type="VARCHAR(256)"/>
<column name="request_bytes" type="BLOB">
<constraints nullable="false"/>
</column>
<column name="status" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-6">
<createTable tableName="certificate_signing_request_aud">
<column name="request_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="rev" type="INT(10)">
<constraints nullable="false"/>
</column>
<column name="revtype" type="TINYINT(3)"/>
<column name="modified_at" type="TIMESTAMP"/>
<column name="remark" type="VARCHAR(256)"/>
<column name="status" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-7">
<createTable tableName="network_map">
<column name="version" type="BIGINT(19)">
<constraints nullable="false"/>
</column>
<column name="certificate" type="BLOB"/>
<column name="serialized_network_map" type="BLOB"/>
<column name="signature" type="BLOB"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-8">
<createTable tableName="network_parameters">
<column name="version" type="BIGINT(19)">
<constraints nullable="false"/>
</column>
<column name="bytes" type="BLOB"/>
<column name="hash" type="VARCHAR(64)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-9">
<createTable tableName="node_info">
<column name="node_info_hash" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="node_info_bytes" type="BLOB"/>
<column name="signature_bytes" type="BLOB"/>
<column name="signature_public_key_algorithm" type="CLOB"/>
<column name="signature_public_key_bytes" type="BLOB"/>
<column name="certificate_signing_request" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-10">
<createTable tableName="revinfo">
<column autoIncrement="true" name="rev" type="INT(10)">
<constraints primaryKey="true" primaryKeyName="CONSTRAINT_6"/>
</column>
<column name="revtstmp" type="BIGINT(19)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-11">
<addPrimaryKey columnNames="version" constraintName="CONSTRAINT_3" tableName="network_parameters"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-12">
<addPrimaryKey columnNames="id" constraintName="CONSTRAINT_7" tableName="certificate_data"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-13">
<addPrimaryKey columnNames="rev, certificatesigningrequestentity_request_id, modified_by" constraintName="CONSTRAINT_B" tableName="certificatesigningrequestentity_modifiedby_aud"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-14">
<addPrimaryKey columnNames="request_id, rev" constraintName="CONSTRAINT_C" tableName="certificate_signing_request_aud"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-15">
<addPrimaryKey columnNames="node_info_hash" constraintName="CONSTRAINT_C3" tableName="node_info"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-16">
<addPrimaryKey columnNames="version" constraintName="CONSTRAINT_CB" tableName="network_map"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-17">
<addPrimaryKey columnNames="request_id" constraintName="CONSTRAINT_D" tableName="certificate_signing_request"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-18">
<addUniqueConstraint columnNames="hash" constraintName="UK_3XJ82Q6C0LT4D7XV085CUUX4Q" tableName="network_parameters"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-19">
<addUniqueConstraint columnNames="certificate_signing_request" constraintName="UK_4MJ3D7DDYMYV6OA2284VWDFHV" tableName="certificate_data"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-20">
<addUniqueConstraint columnNames="certificate_signing_request" constraintName="UK_P37OS0TPLQ2ER2TM9JSDTF1CL" tableName="node_info"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-21">
<createIndex indexName="FK5G5CAGCRX7SIU8LWTAVIRUNXD_INDEX_C" tableName="certificate_signing_request_aud">
<column name="rev"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-22">
<createIndex indexName="FKLFW2KLKDPLYDROVIBVEOMF9PU_INDEX_C" tableName="certificatesigningrequestentity_modifiedby">
<column name="certificatesigningrequestentity_request_id"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-23">
<createIndex indexName="IDX_PUB_KEY_HASH" tableName="certificate_data">
<column name="public_key_hash"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-24">
<addForeignKeyConstraint baseColumnNames="rev" baseTableName="certificate_signing_request_aud" constraintName="FK5G5CAGCRX7SIU8LWTAVIRUNXD" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="rev" referencedTableName="revinfo"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-25">
<addForeignKeyConstraint baseColumnNames="rev" baseTableName="certificatesigningrequestentity_modifiedby_aud" constraintName="FKCNMAJ1J6TO8D5GBY6N1Q3CK9C" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="rev" referencedTableName="revinfo"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-26">
<addForeignKeyConstraint baseColumnNames="certificatesigningrequestentity_request_id" baseTableName="certificatesigningrequestentity_modifiedby" constraintName="FKLFW2KLKDPLYDROVIBVEOMF9PU" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="request_id" referencedTableName="certificate_signing_request"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-27">
<addForeignKeyConstraint baseColumnNames="certificate_signing_request" baseTableName="certificate_data" constraintName="FKLQK11Q68B23W062SH0CLNQKLY" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="request_id" referencedTableName="certificate_signing_request"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1513267683777-28">
<addForeignKeyConstraint baseColumnNames="certificate_signing_request" baseTableName="node_info" constraintName="FKOLO0DB56L1GS6AAY86TBNIXRH" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="request_id" referencedTableName="certificate_signing_request"/>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd" >
<include file="migration/network-manager.changelog-init.xml"/>
</databaseChangeLog>

View File

@ -34,6 +34,9 @@ dependencies {
// For AMQP serialisation.
compile "org.apache.qpid:proton-j:0.21.0"
// For db migration
compile "org.liquibase:liquibase-core:$liquibase_version"
// Unit testing helpers.
testCompile "junit:junit:$junit_version"
testCompile "org.assertj:assertj-core:$assertj_version"

View File

@ -18,8 +18,7 @@ const val NODE_DATABASE_PREFIX = "node_"
// This class forms part of the node config and so any changes to it must be handled with care
data class DatabaseConfig(
val initialiseSchema: Boolean = true,
val serverNameTablePrefix: String = "",
val runMigration: Boolean = true,
val transactionIsolationLevel: TransactionIsolationLevel = TransactionIsolationLevel.REPEATABLE_READ,
val schema: String? = null,
val exportHibernateJMXStatistics: Boolean = false
@ -47,6 +46,7 @@ class CordaPersistence(
) : Closeable {
val defaultIsolationLevel = databaseConfig.transactionIsolationLevel
val hibernateConfig: HibernateConfiguration by lazy {
transaction {
HibernateConfiguration(schemas, databaseConfig, attributeConverters)
}

View File

@ -47,25 +47,17 @@ class HibernateConfiguration(
logger.info("Creating session factory for schemas: $schemas")
val serviceRegistry = BootstrapServiceRegistryBuilder().build()
val metadataSources = MetadataSources(serviceRegistry)
// We set a connection provider as the auto schema generation requires it. The auto schema generation will not
// necessarily remain and would likely be replaced by something like Liquibase. For now it is very convenient though.
// TODO: replace auto schema generation as it isn't intended for production use, according to Hibernate docs.
val config = Configuration(metadataSources).setProperty("hibernate.connection.provider_class", NodeDatabaseConnectionProvider::class.java.name)
.setProperty("hibernate.hbm2ddl.auto", if (databaseConfig.initialiseSchema) "update" else "validate")
.setProperty("hibernate.format_sql", "true")
.setProperty("hibernate.connection.isolation", databaseConfig.transactionIsolationLevel.jdbcValue.toString())
if (databaseConfig.schema != null) {
// This property helps 'hibernate.hbm2ddl.auto' to work properly when many schemas have similar table names.
config.setProperty("hibernate.default_schema", databaseConfig.schema)
}
val config = Configuration(metadataSources).setProperty("hibernate.connection.provider_class", NodeDatabaseConnectionProvider::class.java.name)
.setProperty("hibernate.hbm2ddl.auto", "validate")
.setProperty("hibernate.connection.isolation", databaseConfig.transactionIsolationLevel.jdbcValue.toString())
schemas.forEach { schema ->
// TODO: require mechanism to set schemaOptions (databaseSchema, tablePrefix) which are not global to session
schema.mappedTypes.forEach { config.addAnnotatedClass(it) }
}
val sessionFactory = buildSessionFactory(config, metadataSources, databaseConfig.serverNameTablePrefix)
val sessionFactory = buildSessionFactory(config, metadataSources)
logger.info("Created session factory for schemas: $schemas")
// export Hibernate JMX statistics
@ -92,15 +84,9 @@ class HibernateConfiguration(
}
}
private fun buildSessionFactory(config: Configuration, metadataSources: MetadataSources, tablePrefix: String): SessionFactory {
private fun buildSessionFactory(config: Configuration, metadataSources: MetadataSources): SessionFactory {
config.standardServiceRegistryBuilder.applySettings(config.properties)
val metadata = metadataSources.getMetadataBuilder(config.standardServiceRegistryBuilder.build()).run {
applyPhysicalNamingStrategy(object : PhysicalNamingStrategyStandardImpl() {
override fun toPhysicalTableName(name: Identifier?, context: JdbcEnvironment?): Identifier {
val default = super.toPhysicalTableName(name, context)
return Identifier.toIdentifier(tablePrefix + default.text, default.isQuoted)
}
})
// register custom converters
attributeConverters.forEach { applyAttributeConverter(it) }
// Register a tweaked version of `org.hibernate.type.MaterializedBlobType` that truncates logged messages.

View File

@ -0,0 +1,84 @@
package net.corda.nodeapi.internal.persistence
import com.fasterxml.jackson.databind.ObjectMapper
import liquibase.Contexts
import liquibase.Liquibase
import liquibase.database.Database
import liquibase.database.DatabaseFactory
import liquibase.database.core.MSSQLDatabase
import liquibase.database.jvm.JdbcConnection
import liquibase.resource.ClassLoaderResourceAccessor
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.getMigrationResource
import java.io.*
import javax.sql.DataSource
private const val MIGRATION_PREFIX = "migration"
class SchemaMigration(val schemas: Set<MappedSchema>, val dataSource: DataSource) {
fun generateMigrationScript(outputFile: File) = doRunMigration(PrintWriter(outputFile))
fun runMigration() = doRunMigration()
private fun doRunMigration(outputWriter: Writer? = null) {
// virtual file name of the changelog that includes all schemas
val dynamicInclude = "master.changelog.json"
dataSource.connection.use { connection ->
//create a resourse accessor that aggregates the changelogs included in the schemas into one dynamic stream
val customResourceAccessor = object : ClassLoaderResourceAccessor() {
override fun getResourcesAsStream(path: String): Set<InputStream> {
if (path == dynamicInclude) {
//collect all changelog file referenced in the included schemas
val changelogList = schemas.map { mappedSchema ->
getMigrationResource(mappedSchema).let {
"${MIGRATION_PREFIX}/${it}.xml"
}
}
//create a map in liquibase format including all migration files
val includeAllFiles = mapOf("databaseChangeLog" to changelogList.map { file -> mapOf("include" to mapOf("file" to file)) })
// transform it to json
val includeAllFilesJson = ObjectMapper().writeValueAsBytes(includeAllFiles)
//return the json as a stream
return setOf(ByteArrayInputStream(includeAllFilesJson))
}
return super.getResourcesAsStream(path)?.take(1)?.toSet() ?: emptySet()
}
}
val liquibase = Liquibase(dynamicInclude, customResourceAccessor, getLiquibaseDatabase(JdbcConnection(connection)))
if (outputWriter != null) {
liquibase.update(Contexts(), outputWriter)
} else {
liquibase.update(Contexts())
}
}
}
private fun getLiquibaseDatabase(conn: JdbcConnection): Database {
// the standard MSSQLDatabase in liquibase does not support sequences for Ms Azure
// this class just overrides that behaviour
class AzureDatabase(conn: JdbcConnection) : MSSQLDatabase() {
init {
this.connection = conn
}
override fun getShortName(): String = "azure"
override fun supportsSequences(): Boolean = true
}
val liquibaseDbImplementation = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(conn)
return if (liquibaseDbImplementation is MSSQLDatabase) AzureDatabase(conn) else liquibaseDbImplementation
}
}

View File

@ -11,6 +11,7 @@ import net.corda.core.utilities.getOrThrow
import net.corda.finance.POUNDS
import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
import net.corda.finance.schemas.CashSchemaV1
import net.corda.node.services.Permissions.Companion.invokeRpc
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.nodeapi.internal.config.User
@ -45,7 +46,7 @@ class DistributedServiceTests : IntegrationTest() {
)
driver(
extraCordappPackagesToScan = listOf("net.corda.finance.contracts"),
extraCordappPackagesToScan = listOf("net.corda.finance.contracts", "net.corda.finance.schemas"),
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = listOf(testUser), cluster = ClusterSpec.Raft(clusterSize = 3))))
{
alice = startNode(providedName = ALICE_NAME, rpcUsers = listOf(testUser)).getOrThrow()

View File

@ -138,6 +138,8 @@ object MessageSchemaV1 : MappedSchema(
version = 1,
mappedTypes = listOf(PersistentMessage::class.java)) {
override val migrationResource = "message-schema.changelog-init"
@Entity
@Table(name = "messages")
class PersistentMessage(

View File

@ -0,0 +1,20 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1512743551377-1">
<createTable tableName="messages">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="message_by" type="VARCHAR(255)"/>
<column name="message_value" type="VARCHAR(255)"/>
</createTable>
</changeSet>
</databaseChangeLog>

View File

@ -10,6 +10,8 @@ import org.slf4j.event.Level
import java.io.PrintStream
import java.nio.file.Path
import java.nio.file.Paths
import java.text.SimpleDateFormat
import java.util.*
// NOTE: Do not use any logger in this class as args parsing is done before the logger is setup.
class ArgsParser {
@ -34,8 +36,13 @@ class ArgsParser {
private val noLocalShellArg = optionParser.accepts("no-local-shell", "Do not start the embedded shell locally.")
private val isRegistrationArg = optionParser.accepts("initial-registration", "Start initial node registration with Corda network to obtain certificate from the permissioning server.")
private val isVersionArg = optionParser.accepts("version", "Print the version and exit")
private val justRunDbMigrationArg = optionParser.accepts("just-run-db-migration",
"This will only run the db migration. It will not start the node!")
private val justGenerateNodeInfoArg = optionParser.accepts("just-generate-node-info",
"Perform the node start-up task necessary to generate its nodeInfo, save it to disk, then quit")
private val justGenerateDatabaseMigrationArg = optionParser
.accepts("just-generate-database-migration", "Generate the database migration in the specified output file, and then quit.")
.withOptionalArg()
private val bootstrapRaftClusterArg = optionParser.accepts("bootstrap-raft-cluster", "Bootstraps Raft cluster. The node forms a single node cluster (ignoring otherwise configured peer addresses), acting as a seed for other nodes to join the cluster.")
private val helpArg = optionParser.accepts("help").forHelp()
@ -54,9 +61,14 @@ class ArgsParser {
val noLocalShell = optionSet.has(noLocalShellArg)
val sshdServer = optionSet.has(sshdServerArg)
val justGenerateNodeInfo = optionSet.has(justGenerateNodeInfoArg)
val justRunDbMigration = optionSet.has(justRunDbMigrationArg)
val generateDatabaseMigrationToFile = if (optionSet.has(justGenerateDatabaseMigrationArg))
Pair(true, optionSet.valueOf(justGenerateDatabaseMigrationArg) ?: "migration${SimpleDateFormat("yyyyMMddHHmmss").format(Date())}.sql")
else
Pair(false, null)
val bootstrapRaftCluster = optionSet.has(bootstrapRaftClusterArg)
return CmdLineOptions(baseDirectory, configFile, help, loggingLevel, logToConsole, isRegistration, isVersion,
noLocalShell, sshdServer, justGenerateNodeInfo, bootstrapRaftCluster)
noLocalShell, sshdServer, justGenerateNodeInfo, justRunDbMigration, generateDatabaseMigrationToFile, bootstrapRaftCluster)
}
fun printHelp(sink: PrintStream) = optionParser.printHelpOn(sink)
@ -72,6 +84,8 @@ data class CmdLineOptions(val baseDirectory: Path,
val noLocalShell: Boolean,
val sshdServer: Boolean,
val justGenerateNodeInfo: Boolean,
val justRunDbMigration: Boolean,
val generateDatabaseMigrationToFile: Pair<Boolean, String?>,
val bootstrapRaftCluster: Boolean) {
fun loadConfig(): NodeConfiguration {
val config = ConfigHelper.loadConfig(baseDirectory, configFile).parseAsNodeConfiguration()

View File

@ -59,6 +59,7 @@ import net.corda.node.services.vault.VaultSoftLockManager
import net.corda.node.shell.InteractiveShell
import net.corda.node.utilities.AffinityExecutor
import net.corda.nodeapi.internal.NetworkParameters
import net.corda.nodeapi.internal.persistence.SchemaMigration
import net.corda.nodeapi.internal.crypto.*
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
@ -68,6 +69,7 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry
import org.slf4j.Logger
import rx.Observable
import rx.Scheduler
import java.io.File
import java.io.IOException
import java.lang.management.ManagementFactory
import java.lang.reflect.InvocationTargetException
@ -195,6 +197,18 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
}
}
fun generateDatabaseSchema(outputFile: String) {
HikariDataSource(HikariConfig(configuration.dataSourceProperties)).use { dataSource ->
SchemaMigration(cordappLoader.cordappSchemas, dataSource).generateMigrationScript(File(outputFile))
}
}
fun runDbMigration() {
HikariDataSource(HikariConfig(configuration.dataSourceProperties)).use { dataSource ->
SchemaMigration(cordappLoader.cordappSchemas, dataSource).runMigration()
}
}
open fun start(): StartedNode<AbstractNode> {
check(started == null) { "Node has already been started" }
log.info("Node starting up ...")
@ -829,6 +843,12 @@ fun configureDatabase(dataSourceProperties: Properties,
JavaTypeDescriptorRegistry.INSTANCE.addDescriptor(AbstractPartyDescriptor(identityService))
val config = HikariConfig(dataSourceProperties)
val dataSource = HikariDataSource(config)
val attributeConverters = listOf(AbstractPartyToX500NameAsStringConverter(identityService))
if(databaseConfig.runMigration){
SchemaMigration(schemaService.schemaOptions.keys, dataSource).runMigration()
}
return CordaPersistence(dataSource, databaseConfig, schemaService.schemaOptions.keys, attributeConverters)
}

View File

@ -120,6 +120,14 @@ open class NodeStartup(val args: Array<String>) {
node.generateNodeInfo()
return
}
if (cmdlineOptions.justRunDbMigration) {
node.runDbMigration()
return
}
if (cmdlineOptions.generateDatabaseMigrationToFile.first) {
node.generateDatabaseSchema(cmdlineOptions.generateDatabaseMigrationToFile.second!!)
return
}
val startedNode = node.start()
Node.printBasicNodeInfo("Loaded CorDapps", startedNode.services.cordappProvider.cordapps.joinToString { it.name })
startedNode.internals.nodeReadyFuture.thenMatch({

View File

@ -120,7 +120,7 @@ data class NodeConfigurationImpl(
// TODO See TODO above. Rename this to nodeInfoPollingFrequency and make it of type Duration
override val additionalNodeInfoPollingFrequencyMsec: Long = 5.seconds.toMillis(),
override val sshd: SSHDConfiguration? = null,
override val database: DatabaseConfig = DatabaseConfig(initialiseSchema = devMode, exportHibernateJMXStatistics = devMode)
override val database: DatabaseConfig = DatabaseConfig(exportHibernateJMXStatistics = devMode)
) : NodeConfiguration {
override val exportJMXto: String get() = "http"

View File

@ -51,7 +51,9 @@ class NodeSchemaService(extraSchemas: Set<MappedSchema> = emptySet()) : SchemaSe
PersistentIdentityService.PersistentIdentityNames::class.java,
ContractUpgradeServiceImpl.DBContractUpgrade::class.java,
RunOnceService.MutualExclusion::class.java
))
)){
override val migrationResource = "node-services.changelog-master"
}
// Required schemas are those used by internal Corda services
// For example, cash is used by the vault for coin selection (but will be extracted as a standalone CorDapp in future)

View File

@ -27,6 +27,9 @@ object VaultSchema
@CordaSerializable
object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, version = 1,
mappedTypes = listOf(VaultStates::class.java, VaultLinearStates::class.java, VaultFungibleStates::class.java, VaultTxnNote::class.java)) {
override val migrationResource = "vault-schema.changelog-master"
@Entity
@Table(name = "vault_states",
indexes = arrayOf(Index(name = "state_status_idx", columnList = "state_status"),

View File

@ -0,0 +1,29 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1511451595465-1" dbms="mssql">
<createSequence sequenceName="hibernate_sequence" minValue="1"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-1.2" dbms="azure">
<createSequence sequenceName="hibernate_sequence" minValue="1"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-1.1" dbms="h2">
<createSequence sequenceName="hibernate_sequence"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="create state_participants table">
<createTable tableName="state_participants">
<column name="output_index" type="INT(10)">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="participants" type="VARCHAR(255)"/>
</createTable>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,9 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<include file="migration/common.changelog-init.xml"/>
</databaseChangeLog>

View File

@ -0,0 +1,72 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1511451595465-4">
<createTable tableName="node_link_nodeinfo_party">
<column name="node_info_id" type="INT">
<constraints nullable="false"/>
</column>
<column name="party_name" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-10">
<createTable tableName="node_info_hosts">
<column name="host" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="port" type="INT">
<constraints nullable="false"/>
</column>
<column name="node_info_id" type="INT"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-11">
<createTable tableName="node_info_party_cert">
<column name="party_name" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="ismain" type="BOOLEAN">
<constraints nullable="false"/>
</column>
<column name="owning_key_hash" type="VARCHAR(130)"/>
<column name="party_cert_binary" type="blob"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-12">
<createTable tableName="node_infos">
<column name="node_info_id" type="INT">
<constraints nullable="false"/>
</column>
<column name="node_info_hash" type="VARCHAR(64)"/>
<column name="platform_version" type="INT"/>
<column name="serial" type="BIGINT"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-35">
<addPrimaryKey columnNames="host, port" constraintName="node_info_hosts_pkey" tableName="node_info_hosts"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-36">
<addPrimaryKey columnNames="party_name" constraintName="node_info_party_cert_pkey"
tableName="node_info_party_cert"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-37">
<addPrimaryKey columnNames="node_info_id" constraintName="node_infos_pkey" tableName="node_infos"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-62">
<addForeignKeyConstraint baseColumnNames="node_info_id" baseTableName="node_link_nodeinfo_party"
constraintName="fk544l9wsec35ph7hxrtwfd2lws" deferrable="false"
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="node_info_id" referencedTableName="node_infos"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-63">
<addForeignKeyConstraint baseColumnNames="node_info_id" baseTableName="node_info_hosts"
constraintName="fk5ie46htdrkftmwe6rpwrnp0mp" deferrable="false"
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="node_info_id" referencedTableName="node_infos"/>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,9 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<include file="migration/node-info.changelog-init.xml"/>
</databaseChangeLog>

View File

@ -0,0 +1,213 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1511451595465-5">
<createTable tableName="node_attachments">
<column name="att_id" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="content" type="blob"/>
<column name="filename" type="VARCHAR(255)"/>
<column name="insertion_date" type="timestamp">
<constraints nullable="false"/>
</column>
<column name="uploader" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-6">
<createTable tableName="node_bft_committed_states">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="consuming_input_index" type="INT"/>
<column name="consuming_transaction_id" type="VARCHAR(255)"/>
<column name="requesting_party_name" type="VARCHAR(255)"/>
<column name="requesting_party_key" type="varbinary(255)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-7">
<createTable tableName="node_checkpoints">
<column name="checkpoint_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="checkpoint_value" type="blob"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-8">
<createTable tableName="node_contract_upgrades">
<column name="state_ref" type="VARCHAR(96)">
<constraints nullable="false"/>
</column>
<column name="contract_class_name" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-9">
<createTable tableName="node_identities">
<column name="pk_hash" type="VARCHAR(130)">
<constraints nullable="false"/>
</column>
<column name="identity_value" type="blob"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-13">
<createTable tableName="node_message_ids">
<column name="message_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="insertion_time" type="timestamp"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-14">
<createTable tableName="node_message_retry">
<column name="message_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="message" type="blob"/>
<column name="recipients" type="blob"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-15">
<createTable tableName="node_named_identities">
<column name="name" type="VARCHAR(128)">
<constraints nullable="false"/>
</column>
<column name="pk_hash" type="VARCHAR(130)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-16">
<createTable tableName="node_notary_commit_log">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="consuming_input_index" type="INT"/>
<column name="consuming_transaction_id" type="VARCHAR(255)"/>
<column name="requesting_party_name" type="VARCHAR(255)"/>
<column name="requesting_party_key" type="varbinary(255)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-17">
<createTable tableName="node_our_key_pairs">
<column name="public_key_hash" type="VARCHAR(130)">
<constraints nullable="false"/>
</column>
<column name="private_key" type="blob"/>
<column name="public_key" type="blob"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-18">
<createTable tableName="node_raft_committed_states">
<column name="id" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="state_index" type="BIGINT"/>
<column name="state_value" type="blob"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-19">
<createTable tableName="node_scheduled_states">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="scheduled_at" type="timestamp">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-20">
<createTable tableName="node_transaction_mappings">
<column name="tx_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="state_machine_run_id" type="VARCHAR(36)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-21">
<createTable tableName="node_transactions">
<column name="tx_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="transaction_value" type="blob"/>
</createTable>
</changeSet>
<changeSet author="tudormalene" id="create mutual exclusion">
<createTable tableName="node_mutual_exclusion">
<column name="mutual_exclusion_id" type="CHAR(255)">
<constraints nullable="false"/>
</column>
<column name="MACHINE_NAME" type="VARCHAR(255)"/>
<column name="PID" type="VARCHAR(255)"/>
<column name="MUTUAL_EXCLUSION_TIMESTAMP" type="timestamp"/>
</createTable>
<addPrimaryKey columnNames="mutual_exclusion_id" constraintName="node_mutual_exclusion_pkey" tableName="node_mutual_exclusion"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-30">
<addPrimaryKey columnNames="att_id" constraintName="node_attachments_pkey" tableName="node_attachments"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-31">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="node_bft_committed_states_pkey"
tableName="node_bft_committed_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-32">
<addPrimaryKey columnNames="checkpoint_id" constraintName="node_checkpoints_pkey" tableName="node_checkpoints"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-33">
<addPrimaryKey columnNames="state_ref" constraintName="node_contract_upgrades_pkey"
tableName="node_contract_upgrades"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-34">
<addPrimaryKey columnNames="pk_hash" constraintName="node_identities_pkey" tableName="node_identities"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-38">
<addPrimaryKey columnNames="message_id" constraintName="node_message_ids_pkey" tableName="node_message_ids"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-39">
<addPrimaryKey columnNames="message_id" constraintName="node_message_retry_pkey"
tableName="node_message_retry"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-40">
<addPrimaryKey columnNames="name" constraintName="node_named_identities_pkey"
tableName="node_named_identities"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-41">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="node_notary_commit_log_pkey"
tableName="node_notary_commit_log"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-42">
<addPrimaryKey columnNames="public_key_hash" constraintName="node_our_key_pairs_pkey"
tableName="node_our_key_pairs"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-43">
<addPrimaryKey columnNames="id" constraintName="node_raft_committed_states_pkey"
tableName="node_raft_committed_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-44">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="node_scheduled_states_pkey"
tableName="node_scheduled_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-45">
<addPrimaryKey columnNames="tx_id" constraintName="node_transaction_mappings_pkey"
tableName="node_transaction_mappings"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-46">
<addPrimaryKey columnNames="tx_id" constraintName="node_transactions_pkey" tableName="node_transactions"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-61">
<addForeignKeyConstraint baseColumnNames="party_name" baseTableName="node_link_nodeinfo_party"
constraintName="fk1ua3h6nwwfji0mn23c5d1xx8e" deferrable="false"
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="party_name" referencedTableName="node_info_party_cert"/>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,9 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<include file="migration/node-services.changelog-init.xml"/>
</databaseChangeLog>

View File

@ -0,0 +1,140 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1511451595465-22">
<createTable tableName="vault_fungible_states">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="issuer_name" type="VARCHAR(255)"/>
<column name="issuer_ref" type="varbinary(512)"/>
<column name="owner_name" type="VARCHAR(255)"/>
<column name="quantity" type="BIGINT"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-23">
<createTable tableName="vault_fungible_states_parts">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="participants" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-24">
<createTable tableName="vault_linear_states">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="external_id" type="VARCHAR(255)"/>
<column name="uuid" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-25">
<createTable tableName="vault_linear_states_parts">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="participants" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-26">
<createTable tableName="vault_states">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="consumed_timestamp" type="timestamp"/>
<column name="contract_state_class_name" type="VARCHAR(255)"/>
<column name="lock_id" type="VARCHAR(255)"/>
<column name="lock_timestamp" type="timestamp"/>
<column name="notary_name" type="VARCHAR(255)"/>
<column name="recorded_timestamp" type="timestamp"/>
<column name="state_status" type="INT"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-27">
<createTable tableName="vault_transaction_notes">
<column name="seq_no" type="INT">
<constraints nullable="false"/>
</column>
<column name="note" type="VARCHAR(255)"/>
<column name="transaction_id" type="VARCHAR(64)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-47">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="vault_fungible_states_pkey"
tableName="vault_fungible_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-48">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="vault_linear_states_pkey"
tableName="vault_linear_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-49">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="vault_states_pkey"
tableName="vault_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-50">
<addPrimaryKey columnNames="seq_no" constraintName="vault_transaction_notes_pkey"
tableName="vault_transaction_notes"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-53">
<createIndex indexName="external_id_index" tableName="vault_linear_states">
<column name="external_id"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-55">
<createIndex indexName="lock_id_idx" tableName="vault_states">
<column name="lock_id"/>
<column name="state_status"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-58">
<createIndex indexName="state_status_idx" tableName="vault_states">
<column name="state_status"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-59">
<createIndex indexName="transaction_id_index" tableName="vault_transaction_notes">
<column name="transaction_id"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-60">
<createIndex indexName="uuid_index" tableName="vault_linear_states">
<column name="uuid"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-64">
<addForeignKeyConstraint baseColumnNames="output_index,transaction_id"
baseTableName="vault_fungible_states_parts"
constraintName="fkchmfeq1ldqnoq9idv9ogxauqm" deferrable="false"
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="output_index,transaction_id"
referencedTableName="vault_fungible_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-65">
<addForeignKeyConstraint baseColumnNames="output_index,transaction_id" baseTableName="vault_linear_states_parts"
constraintName="fkhafsv733d0bo9j1tg352koq3y" deferrable="false"
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
referencedColumnNames="output_index,transaction_id"
referencedTableName="vault_linear_states"/>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,9 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<include file="migration/vault-schema.changelog-init.xml"/>
</databaseChangeLog>

View File

@ -27,6 +27,7 @@ import net.corda.testing.TestIdentity;
import net.corda.testing.contracts.DummyLinearContract;
import net.corda.testing.contracts.VaultFiller;
import net.corda.testing.node.MockServices;
import net.corda.testing.schemas.DummyLinearStateSchemaV1;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@ -69,7 +70,11 @@ public class VaultQueryJavaTests {
@Before
public void setUp() throws CertificateException, InvalidAlgorithmParameterException {
List<String> cordappPackages = Arrays.asList("net.corda.testing.contracts", "net.corda.finance.contracts.asset", CashSchemaV1.class.getPackage().getName());
List<String> cordappPackages = Arrays.asList(
"net.corda.testing.contracts",
"net.corda.finance.contracts.asset",
CashSchemaV1.class.getPackage().getName(),
DummyLinearStateSchemaV1.class.getPackage().getName());
IdentityServiceInternal identitySvc = makeTestIdentityService(Arrays.asList(MEGA_CORP.getIdentity(), DUMMY_CASH_ISSUER_INFO.getIdentity(), DUMMY_NOTARY.getIdentity()));
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(
Arrays.asList(MEGA_CORP.getKey(), DUMMY_NOTARY.getKey()),

View File

@ -25,7 +25,10 @@ class ArgsParserTest {
noLocalShell = false,
sshdServer = false,
justGenerateNodeInfo = false,
bootstrapRaftCluster = false))
justRunDbMigration = false,
bootstrapRaftCluster = false,
generateDatabaseMigrationToFile = Pair(false, null)
))
}
@Test

View File

@ -76,7 +76,7 @@ class CordaRPCOpsImplTest {
@Before
fun setup() {
mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset"))
mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"))
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
rpc = SecureCordaRPCOps(aliceNode.services, aliceNode.smm, aliceNode.database, aliceNode.services)
CURRENT_RPC_CONTEXT.set(RpcAuthContext(InvocationContext.rpc(testActor()), buildSubject("TEST_USER", emptySet())))

View File

@ -68,7 +68,7 @@ import kotlin.test.assertTrue
@RunWith(Parameterized::class)
class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
companion object {
private val cordappPackages = listOf("net.corda.finance.contracts")
private val cordappPackages = listOf("net.corda.finance.contracts", "net.corda.finance.schemas")
@JvmStatic
@Parameterized.Parameters(name = "Anonymous = {0}")
fun data(): Collection<Boolean> = listOf(true, false)

View File

@ -25,8 +25,8 @@ import net.corda.finance.SWISS_FRANCS
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.asset.DummyFungibleContract
import net.corda.finance.schemas.CashSchemaV1
import net.corda.finance.schemas.SampleCashSchemaV2
import net.corda.finance.schemas.SampleCashSchemaV3
import net.corda.finance.sampleschemas.SampleCashSchemaV2
import net.corda.finance.sampleschemas.SampleCashSchemaV3
import net.corda.finance.utils.sumCash
import net.corda.node.services.schema.HibernateObserver
import net.corda.node.services.schema.NodeSchemaService
@ -40,6 +40,7 @@ import net.corda.testing.*
import net.corda.testing.contracts.*
import net.corda.testing.node.MockServices
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.schemas.DummyDealStateSchemaV1
import net.corda.testing.schemas.DummyLinearStateSchemaV1
import net.corda.testing.schemas.DummyLinearStateSchemaV2
import org.assertj.core.api.Assertions
@ -105,7 +106,7 @@ class HibernateConfigurationTest {
doReturn(it.party).whenever(mock).wellKnownPartyFromX500Name(it.name)
}
}
val schemaService = NodeSchemaService()
val schemaService = NodeSchemaService(extraSchemas = setOf(CashSchemaV1, SampleCashSchemaV2, SampleCashSchemaV3, DummyLinearStateSchemaV1, DummyLinearStateSchemaV2, DummyDealStateSchemaV1 ))
database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService, schemaService)
database.transaction {
hibernateConfig = database.hibernateConfig

View File

@ -8,6 +8,7 @@ import net.corda.core.crypto.SecureHash
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name
import net.corda.core.node.services.Vault
import net.corda.core.schemas.CommonSchemaV1
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState
@ -55,7 +56,9 @@ class HibernateObserverTests {
val testSchema = TestSchema
val rawUpdatesPublisher = PublishSubject.create<Vault.Update<ContractState>>()
val schemaService = object : SchemaService {
override val schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = emptyMap()
override val schemaOptions: Map<MappedSchema, SchemaService.SchemaOptions> = mapOf(
CommonSchemaV1 to SchemaService.SchemaOptions(),
testSchema to SchemaService.SchemaOptions())
override fun selectSchemas(state: ContractState): Iterable<MappedSchema> = setOf(testSchema)

View File

@ -72,8 +72,11 @@ class NodeSchemaServiceTest {
class SchemaFamily
object TestSchema : MappedSchema(SchemaFamily::class.java, 1, setOf(Parent::class.java, Child::class.java)) {
override val migrationResource = "test.changelog-init"
@Entity
@Table(name = "Parents")
@Table(name = "parents")
class Parent : PersistentState() {
@OneToMany(fetch = FetchType.LAZY)
@JoinColumns(JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"), JoinColumn(name = "output_index", referencedColumnName = "output_index"))
@ -84,7 +87,7 @@ object TestSchema : MappedSchema(SchemaFamily::class.java, 1, setOf(Parent::clas
@Suppress("unused")
@Entity
@Table(name = "Children")
@Table(name = "children")
class Child {
@Id
@GeneratedValue

View File

@ -88,7 +88,7 @@ class DistributedImmutableMapTests {
private fun createReplica(myAddress: NetworkHostAndPort, clusterAddress: NetworkHostAndPort? = null): CompletableFuture<Member> {
val storage = Storage.builder().withStorageLevel(StorageLevel.MEMORY).build()
val address = Address(myAddress.host, myAddress.port)
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(serverNameTablePrefix = "PORT_${myAddress.port}_"), rigorousMock())
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
databases.add(database)
val stateMachineFactory = { DistributedImmutableMap(database, RaftUniquenessProvider.Companion::createMap) }

View File

@ -21,7 +21,7 @@ import net.corda.finance.contracts.asset.Cash
import net.corda.finance.schemas.CashSchemaV1
import net.corda.finance.schemas.CashSchemaV1.PersistentCashState
import net.corda.finance.schemas.CommercialPaperSchemaV1
import net.corda.finance.schemas.SampleCashSchemaV3
import net.corda.finance.sampleschemas.SampleCashSchemaV3
import net.corda.node.internal.configureDatabase
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
@ -30,6 +30,7 @@ import net.corda.testing.contracts.*
import net.corda.testing.node.MockServices
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseAndMockServices
import net.corda.testing.node.makeTestIdentityService
import net.corda.testing.schemas.DummyDealStateSchemaV1
import net.corda.testing.schemas.DummyLinearStateSchemaV1
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
@ -91,7 +92,8 @@ open class VaultQueryTests {
"net.corda.testing.contracts",
"net.corda.finance.contracts",
CashSchemaV1::class.packageName,
DummyLinearStateSchemaV1::class.packageName)
DummyLinearStateSchemaV1::class.packageName,
DummyDealStateSchemaV1::class.packageName)
private lateinit var services: MockServices
private lateinit var vaultFiller: VaultFiller
private lateinit var vaultFillerCashNotary: VaultFiller

View File

@ -25,6 +25,7 @@ import net.corda.testing.contracts.*
import net.corda.testing.node.MockServices
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseAndMockServices
import net.corda.testing.node.makeTestIdentityService
import net.corda.testing.schemas.DummyLinearStateSchemaV1
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.After
@ -39,7 +40,8 @@ import kotlin.test.fail
class VaultWithCashTest {
private companion object {
val cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", CashSchemaV1::class.packageName)
private val cordappPackages = listOf(
"net.corda.testing.contracts", "net.corda.finance.contracts.asset", CashSchemaV1::class.packageName, DummyLinearStateSchemaV1::class.packageName)
val BOB = TestIdentity(BOB_NAME, 80).party
val dummyCashIssuer = TestIdentity(CordaX500Name("Snake Oil Issuer", "London", "GB"), 10)
val DUMMY_CASH_ISSUER = dummyCashIssuer.ref(1)

View File

@ -0,0 +1,29 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1512743551377-11">
<createTable tableName="parents">
<column name="output_index" type="INT(10)">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
</createTable>
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="CONSTRAINT_F" tableName="parents"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1512743551377-18">
<createTable tableName="children">
<column name="child_id" type="INT(10)">
<constraints nullable="false"/>
</column>
<column name="output_index" type="INT(10)"/>
<column name="transaction_id" type="VARCHAR(64)"/>
</createTable>
<addPrimaryKey columnNames="child_id" constraintName="CONSTRAINT_9" tableName="children"/>
</changeSet>
</databaseChangeLog>

View File

@ -18,6 +18,7 @@ import net.corda.core.transactions.TransactionBuilder
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
import com.r3.corda.enterprise.perftestcordapp.schemas.CommercialPaperSchemaV1
import com.r3.corda.enterprise.perftestcordapp.utils.sumCashBy
import net.corda.core.crypto.toStringShort
import java.time.Instant
import java.util.*
@ -76,13 +77,13 @@ class CommercialPaper : Contract {
override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) {
is CommercialPaperSchemaV1 -> CommercialPaperSchemaV1.PersistentCommercialPaperState(
issuanceParty = this.issuance.party.owningKey.toBase58String(),
issuancePartyHash = this.issuance.party.owningKey.toStringShort(),
issuanceRef = this.issuance.reference.bytes,
owner = this.owner.owningKey.toBase58String(),
ownerHash = this.owner.owningKey.toStringShort(),
maturity = this.maturityDate,
faceValue = this.faceValue.quantity,
currency = this.faceValue.token.product.currencyCode,
faceValueIssuerParty = this.faceValue.token.issuer.party.owningKey.toBase58String(),
faceValueIssuerPartyHash = this.faceValue.token.issuer.party.owningKey.toStringShort(),
faceValueIssuerRef = this.faceValue.token.issuer.reference.bytes
)
/** Additional schema mappings would be added here (eg. CommercialPaperV2, ...) */

View File

@ -56,9 +56,9 @@ class CashSelectionH2Impl : AbstractCashSelection() {
if (notary != null)
psSelectJoin.setString(++pIndex, notary.name.toString())
if (onlyFromIssuerParties.isNotEmpty())
psSelectJoin.setObject(++pIndex, onlyFromIssuerParties.map { it.owningKey.toStringShort() as Any }.toTypedArray())
psSelectJoin.setObject(++pIndex, onlyFromIssuerParties.map { it.owningKey.toStringShort() as Any}.toTypedArray() )
if (withIssuerRefs.isNotEmpty())
psSelectJoin.setObject(++pIndex, withIssuerRefs.map { it.bytes as Any }.toTypedArray())
psSelectJoin.setObject(++pIndex, withIssuerRefs.map { it.bytes.toHexString() as Any }.toTypedArray())
log.debug { psSelectJoin.toString() }
psSelectJoin.executeQuery().use { rs ->

View File

@ -21,6 +21,8 @@ object CashSchema
*/
@CordaSerializable
object CashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCashState::class.java)) {
override val migrationResource = "cash-pt.changelog-master"
@Entity
@Table(name = "contract_pt_cash_states",
indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"),

View File

@ -1,7 +1,11 @@
package com.r3.corda.enterprise.perftestcordapp.schemas
import net.corda.core.contracts.MAX_ISSUER_REF_SIZE
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import org.hibernate.annotations.Type
import java.time.Instant
import javax.persistence.Column
import javax.persistence.Entity
@ -19,20 +23,23 @@ object CommercialPaperSchema
*/
@CordaSerializable
object CommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCommercialPaperState::class.java)) {
override val migrationResource = "commercial-paper-pt.changelog-master"
@Entity
@Table(name = "cp_pt_states",
indexes = arrayOf(Index(name = "ccy_code_index", columnList = "ccy_code"),
Index(name = "maturity_index", columnList = "maturity_instant"),
Index(name = "face_value_index", columnList = "face_value")))
class PersistentCommercialPaperState(
@Column(name = "issuance_key")
var issuanceParty: String,
@Column(name = "issuance_key_hash", length = MAX_HASH_HEX_SIZE)
var issuancePartyHash: String,
@Column(name = "issuance_ref")
var issuanceRef: ByteArray,
@Column(name = "owner_key")
var owner: String,
@Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE)
var ownerHash: String,
@Column(name = "maturity_instant")
var maturity: Instant,
@ -43,10 +50,11 @@ object CommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSche
@Column(name = "ccy_code", length = 3)
var currency: String,
@Column(name = "face_value_issuer_key")
var faceValueIssuerParty: String,
@Column(name = "face_value_issuer_key_hash", length = MAX_HASH_HEX_SIZE)
var faceValueIssuerPartyHash: String,
@Column(name = "face_value_issuer_ref")
@Column(name = "face_value_issuer_ref", length = MAX_ISSUER_REF_SIZE)
@Type(type = "corda-wrapper-binary")
var faceValueIssuerRef: ByteArray
) : PersistentState()
}

View File

@ -0,0 +1,31 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd" >
<changeSet author="tudormalene (generated)" id="perf test cash">
<createTable tableName="contract_pt_cash_states">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="ccy_code" type="VARCHAR(3)"/>
<column name="issuer_key_hash" type="VARCHAR(130)"/>
<column name="issuer_ref" type="varbinary(512)"/>
<column name="owner_name" type="VARCHAR(255)"/>
<column name="pennies" type="BIGINT"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-28">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="contract_pt_cash_states_pkey" tableName="contract_pt_cash_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-51">
<createIndex indexName="ccy_pt_code_idx" tableName="contract_pt_cash_states">
<column name="ccy_code"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-57">
<createIndex indexName="pennies_pt_idx" tableName="contract_pt_cash_states">
<column name="pennies"/>
</createIndex>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd" >
<include file="migration/cash-pt.changelog-init.xml"/>
</databaseChangeLog>

View File

@ -0,0 +1,39 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1511451595465-3">
<createTable tableName="cp_pt_states">
<column name="output_index" type="INT">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="ccy_code" type="VARCHAR(3)"/>
<column name="face_value" type="BIGINT"/>
<column name="face_value_issuer_key_hash" type="VARCHAR(130)"/>
<column name="face_value_issuer_ref" type="varbinary(512)"/>
<column name="issuance_key_hash" type="VARCHAR(130)"/>
<column name="issuance_ref" type="varbinary(255)"/>
<column name="maturity_instant" type="timestamp"/>
<column name="owner_key_hash" type="VARCHAR(130)"/>
</createTable>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-29">
<addPrimaryKey columnNames="output_index, transaction_id" constraintName="cp_pt_states_pkey" tableName="cp_pt_states"/>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-52">
<createIndex indexName="ccy_cp_pt_code_index" tableName="cp_pt_states">
<column name="ccy_code"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-54">
<createIndex indexName="face_value_cp_pt_index" tableName="cp_pt_states">
<column name="face_value"/>
</createIndex>
</changeSet>
<changeSet author="tudormalene (generated)" id="1511451595465-56">
<createIndex indexName="maturity_cp_pt_index" tableName="cp_pt_states">
<column name="maturity_instant"/>
</createIndex>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<include file="migration/commercial-paper-pt.changelog-init.xml"/>
</databaseChangeLog>

View File

@ -17,7 +17,9 @@ import org.junit.Test
import java.util.Collections.nCopies
class CashSelectionH2Test {
private val mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"))
private val mockNet = MockNetwork(
threadPerNode = true,
cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"))
@After
fun cleanUp() {

View File

@ -133,13 +133,19 @@ class CashTests {
@Before
fun setUp() {
LogHelper.setLevel(NodeVaultService::class)
megaCorpServices = MockServices(listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"), rigorousMock(), MEGA_CORP.name, MEGA_CORP_KEY)
miniCorpServices = MockServices(listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"), rigorousMock<IdentityServiceInternal>().also {
doNothing().whenever(it).justVerifyAndRegisterIdentity(argThat { name == MINI_CORP.name })
}, MINI_CORP.name, MINI_CORP_KEY)
val notaryServices = MockServices(listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"), rigorousMock(), DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
megaCorpServices = MockServices(
listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"),
rigorousMock(), MEGA_CORP.name, MEGA_CORP_KEY)
miniCorpServices = MockServices(
listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"),
rigorousMock<IdentityServiceInternal>().also {
doNothing().whenever(it).justVerifyAndRegisterIdentity(argThat { name == MINI_CORP.name })
}, MINI_CORP.name, MINI_CORP_KEY)
val notaryServices = MockServices(
listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"),
rigorousMock(), DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
val databaseAndServices = makeTestDatabaseAndMockServices(
cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"),
cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"),
initialIdentityName = CordaX500Name(organisation = "Me", locality = "London", country = "GB"),
keys = listOf(generateKeyPair()),
identityService = makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)))
@ -247,9 +253,9 @@ class CashTests {
transaction {
attachment(Cash.PROGRAM_ID)
output(Cash.PROGRAM_ID,
Cash.State(
amount = 1000.DOLLARS `issued by` MINI_CORP.ref(12, 34),
owner = AnonymousParty(ALICE_PUBKEY)))
Cash.State(
amount = 1000.DOLLARS `issued by` MINI_CORP.ref(12, 34),
owner = AnonymousParty(ALICE_PUBKEY)))
command(MINI_CORP_PUBKEY, Cash.Commands.Issue())
this.verifies()
}
@ -432,9 +438,9 @@ class CashTests {
attachment(Cash.PROGRAM_ID)
input(Cash.PROGRAM_ID, inState)
input(Cash.PROGRAM_ID,
inState.copy(
amount = 150.POUNDS `issued by` defaultIssuer,
owner = AnonymousParty(BOB_PUBKEY)))
inState.copy(
amount = 150.POUNDS `issued by` defaultIssuer,
owner = AnonymousParty(BOB_PUBKEY)))
output(Cash.PROGRAM_ID, outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer))
command(ALICE_PUBKEY, Cash.Commands.Move())
this `fails with` "the amounts balance"
@ -851,16 +857,17 @@ class CashTests {
// Double spend.
@Test
fun chainCashDoubleSpendFailsWith() {
val mockService = MockServices(listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"), rigorousMock<IdentityServiceInternal>().also {
val mockService = MockServices(
listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"), rigorousMock<IdentityServiceInternal>().also {
doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY)
}, MEGA_CORP.name, MEGA_CORP_KEY)
mockService.ledger(DUMMY_NOTARY) {
unverifiedTransaction {
attachment(Cash.PROGRAM_ID)
output(Cash.PROGRAM_ID, "MEGA_CORP cash",
Cash.State(
amount = 1000.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
owner = MEGA_CORP))
Cash.State(
amount = 1000.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
owner = MEGA_CORP))
}
transaction {

View File

@ -29,7 +29,7 @@ class CashExitFlowTests {
@Before
fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"))
cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
notary = mockNet.defaultNotaryIdentity

View File

@ -31,7 +31,8 @@ class CashIssueAndPaymentFlowTests {
@Before
fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"))
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
aliceNode = mockNet.createPartyNode(ALICE_NAME)
bankOfCorda = bankOfCordaNode.info.chooseIdentity()

View File

@ -40,7 +40,7 @@ class CashIssueAndPayNoSelectionTests(private val anonymous: Boolean) {
@Before
fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"))
cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
aliceNode = mockNet.createPartyNode(ALICE_NAME)
bankOfCorda = bankOfCordaNode.info.chooseIdentity()

View File

@ -26,7 +26,9 @@ class CashIssueFlowTests {
@Before
fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"))
mockNet = MockNetwork(
servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
notary = mockNet.defaultNotaryIdentity

View File

@ -31,7 +31,9 @@ class CashPaymentFlowTests {
@Before
fun start() {
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset"))
mockNet = MockNetwork(
servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts.asset", "com.r3.corda.enterprise.perftestcordapp.schemas"))
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
aliceNode = mockNet.createPartyNode(ALICE_NAME)
bankOfCorda = bankOfCordaNode.info.chooseIdentity()

View File

@ -79,7 +79,8 @@ internal fun CheckpointStorage.checkpoints(): List<SerializedBytes<Checkpoint>>
@RunWith(Parameterized::class)
class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
companion object {
private val cordappPackages = listOf("com.r3.corda.enterprise.perftestcordapp.contracts")
private val cordappPackages = listOf(
"com.r3.corda.enterprise.perftestcordapp.contracts", "com.r3.corda.enterprise.perftestcordapp.schemas")
@JvmStatic
@Parameterized.Parameters(name = "Anonymous = {0}")
fun data(): Collection<Boolean> = listOf(true, false)

View File

@ -1,2 +1,3 @@
corda.host=localhost:10006
server.port=10007
server.port=10007
liquibase.enabled=false

View File

@ -1,2 +1,3 @@
corda.host=localhost:10009
server.port=10010
server.port=10010
liquibase.enabled=false

View File

@ -1,2 +1,3 @@
corda.host=localhost:10003
server.port=10004
server.port=10004
liquibase.enabled=false

View File

@ -1,2 +1,3 @@
corda.user=user
corda.password=password
corda.password=password
liquibase.enabled=false

View File

@ -8,7 +8,7 @@ import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.test.context.junit4.SpringRunner
@RunWith(SpringRunner::class)
@SpringBootTest(properties = arrayOf("corda.host=localhost:12345", "corda.user=user", "corda.password=password"))
@SpringBootTest(properties = arrayOf("corda.host=localhost:12345", "corda.user=user", "corda.password=password", "liquibase.enabled=false"))
class IrsDemoWebApplicationTests {
@MockBean
lateinit var rpc: CordaRPCOps

View File

@ -426,7 +426,7 @@ class DriverDSLImpl(
providedName = nodeNames[0],
rpcUsers = spec.rpcUsers,
verifierType = spec.verifierType,
customOverrides = notaryConfig(clusterAddress) //TODO discrepancy with OS - check if 'serverNameTablePrefix' can be removed in OS
customOverrides = notaryConfig(clusterAddress)
)
// All other nodes will join the cluster
@ -436,7 +436,7 @@ class DriverDSLImpl(
providedName = it,
rpcUsers = spec.rpcUsers,
verifierType = spec.verifierType,
customOverrides = notaryConfig(nodeAddress, clusterAddress) //TODO discrepancy with OS - check if 'serverNameTablePrefix' can be removed in OS
customOverrides = notaryConfig(nodeAddress, clusterAddress)
)
}

View File

@ -30,6 +30,7 @@ abstract class IntegrationTest {
@JvmStatic
fun globalSetUp() {
if (dbProvider.isNotEmpty()) {
runDbScript(dbProvider,"$testDbScriptDir/db-global-cleanup.sql", databaseSchemas)
runDbScript(dbProvider,"$testDbScriptDir/db-global-setup.sql", databaseSchemas)
}
}

View File

@ -18,6 +18,9 @@ object DummyDealStateSchema
* at the time of writing.
*/
object DummyDealStateSchemaV1 : MappedSchema(schemaFamily = DummyDealStateSchema.javaClass, version = 1, mappedTypes = listOf(PersistentDummyDealState::class.java)) {
override val migrationResource = "dummy-deal.changelog-init"
@Entity
@Table(name = "dummy_deal_states")
class PersistentDummyDealState(

View File

@ -4,6 +4,7 @@ import net.corda.core.contracts.ContractState
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import org.hibernate.annotations.Type
import java.time.Instant
import java.util.*
import javax.persistence.*
@ -18,6 +19,9 @@ object DummyLinearStateSchema
* at the time of writing.
*/
object DummyLinearStateSchemaV1 : MappedSchema(schemaFamily = DummyLinearStateSchema.javaClass, version = 1, mappedTypes = listOf(PersistentDummyLinearState::class.java)) {
override val migrationResource = "dummy-linear-v1.changelog-init"
@Entity
@Table(name = "dummy_linear_states",
indexes = arrayOf(Index(name = "external_id_idx", columnList = "external_id"),
@ -27,6 +31,9 @@ object DummyLinearStateSchemaV1 : MappedSchema(schemaFamily = DummyLinearStateSc
/** X500Name of participant parties **/
@ElementCollection
@CollectionTable(name="state_participants",joinColumns = arrayOf(
JoinColumn(name = "output_index", referencedColumnName = "output_index"),
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")))
var participants: MutableSet<AbstractParty>,
/**
@ -36,6 +43,7 @@ object DummyLinearStateSchemaV1 : MappedSchema(schemaFamily = DummyLinearStateSc
var externalId: String?,
@Column(name = "uuid", nullable = false)
@Type(type = "uuid-char")
var uuid: UUID,
/**

View File

@ -14,6 +14,9 @@ import javax.persistence.Table
*/
object DummyLinearStateSchemaV2 : MappedSchema(schemaFamily = DummyLinearStateSchema.javaClass, version = 2,
mappedTypes = listOf(PersistentDummyLinearState::class.java)) {
override val migrationResource = "dummy-linear-v2.changelog-init"
@Entity
@Table(name = "dummy_linear_states_v2")
class PersistentDummyLinearState(

View File

@ -30,12 +30,7 @@ DROP TABLE IF EXISTS ${schema}.children;
DROP TABLE IF EXISTS ${schema}.parents;
DROP TABLE IF EXISTS ${schema}.contract_cash_states;
DROP TABLE IF EXISTS ${schema}.messages;
DROP TABLE IF EXISTS ${schema}.DummyDealStateSchemaV1$PersistentDummyDealState_participants;
DROP TABLE IF EXISTS ${schema}.DummyLinearStateSchemaV1$PersistentDummyLinearState_participants;
DROP TABLE IF EXISTS ${schema}.DummyLinearStateSchemaV2$PersistentDummyLinearState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCashSchemaV2$PersistentCashState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCashSchemaV3$PersistentCashState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCommercialPaperSchemaV2$PersistentCommercialPaperState_participants;
DROP TABLE IF EXISTS ${schema}.state_participants;
DROP TABLE IF EXISTS ${schema}.cash_states_v2;
DROP TABLE IF EXISTS ${schema}.cash_states_v3;
DROP TABLE IF EXISTS ${schema}.cp_states_v2;
@ -43,6 +38,8 @@ DROP TABLE IF EXISTS ${schema}.dummy_deal_states;
DROP TABLE IF EXISTS ${schema}.dummy_linear_states;
DROP TABLE IF EXISTS ${schema}.dummy_linear_states_v2;
DROP TABLE IF EXISTS ${schema}.node_mutual_exclusion;
DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOG;
DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOGLOCK;
DROP SEQUENCE IF EXISTS ${schema}.hibernate_sequence;
DROP USER IF EXISTS ${schema};
DROP SCHEMA IF EXISTS ${schema};

View File

@ -30,12 +30,7 @@ DROP TABLE IF EXISTS ${schema}.children;
DROP TABLE IF EXISTS ${schema}.parents;
DROP TABLE IF EXISTS ${schema}.contract_cash_states;
DROP TABLE IF EXISTS ${schema}.messages;
DROP TABLE IF EXISTS ${schema}.DummyDealStateSchemaV1$PersistentDummyDealState_participants;
DROP TABLE IF EXISTS ${schema}.DummyLinearStateSchemaV1$PersistentDummyLinearState_participants;
DROP TABLE IF EXISTS ${schema}.DummyLinearStateSchemaV2$PersistentDummyLinearState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCashSchemaV2$PersistentCashState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCashSchemaV3$PersistentCashState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCommercialPaperSchemaV2$PersistentCommercialPaperState_participants;
DROP TABLE IF EXISTS ${schema}.state_participants;
DROP TABLE IF EXISTS ${schema}.cash_states_v2;
DROP TABLE IF EXISTS ${schema}.cash_states_v3;
DROP TABLE IF EXISTS ${schema}.cp_states_v2;
@ -43,4 +38,6 @@ DROP TABLE IF EXISTS ${schema}.dummy_deal_states;
DROP TABLE IF EXISTS ${schema}.dummy_linear_states;
DROP TABLE IF EXISTS ${schema}.dummy_linear_states_v2;
DROP TABLE IF EXISTS ${schema}.node_mutual_exclusion;
DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOG;
DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOGLOCK;
DROP SEQUENCE IF EXISTS ${schema}.hibernate_sequence;

View File

@ -30,12 +30,7 @@ DROP TABLE IF EXISTS ${schema}.children;
DROP TABLE IF EXISTS ${schema}.parents;
DROP TABLE IF EXISTS ${schema}.contract_cash_states;
DROP TABLE IF EXISTS ${schema}.messages;
DROP TABLE IF EXISTS ${schema}.DummyDealStateSchemaV1$PersistentDummyDealState_participants;
DROP TABLE IF EXISTS ${schema}.DummyLinearStateSchemaV1$PersistentDummyLinearState_participants;
DROP TABLE IF EXISTS ${schema}.DummyLinearStateSchemaV2$PersistentDummyLinearState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCashSchemaV2$PersistentCashState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCashSchemaV3$PersistentCashState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCommercialPaperSchemaV2$PersistentCommercialPaperState_participants;
DROP TABLE IF EXISTS ${schema}.state_participants;
DROP TABLE IF EXISTS ${schema}.cash_states_v2;
DROP TABLE IF EXISTS ${schema}.cash_states_v3;
DROP TABLE IF EXISTS ${schema}.cp_states_v2;
@ -44,6 +39,8 @@ DROP TABLE IF EXISTS ${schema}.dummy_linear_states;
DROP TABLE IF EXISTS ${schema}.dummy_linear_states_v2;
DROP TABLE IF EXISTS ${schema}.node_mutual_exclusion;
DROP SEQUENCE IF EXISTS ${schema}.hibernate_sequence;
DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOG;
DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOGLOCK;
DROP USER IF EXISTS ${schema};
DROP LOGIN ${schema};
DROP SCHEMA IF EXISTS ${schema};

View File

@ -30,12 +30,7 @@ DROP TABLE IF EXISTS ${schema}.children;
DROP TABLE IF EXISTS ${schema}.parents;
DROP TABLE IF EXISTS ${schema}.contract_cash_states;
DROP TABLE IF EXISTS ${schema}.messages;
DROP TABLE IF EXISTS ${schema}.DummyDealStateSchemaV1$PersistentDummyDealState_participants;
DROP TABLE IF EXISTS ${schema}.DummyLinearStateSchemaV1$PersistentDummyLinearState_participants;
DROP TABLE IF EXISTS ${schema}.DummyLinearStateSchemaV2$PersistentDummyLinearState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCashSchemaV2$PersistentCashState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCashSchemaV3$PersistentCashState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCommercialPaperSchemaV2$PersistentCommercialPaperState_participants;
DROP TABLE IF EXISTS ${schema}.state_participants;
DROP TABLE IF EXISTS ${schema}.cash_states_v2;
DROP TABLE IF EXISTS ${schema}.cash_states_v3;
DROP TABLE IF EXISTS ${schema}.cp_states_v2;
@ -44,6 +39,8 @@ DROP TABLE IF EXISTS ${schema}.dummy_linear_states;
DROP TABLE IF EXISTS ${schema}.dummy_linear_states_v2;
DROP TABLE IF EXISTS ${schema}.node_mutual_exclusion;
DROP SEQUENCE IF EXISTS ${schema}.hibernate_sequence;
DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOG;
DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOGLOCK;
DROP USER IF EXISTS ${schema};
DROP LOGIN ${schema};
DROP SCHEMA IF EXISTS ${schema};

View File

@ -30,12 +30,7 @@ DROP TABLE IF EXISTS ${schema}.children;
DROP TABLE IF EXISTS ${schema}.parents;
DROP TABLE IF EXISTS ${schema}.contract_cash_states;
DROP TABLE IF EXISTS ${schema}.messages;
DROP TABLE IF EXISTS ${schema}.DummyDealStateSchemaV1$PersistentDummyDealState_participants;
DROP TABLE IF EXISTS ${schema}.DummyLinearStateSchemaV1$PersistentDummyLinearState_participants;
DROP TABLE IF EXISTS ${schema}.DummyLinearStateSchemaV2$PersistentDummyLinearState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCashSchemaV2$PersistentCashState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCashSchemaV3$PersistentCashState_participants;
DROP TABLE IF EXISTS ${schema}.SampleCommercialPaperSchemaV2$PersistentCommercialPaperState_participants;
DROP TABLE IF EXISTS ${schema}.state_participants;
DROP TABLE IF EXISTS ${schema}.cash_states_v2;
DROP TABLE IF EXISTS ${schema}.cash_states_v3;
DROP TABLE IF EXISTS ${schema}.cp_states_v2;
@ -44,6 +39,8 @@ DROP TABLE IF EXISTS ${schema}.dummy_linear_states;
DROP TABLE IF EXISTS ${schema}.dummy_linear_states_v2;
DROP TABLE IF EXISTS ${schema}.node_mutual_exclusion;
DROP SEQUENCE IF EXISTS ${schema}.hibernate_sequence;
DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOG;
DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOGLOCK;
IF NOT EXISTS (SELECT schema_name FROM information_schema.schemata WHERE schema_name = '${schema}') EXEC('CREATE SCHEMA ${schema}');
IF NOT EXISTS (SELECT * FROM sys.sysusers WHERE name='${schema}') CREATE USER ${schema} FOR LOGIN ${schema} WITH DEFAULT_SCHEMA = ${schema};
GRANT ALTER, DELETE, EXECUTE, INSERT, REFERENCES, SELECT, UPDATE, VIEW DEFINITION ON SCHEMA::${schema} TO ${schema};

View File

@ -0,0 +1,24 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet author="tudormalene (generated)" id="1512743551377-8">
<createTable tableName="dummy_deal_states">
<column name="output_index" type="INT(10)">
<constraints nullable="false"/>
</column>
<column name="transaction_id" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="external_id" type="VARCHAR(255)"/>
<column name="uuid" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
</databaseChangeLog>

Some files were not shown because too many files have changed in this diff Show More