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.crypto.SecureHash
import net.corda.core.getOrThrow import net.corda.core.getOrThrow
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.*
import net.corda.core.messaging.StateMachineUpdate
import net.corda.core.messaging.startFlow
import net.corda.core.messaging.startTrackedFlow
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.node.services.vault.PageSpecification import net.corda.core.node.services.vault.PageSpecification
import net.corda.core.node.services.vault.QueryCriteria 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]. * It is the responsibility of the Client to request further pages and/or specify a more suitable [PageSpecification].
*/ */
// DOCSTART VaultQueryByAPI // DOCSTART VaultQueryByAPI
fun <T : ContractState> vaultQueryBy(criteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(), @RPCReturnsObservables
paging: PageSpecification = PageSpecification(), fun <T : ContractState> vaultQueryBy(criteria: QueryCriteria,
sorting: Sort = Sort(emptySet())): Vault.Page<T> paging: PageSpecification,
sorting: Sort,
contractType: Class<out T>): Vault.Page<T>
// DOCEND VaultQueryByAPI // 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. * 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 // DOCSTART VaultTrackByAPI
@RPCReturnsObservables @RPCReturnsObservables
fun <T : ContractState> vaultTrackBy(criteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(), fun <T : ContractState> vaultTrackBy(criteria: QueryCriteria,
paging: PageSpecification = PageSpecification(), paging: PageSpecification,
sorting: Sort = Sort(emptySet())): Vault.PageAndUpdates<T> sorting: Sort,
contractType: Class<out T>): Vault.PageAndUpdates<T>
// DOCEND VaultTrackByAPI // DOCEND VaultTrackByAPI
// Note: cannot apply @JvmOverloads to interfaces nor interface implementations // Note: cannot apply @JvmOverloads to interfaces nor interface implementations
// Java Helpers // Java Helpers
// DOCSTART VaultQueryAPIJavaHelpers // DOCSTART VaultTrackAPIHelpers
fun <T : ContractState> vaultQueryByCriteria(criteria: QueryCriteria): Vault.Page<T> = vaultQueryBy(criteria) fun <T : ContractState> vaultTrack(contractType: Class<out T>): Vault.PageAndUpdates<T> {
fun <T : ContractState> vaultQueryByWithPagingSpec(criteria: QueryCriteria, paging: PageSpecification): Vault.Page<T> = vaultQueryBy(criteria, paging) return vaultTrackBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractType)
fun <T : ContractState> vaultQueryByWithSorting(criteria: QueryCriteria, sorting: Sort): Vault.Page<T> = vaultQueryBy(criteria, sorting = sorting) }
fun <T : ContractState> vaultTrackByCriteria(contractType: Class<out T>, criteria: QueryCriteria): Vault.PageAndUpdates<T> {
fun <T : ContractState> vaultTrackByCriteria(criteria: QueryCriteria): Vault.PageAndUpdates<T> = vaultTrackBy(criteria) return vaultTrackBy(criteria, PageSpecification(), Sort(emptySet()), contractType)
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) fun <T : ContractState> vaultTrackByWithPagingSpec(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.PageAndUpdates<T> {
// DOCEND VaultQueryAPIJavaHelpers 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. * 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> 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.: * 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 * Note2: you can also annotate entity fields with JPA OrderBy annotation to achieve the same effect as explicit sorting
*/ */
@Throws(VaultQueryException::class) @Throws(VaultQueryException::class)
fun <T : ContractState> _queryBy(criteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(), fun <T : ContractState> _queryBy(criteria: QueryCriteria,
paging: PageSpecification = PageSpecification(), paging: PageSpecification,
sorting: Sort = Sort(emptySet()), sorting: Sort,
contractType: Class<out ContractState>): Vault.Page<T> contractType: Class<out T>): Vault.Page<T>
/** /**
* Generic vault query function which takes a [QueryCriteria] object to define filters, * Generic vault query function which takes a [QueryCriteria] object to define filters,
* optional [PageSpecification] and optional [Sort] modification criteria (default unsorted), * 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). * the [QueryCriteria] applies to both snapshot and deltas (streaming updates).
*/ */
@Throws(VaultQueryException::class) @Throws(VaultQueryException::class)
fun <T : ContractState> _trackBy(criteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(), fun <T : ContractState> _trackBy(criteria: QueryCriteria,
paging: PageSpecification = PageSpecification(), paging: PageSpecification,
sorting: Sort = Sort(emptySet()), sorting: Sort,
contractType: Class<out ContractState>): Vault.PageAndUpdates<T> contractType: Class<out T>): Vault.PageAndUpdates<T>
// DOCEND VaultQueryAPI // DOCEND VaultQueryAPI
// Note: cannot apply @JvmOverloads to interfaces nor interface implementations // Note: cannot apply @JvmOverloads to interfaces nor interface implementations
// Java Helpers // 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>): Vault.Page<T> {
fun <T : ContractState> queryBy(contractType: Class<out T>, criteria: QueryCriteria): Vault.Page<T> = _queryBy(criteria, PageSpecification(), Sort(emptySet()), contractType) return _queryBy(QueryCriteria.VaultQueryCriteria(), 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): Vault.Page<T> {
fun <T : ContractState> queryBy(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): Vault.Page<T> = _queryBy(criteria, paging, sorting, contractType) 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>): Vault.Page<T> {
fun <T : ContractState> trackBy(contractType: Class<out T>, criteria: QueryCriteria): Vault.PageAndUpdates<T> = _trackBy(criteria, PageSpecification(), Sort(emptySet()), contractType) return _queryBy(QueryCriteria.VaultQueryCriteria(), 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): Vault.PageAndUpdates<T> {
fun <T : ContractState> trackBy(contractType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification, sorting: Sort): Vault.PageAndUpdates<T> = _trackBy(criteria, paging, sorting, contractType) 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> { 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 :start-after: DOCSTART VaultTrackByAPI
:end-before: DOCEND 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 .. literalinclude:: ../../core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt
:language: kotlin :language: kotlin
:start-after: DOCSTART VaultQueryAPIJavaHelpers :start-after: DOCSTART VaultQueryAPIHelpers
:end-before: DOCEND VaultQueryAPIJavaHelpers :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. 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, override fun <T : ContractState> vaultQueryBy(criteria: QueryCriteria,
paging: PageSpecification, paging: PageSpecification,
sorting: Sort): Vault.Page<T> { sorting: Sort,
contractType: Class<out T>): Vault.Page<T> {
return database.transaction { return database.transaction {
services.vaultQueryService._queryBy(criteria, paging, sorting, ContractState::class.java as Class<T>) services.vaultQueryService._queryBy(criteria, paging, sorting, contractType)
} }
} }
@RPCReturnsObservables @RPCReturnsObservables
override fun <T : ContractState> vaultTrackBy(criteria: QueryCriteria, override fun <T : ContractState> vaultTrackBy(criteria: QueryCriteria,
paging: PageSpecification, paging: PageSpecification,
sorting: Sort): Vault.PageAndUpdates<T> { sorting: Sort,
contractType: Class<out T>): Vault.PageAndUpdates<T> {
return database.transaction { 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 private val criteriaBuilder = sessionFactory.criteriaBuilder
@Throws(VaultQueryException::class) @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") log.info("Vault Query for contract type: $contractType, criteria: $criteria, pagination: $paging, sorting: $sorting")
val session = sessionFactory.withOptions(). val session = sessionFactory.withOptions().
@ -102,7 +102,7 @@ class HibernateVaultQueryImpl(hibernateConfig: HibernateConfiguration,
private val mutex = ThreadBox ({ updatesPublisher }) private val mutex = ThreadBox ({ updatesPublisher })
@Throws(VaultQueryException::class) @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 { return mutex.locked {
val snapshotResults = _queryBy<T>(criteria, paging, sorting, contractType) val snapshotResults = _queryBy<T>(criteria, paging, sorting, contractType)
Vault.PageAndUpdates(snapshotResults, 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.crypto.keys
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StateMachineRunId import net.corda.core.flows.StateMachineRunId
import net.corda.core.messaging.StateMachineUpdate import net.corda.core.messaging.*
import net.corda.core.messaging.startFlow
import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.ServiceInfo
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.node.services.unconsumedStates import net.corda.core.node.services.unconsumedStates
@ -50,7 +49,7 @@ class CordaRPCOpsImplTest {
lateinit var mockNet: MockNetwork lateinit var mockNet: MockNetwork
lateinit var aliceNode: MockNode lateinit var aliceNode: MockNode
lateinit var notaryNode: MockNode lateinit var notaryNode: MockNode
lateinit var rpc: CordaRPCOpsImpl lateinit var rpc: CordaRPCOps
lateinit var stateMachineUpdates: Observable<StateMachineUpdate> lateinit var stateMachineUpdates: Observable<StateMachineUpdate>
lateinit var transactions: Observable<SignedTransaction> lateinit var transactions: Observable<SignedTransaction>
lateinit var vaultUpdates: Observable<Vault.Update> // TODO: deprecated lateinit var vaultUpdates: Observable<Vault.Update> // TODO: deprecated
@ -95,6 +94,10 @@ class CordaRPCOpsImplTest {
Issued(aliceNode.info.legalIdentity.ref(ref), GBP)), Issued(aliceNode.info.legalIdentity.ref(ref), GBP)),
recipient) recipient)
// Query vault via RPC
val cash = rpc.vaultQueryBy<Cash.State>()
assertEquals(expectedState, cash.states.first().state.data)
var issueSmId: StateMachineRunId? = null var issueSmId: StateMachineRunId? = null
stateMachineUpdates.expectEvents { stateMachineUpdates.expectEvents {
sequence( sequence(