Align CordaRPCOps Vault Query API's for Java/Kotlin with VaultQuery service equivalents. (#914)

Added Kotlin extension functions for ease of use in simplest case.
Added missing Java contractType class (previously was forced cast of ContractState::class)

Fixed generic typing.

Addressed items raised in SA PR review.

Removed 2 blank lines.

Fixed generics typing.

Updates RST doc and grouped API helpers accordingly.
This commit is contained in:
josecoll 2017-06-23 14:35:55 +01:00 committed by GitHub
parent 61a24897fe
commit 1866f6ff7f
7 changed files with 115 additions and 49 deletions

View File

@ -11,10 +11,7 @@ import net.corda.core.contracts.SWISS_FRANCS
import net.corda.core.crypto.SecureHash
import net.corda.core.getOrThrow
import net.corda.core.identity.Party
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.StateMachineUpdate
import net.corda.core.messaging.startFlow
import net.corda.core.messaging.startTrackedFlow
import net.corda.core.messaging.*
import net.corda.core.node.services.Vault
import net.corda.core.node.services.vault.PageSpecification
import net.corda.core.node.services.vault.QueryCriteria

View File

@ -83,11 +83,31 @@ interface CordaRPCOps : RPCOps {
* It is the responsibility of the Client to request further pages and/or specify a more suitable [PageSpecification].
*/
// DOCSTART VaultQueryByAPI
fun <T : ContractState> vaultQueryBy(criteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(),
paging: PageSpecification = PageSpecification(),
sorting: Sort = Sort(emptySet())): Vault.Page<T>
@RPCReturnsObservables
fun <T : ContractState> vaultQueryBy(criteria: QueryCriteria,
paging: PageSpecification,
sorting: Sort,
contractType: Class<out T>): Vault.Page<T>
// DOCEND VaultQueryByAPI
// Note: cannot apply @JvmOverloads to interfaces nor interface implementations
// Java Helpers
// DOCSTART VaultQueryAPIHelpers
fun <T : ContractState> vaultQuery(contractType: Class<out T>): Vault.Page<T> {
return vaultQueryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType)
}
fun <T : ContractState> vaultQueryByCriteria(criteria: QueryCriteria, contractType: Class<out T>): Vault.Page<T> {
return vaultQueryBy(criteria, PageSpecification(), Sort(emptySet()), contractType)
}
fun <T : ContractState> vaultQueryByWithPagingSpec(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.Page<T> {
return vaultQueryBy(criteria, paging, Sort(emptySet()), contractType)
}
fun <T : ContractState> vaultQueryByWithSorting(contractType: Class<out T>, criteria: QueryCriteria, sorting: Sort): Vault.Page<T> {
return vaultQueryBy(criteria, PageSpecification(), sorting, contractType)
}
// DOCEND VaultQueryAPIHelpers
/**
* Returns a snapshot (as per queryBy) and an observable of future updates to the vault for the given query criteria.
*
@ -102,23 +122,29 @@ interface CordaRPCOps : RPCOps {
*/
// DOCSTART VaultTrackByAPI
@RPCReturnsObservables
fun <T : ContractState> vaultTrackBy(criteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(),
paging: PageSpecification = PageSpecification(),
sorting: Sort = Sort(emptySet())): Vault.PageAndUpdates<T>
fun <T : ContractState> vaultTrackBy(criteria: QueryCriteria,
paging: PageSpecification,
sorting: Sort,
contractType: Class<out T>): Vault.PageAndUpdates<T>
// DOCEND VaultTrackByAPI
// Note: cannot apply @JvmOverloads to interfaces nor interface implementations
// Java Helpers
// DOCSTART VaultQueryAPIJavaHelpers
fun <T : ContractState> vaultQueryByCriteria(criteria: QueryCriteria): Vault.Page<T> = vaultQueryBy(criteria)
fun <T : ContractState> vaultQueryByWithPagingSpec(criteria: QueryCriteria, paging: PageSpecification): Vault.Page<T> = vaultQueryBy(criteria, paging)
fun <T : ContractState> vaultQueryByWithSorting(criteria: QueryCriteria, sorting: Sort): Vault.Page<T> = vaultQueryBy(criteria, sorting = sorting)
fun <T : ContractState> vaultTrackByCriteria(criteria: QueryCriteria): Vault.PageAndUpdates<T> = vaultTrackBy(criteria)
fun <T : ContractState> vaultTrackByWithPagingSpec(criteria: QueryCriteria, paging: PageSpecification): Vault.PageAndUpdates<T> = vaultTrackBy(criteria, paging)
fun <T : ContractState> vaultTrackByWithSorting(criteria: QueryCriteria, sorting: Sort): Vault.PageAndUpdates<T> = vaultTrackBy(criteria, sorting = sorting)
// DOCEND VaultQueryAPIJavaHelpers
// DOCSTART VaultTrackAPIHelpers
fun <T : ContractState> vaultTrack(contractType: Class<out T>): Vault.PageAndUpdates<T> {
return vaultTrackBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType)
}
fun <T : ContractState> vaultTrackByCriteria(contractType: Class<out T>, criteria: QueryCriteria): Vault.PageAndUpdates<T> {
return vaultTrackBy(criteria, PageSpecification(), Sort(emptySet()), contractType)
}
fun <T : ContractState> vaultTrackByWithPagingSpec(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.PageAndUpdates<T> {
return vaultTrackBy(criteria, paging, Sort(emptySet()), contractType)
}
fun <T : ContractState> vaultTrackByWithSorting(contractType: Class<out T>, criteria: QueryCriteria, sorting: Sort): Vault.PageAndUpdates<T> {
return vaultTrackBy(criteria, PageSpecification(), sorting, contractType)
}
// DOCEND VaultTrackAPIHelpers
/**
* Returns a pair of head states in the vault and an observable of future updates to the vault.
@ -258,6 +284,18 @@ interface CordaRPCOps : RPCOps {
fun registeredFlows(): List<String>
}
inline fun <reified T : ContractState> CordaRPCOps.vaultQueryBy(criteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(),
paging: PageSpecification = PageSpecification(),
sorting: Sort = Sort(emptySet())): Vault.Page<T> {
return vaultQueryBy(criteria, paging, sorting, T::class.java)
}
inline fun <reified T : ContractState> CordaRPCOps.vaultTrackBy(criteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(),
paging: PageSpecification = PageSpecification(),
sorting: Sort = Sort(emptySet())): Vault.PageAndUpdates<T> {
return vaultTrackBy(criteria, paging, sorting, T::class.java)
}
/**
* These allow type safe invocations of flows from Kotlin, e.g.:
*

View File

@ -361,10 +361,10 @@ interface VaultQueryService {
* Note2: you can also annotate entity fields with JPA OrderBy annotation to achieve the same effect as explicit sorting
*/
@Throws(VaultQueryException::class)
fun <T : ContractState> _queryBy(criteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(),
paging: PageSpecification = PageSpecification(),
sorting: Sort = Sort(emptySet()),
contractType: Class<out ContractState>): Vault.Page<T>
fun <T : ContractState> _queryBy(criteria: QueryCriteria,
paging: PageSpecification,
sorting: Sort,
contractType: Class<out T>): Vault.Page<T>
/**
* Generic vault query function which takes a [QueryCriteria] object to define filters,
* optional [PageSpecification] and optional [Sort] modification criteria (default unsorted),
@ -378,25 +378,45 @@ interface VaultQueryService {
* the [QueryCriteria] applies to both snapshot and deltas (streaming updates).
*/
@Throws(VaultQueryException::class)
fun <T : ContractState> _trackBy(criteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(),
paging: PageSpecification = PageSpecification(),
sorting: Sort = Sort(emptySet()),
contractType: Class<out ContractState>): Vault.PageAndUpdates<T>
fun <T : ContractState> _trackBy(criteria: QueryCriteria,
paging: PageSpecification,
sorting: Sort,
contractType: Class<out T>): Vault.PageAndUpdates<T>
// DOCEND VaultQueryAPI
// Note: cannot apply @JvmOverloads to interfaces nor interface implementations
// Java Helpers
fun <T : ContractState> queryBy(contractType: Class<out T>): Vault.Page<T> = _queryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType)
fun <T : ContractState> queryBy(contractType: Class<out T>, criteria: QueryCriteria): Vault.Page<T> = _queryBy(criteria, PageSpecification(), Sort(emptySet()), contractType)
fun <T : ContractState> queryBy(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.Page<T> = _queryBy(criteria, paging, Sort(emptySet()), contractType)
fun <T : ContractState> queryBy(contractType: Class<out T>, criteria: QueryCriteria, sorting: Sort): Vault.Page<T> = _queryBy(criteria, PageSpecification(), sorting, contractType)
fun <T : ContractState> queryBy(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): Vault.Page<T> = _queryBy(criteria, paging, sorting, contractType)
fun <T : ContractState> queryBy(contractType: Class<out T>): Vault.Page<T> {
return _queryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType)
}
fun <T : ContractState> queryBy(contractType: Class<out T>, criteria: QueryCriteria): Vault.Page<T> {
return _queryBy(criteria, PageSpecification(), Sort(emptySet()), contractType)
}
fun <T : ContractState> queryBy(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.Page<T> {
return _queryBy(criteria, paging, Sort(emptySet()), contractType)
}
fun <T : ContractState> queryBy(contractType: Class<out T>, criteria: QueryCriteria, sorting: Sort): Vault.Page<T> {
return _queryBy(criteria, PageSpecification(), sorting, contractType)
}
fun <T : ContractState> queryBy(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): Vault.Page<T> {
return _queryBy(criteria, paging, sorting, contractType)
}
fun <T : ContractState> trackBy(contractType: Class<out T>): Vault.Page<T> = _queryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType)
fun <T : ContractState> trackBy(contractType: Class<out T>, criteria: QueryCriteria): Vault.PageAndUpdates<T> = _trackBy(criteria, PageSpecification(), Sort(emptySet()), contractType)
fun <T : ContractState> trackBy(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.PageAndUpdates<T> = _trackBy(criteria, paging, Sort(emptySet()), contractType)
fun <T : ContractState> trackBy(contractType: Class<out T>, criteria: QueryCriteria, sorting: Sort): Vault.PageAndUpdates<T> = _trackBy(criteria, PageSpecification(), sorting, contractType)
fun <T : ContractState> trackBy(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): Vault.PageAndUpdates<T> = _trackBy(criteria, paging, sorting, contractType)
fun <T : ContractState> trackBy(contractType: Class<out T>): Vault.Page<T> {
return _queryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType)
}
fun <T : ContractState> trackBy(contractType: Class<out T>, criteria: QueryCriteria): Vault.PageAndUpdates<T> {
return _trackBy(criteria, PageSpecification(), Sort(emptySet()), contractType)
}
fun <T : ContractState> trackBy(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.PageAndUpdates<T> {
return _trackBy(criteria, paging, Sort(emptySet()), contractType)
}
fun <T : ContractState> trackBy(contractType: Class<out T>, criteria: QueryCriteria, sorting: Sort): Vault.PageAndUpdates<T> {
return _trackBy(criteria, PageSpecification(), sorting, contractType)
}
fun <T : ContractState> trackBy(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): Vault.PageAndUpdates<T> {
return _trackBy(criteria, paging, sorting, contractType)
}
}
inline fun <reified T : ContractState> VaultQueryService.queryBy(): Vault.Page<T> {

View File

@ -28,12 +28,17 @@ and via ``CordaRPCOps`` for use by RPC client applications:
:start-after: DOCSTART VaultTrackByAPI
:end-before: DOCEND VaultTrackByAPI
Java helper methods are also provided with default values for arguments:
Helper methods are also provided with default values for arguments:
.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt
:language: kotlin
:start-after: DOCSTART VaultQueryAPIJavaHelpers
:end-before: DOCEND VaultQueryAPIJavaHelpers
:start-after: DOCSTART VaultQueryAPIHelpers
:end-before: DOCEND VaultQueryAPIHelpers
.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt
:language: kotlin
:start-after: DOCSTART VaultTrackAPIHelpers
:end-before: DOCEND VaultTrackAPIHelpers
The API provides both static (snapshot) and dynamic (snapshot with streaming updates) methods for a defined set of filter criteria.

View File

@ -58,18 +58,20 @@ class CordaRPCOpsImpl(
override fun <T : ContractState> vaultQueryBy(criteria: QueryCriteria,
paging: PageSpecification,
sorting: Sort): Vault.Page<T> {
sorting: Sort,
contractType: Class<out T>): Vault.Page<T> {
return database.transaction {
services.vaultQueryService._queryBy(criteria, paging, sorting, ContractState::class.java as Class<T>)
services.vaultQueryService._queryBy(criteria, paging, sorting, contractType)
}
}
@RPCReturnsObservables
override fun <T : ContractState> vaultTrackBy(criteria: QueryCriteria,
paging: PageSpecification,
sorting: Sort): Vault.PageAndUpdates<T> {
sorting: Sort,
contractType: Class<out T>): Vault.PageAndUpdates<T> {
return database.transaction {
services.vaultQueryService._trackBy<T>(criteria, paging, sorting, ContractState::class.java as Class<T>)
services.vaultQueryService._trackBy<T>(criteria, paging, sorting, contractType)
}
}
@ -195,3 +197,4 @@ class CordaRPCOpsImpl(
}
}

View File

@ -39,7 +39,7 @@ class HibernateVaultQueryImpl(hibernateConfig: HibernateConfiguration,
private val criteriaBuilder = sessionFactory.criteriaBuilder
@Throws(VaultQueryException::class)
override fun <T : ContractState> _queryBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort, contractType: Class<out ContractState>): Vault.Page<T> {
override fun <T : ContractState> _queryBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort, contractType: Class<out T>): Vault.Page<T> {
log.info("Vault Query for contract type: $contractType, criteria: $criteria, pagination: $paging, sorting: $sorting")
val session = sessionFactory.withOptions().
@ -102,7 +102,7 @@ class HibernateVaultQueryImpl(hibernateConfig: HibernateConfiguration,
private val mutex = ThreadBox ({ updatesPublisher })
@Throws(VaultQueryException::class)
override fun <T : ContractState> _trackBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort, contractType: Class<out ContractState>): Vault.PageAndUpdates<T> {
override fun <T : ContractState> _trackBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort, contractType: Class<out T>): Vault.PageAndUpdates<T> {
return mutex.locked {
val snapshotResults = _queryBy<T>(criteria, paging, sorting, contractType)
Vault.PageAndUpdates(snapshotResults,

View File

@ -7,8 +7,7 @@ import net.corda.core.crypto.isFulfilledBy
import net.corda.core.crypto.keys
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StateMachineRunId
import net.corda.core.messaging.StateMachineUpdate
import net.corda.core.messaging.startFlow
import net.corda.core.messaging.*
import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault
import net.corda.core.node.services.unconsumedStates
@ -50,7 +49,7 @@ class CordaRPCOpsImplTest {
lateinit var mockNet: MockNetwork
lateinit var aliceNode: MockNode
lateinit var notaryNode: MockNode
lateinit var rpc: CordaRPCOpsImpl
lateinit var rpc: CordaRPCOps
lateinit var stateMachineUpdates: Observable<StateMachineUpdate>
lateinit var transactions: Observable<SignedTransaction>
lateinit var vaultUpdates: Observable<Vault.Update> // TODO: deprecated
@ -95,6 +94,10 @@ class CordaRPCOpsImplTest {
Issued(aliceNode.info.legalIdentity.ref(ref), GBP)),
recipient)
// Query vault via RPC
val cash = rpc.vaultQueryBy<Cash.State>()
assertEquals(expectedState, cash.states.first().state.data)
var issueSmId: StateMachineRunId? = null
stateMachineUpdates.expectEvents {
sequence(