Vault Query API design (#522)

* Added queryBy(QueryCriteria) Vault API and Junit tests.

* Minor fix following rebase.

* Spit out Vault Query tests into separate source file.

* WIP

* Enable composition of QueryCriteria specifications.
Additional JUnit test cases to validate API.

* Added Deprecating annotations.
Added QueryCriteria for set of contractStateTypes

* Minor tweaks and additional JUnit test cases (chain of linear id)

* Added Java Junit tests and QueryCriteria builder support.

* Added API documentation (including coding snippets and examples).

* Added @JvmOverloads to QueryCriteria classes for easy of use from Java.

* Refactored QueryCriteria API to use composition via sealed data classes.

* Enable infix notation.

* Fixed typo.

* Clarified future work to enforce DB level permissioning.

* Moved PageSpec and Order from QueryCriteria to become parameters of Query itself.

* Moved PageSpec and Order from QueryCriteria to become parameters of Query itself.

* TokenType now specified as set of <Class> (was non extensible enum).

* Exposed new Vault Query API functions via RPC.

* Fixed compiler error in java test.

* Addressed a couple of minor PR review scomments from MH.

* Major updates following PR discussion and recommendations.

* All pagination and sorting arguments are optional (and constructed with sensible defaults).
Added Java helper functions for queryBy and trackBy interfaces.
Added Java trackBy unit tests.
Miscellaneous cleanup.

* Added Generic Index schema mapping and query support.

* Query criteria referencing Party now references a String (until Identity framework built out).
Added participants attribute to general query criteria.

* Fleshed our IndexCriteria including PR recommendation to define column aliases for index mappings.

* Removed all directly exposed API dependencies on requery.

* Updated documentation.

* Provide sensible defaults for all Query arguments.
Add RPC Java helpers and increase range of Vault Service helpers.

* Further improvements (upgrading notes) and updates to documentation.

* RST documentation updates.

* Updates to address RP latest set of review comments.

* Updates to address MH latest set of review comments.

* Updated to highlight use of VaultIndexQueryCriteria to directly reference a JPA-annotated entity (versus the indirect, explicitly mapped attribute to GenericIndexSchema approach)

* Aesthetic updates requested by MH

* Reverted Indexing approach: removed all references to VaultIndexedQueryCriteria and GenericVaultIndexSchemaV1 scheme.

* Final clean-up and minor updates prior to merge.

* Fixed compiler warnings (except deprecation warnings)

* Reverted all changes to Vault Schemas (except simple illustrative VaultLinearState used in VaultQueryTests)

* Reverted all changes to Vault Schemas (except simple illustrative VaultLinearState used in VaultQueryTests)

* Commented out @Deprecated annotations (as a hedge against us releasing M12 with the work half-done)

* Renamed RPC JavaHelper functions as RPCDispatcher does not allow more than one method with same name.
This commit is contained in:
josecoll
2017-05-05 15:14:43 +01:00
committed by GitHub
parent c062d48e6e
commit 8c3b9ac589
20 changed files with 1918 additions and 84 deletions

View File

@ -81,13 +81,14 @@ class CommercialPaper : Contract {
override fun withFaceValue(newFaceValue: Amount<Issued<Currency>>): ICommercialPaperState = copy(faceValue = newFaceValue)
override fun withMaturityDate(newMaturityDate: Instant): ICommercialPaperState = copy(maturityDate = newMaturityDate)
// DOCSTART VaultIndexedQueryCriteria
/** Object Relational Mapping support. */
override fun supportedSchemas(): Iterable<MappedSchema> = listOf(CommercialPaperSchemaV1)
/** Object Relational Mapping support. */
override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) {
is CommercialPaperSchemaV1 -> CommercialPaperSchemaV1.PersistentCommericalPaperState(
is CommercialPaperSchemaV1 -> CommercialPaperSchemaV1.PersistentCommercialPaperState(
issuanceParty = this.issuance.party.owningKey.toBase58String(),
issuanceRef = this.issuance.reference.bytes,
owner = this.owner.toBase58String(),
@ -100,6 +101,7 @@ class CommercialPaper : Contract {
else -> throw IllegalArgumentException("Unrecognised schema $schema")
}
}
// DOCEND VaultIndexedQueryCriteria
}
interface Clauses {

View File

@ -5,10 +5,8 @@ package net.corda.contracts.testing
import net.corda.contracts.asset.Cash
import net.corda.contracts.asset.DUMMY_CASH_ISSUER
import net.corda.contracts.asset.DUMMY_CASH_ISSUER_KEY
import net.corda.core.contracts.Amount
import net.corda.core.contracts.Issued
import net.corda.core.contracts.PartyAndReference
import net.corda.core.contracts.TransactionType
import net.corda.core.contracts.*
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.Party
import net.corda.core.node.ServiceHub
import net.corda.core.node.services.Vault
@ -20,12 +18,16 @@ import java.security.KeyPair
import java.security.PublicKey
import java.util.*
fun ServiceHub.fillWithSomeTestDeals(dealIds: List<String>) {
@JvmOverloads
fun ServiceHub.fillWithSomeTestDeals(dealIds: List<String>,
revisions: Int? = 0,
participants: List<PublicKey> = emptyList()) : Vault<DealState> {
val freshKey = keyManagementService.freshKey()
val transactions: List<SignedTransaction> = dealIds.map {
// Issue a deal state
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyDealContract.State(ref = it, participants = listOf(freshKey.public)))
addOutputState(DummyDealContract.State(ref = it, participants = participants.plus(freshKey.public)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}
@ -33,19 +35,40 @@ fun ServiceHub.fillWithSomeTestDeals(dealIds: List<String>) {
}
recordTransactions(transactions)
// Get all the StateAndRefs of all the generated transactions.
val states = transactions.flatMap { stx ->
stx.tx.outputs.indices.map { i -> stx.tx.outRef<DealState>(i) }
}
return Vault(states)
}
fun ServiceHub.fillWithSomeTestLinearStates(numberToCreate: Int) {
@JvmOverloads
fun ServiceHub.fillWithSomeTestLinearStates(numberToCreate: Int,
uid: UniqueIdentifier = UniqueIdentifier(),
participants: List<PublicKey> = emptyList()) : Vault<LinearState> {
val freshKey = keyManagementService.freshKey()
for (i in 1..numberToCreate) {
// Issue a deal state
val transactions: List<SignedTransaction> = (1..numberToCreate).map {
// Issue a Linear state
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyLinearContract.State(participants = listOf(freshKey.public)))
addOutputState(DummyLinearContract.State(linearId = uid, participants = participants.plus(freshKey.public)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}
recordTransactions(dummyIssue.toSignedTransaction())
return@map dummyIssue.toSignedTransaction(true)
}
recordTransactions(transactions)
// Get all the StateAndRefs of all the generated transactions.
val states = transactions.flatMap { stx ->
stx.tx.outputs.indices.map { i -> stx.tx.outRef<LinearState>(i) }
}
return Vault(states)
}
/**

View File

@ -4,6 +4,7 @@ import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Index
import javax.persistence.Table
/**
@ -17,7 +18,9 @@ object CashSchema
*/
object CashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCashState::class.java)) {
@Entity
@Table(name = "cash_states")
@Table(name = "cash_states",
indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"),
Index(name = "pennies_idx", columnList = "pennies")))
class PersistentCashState(
@Column(name = "owner_key")
var owner: String,

View File

@ -5,6 +5,7 @@ import net.corda.core.schemas.PersistentState
import java.time.Instant
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Index
import javax.persistence.Table
/**
@ -16,10 +17,13 @@ object CommercialPaperSchema
* First version of a commercial paper contract ORM schema that maps all fields of the [CommercialPaper] contract state
* as it stood at the time of writing.
*/
object CommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCommericalPaperState::class.java)) {
object CommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCommercialPaperState::class.java)) {
@Entity
@Table(name = "cp_states")
class PersistentCommericalPaperState(
@Table(name = "cp_states",
indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"),
Index(name = "maturity_idx", columnList = "maturity_instant"),
Index(name = "face_value_idx", columnList = "face_value")))
class PersistentCommercialPaperState(
@Column(name = "issuance_key")
var issuanceParty: String,