mirror of
https://github.com/corda/corda.git
synced 2024-12-26 08:01:09 +00:00
Merge pull request #3189 from corda/cherrypick-corda-1397
CORDA-1397 - Fixed incorrect exception handling in `NodeVaultService…
This commit is contained in:
commit
35246460e2
@ -7,6 +7,10 @@ release, see :doc:`upgrade-notes`.
|
|||||||
Unreleased
|
Unreleased
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
* Fixed incorrect exception handling in ``NodeVaultService._query()``.
|
||||||
|
|
||||||
|
* Avoided a memory leak deriving from incorrect MappedSchema caching strategy.
|
||||||
|
|
||||||
* Fix CORDA-1403 where a property of a class that implemented a generic interface could not be deserialised in
|
* Fix CORDA-1403 where a property of a class that implemented a generic interface could not be deserialised in
|
||||||
a factory without a serialiser as the subtype check for the class instance failed. Fix is to compare the raw
|
a factory without a serialiser as the subtype check for the class instance failed. Fix is to compare the raw
|
||||||
type.
|
type.
|
||||||
|
@ -396,65 +396,60 @@ class NodeVaultService(
|
|||||||
// TODO: revisit (use single instance of parser for all queries)
|
// TODO: revisit (use single instance of parser for all queries)
|
||||||
val criteriaParser = HibernateQueryCriteriaParser(contractStateType, contractStateTypeMappings, criteriaBuilder, criteriaQuery, queryRootVaultStates)
|
val criteriaParser = HibernateQueryCriteriaParser(contractStateType, contractStateTypeMappings, criteriaBuilder, criteriaQuery, queryRootVaultStates)
|
||||||
|
|
||||||
try {
|
// parse criteria and build where predicates
|
||||||
// parse criteria and build where predicates
|
criteriaParser.parse(criteria, sorting)
|
||||||
criteriaParser.parse(criteria, sorting)
|
|
||||||
|
|
||||||
// prepare query for execution
|
// prepare query for execution
|
||||||
val query = session.createQuery(criteriaQuery)
|
val query = session.createQuery(criteriaQuery)
|
||||||
|
|
||||||
// pagination checks
|
// pagination checks
|
||||||
if (!paging.isDefault) {
|
if (!paging.isDefault) {
|
||||||
// pagination
|
// pagination
|
||||||
if (paging.pageNumber < DEFAULT_PAGE_NUM) throw VaultQueryException("Page specification: invalid page number ${paging.pageNumber} [page numbers start from $DEFAULT_PAGE_NUM]")
|
if (paging.pageNumber < DEFAULT_PAGE_NUM) throw VaultQueryException("Page specification: invalid page number ${paging.pageNumber} [page numbers start from $DEFAULT_PAGE_NUM]")
|
||||||
if (paging.pageSize < 1) throw VaultQueryException("Page specification: invalid page size ${paging.pageSize} [must be a value between 1 and $MAX_PAGE_SIZE]")
|
if (paging.pageSize < 1) throw VaultQueryException("Page specification: invalid page size ${paging.pageSize} [must be a value between 1 and $MAX_PAGE_SIZE]")
|
||||||
}
|
|
||||||
|
|
||||||
query.firstResult = (paging.pageNumber - 1) * paging.pageSize
|
|
||||||
query.maxResults = paging.pageSize + 1 // detection too many results
|
|
||||||
|
|
||||||
// execution
|
|
||||||
val results = query.resultList
|
|
||||||
|
|
||||||
// final pagination check (fail-fast on too many results when no pagination specified)
|
|
||||||
if (paging.isDefault && results.size > DEFAULT_PAGE_SIZE)
|
|
||||||
throw VaultQueryException("Please specify a `PageSpecification` as there are more results [${results.size}] than the default page size [$DEFAULT_PAGE_SIZE]")
|
|
||||||
|
|
||||||
val statesAndRefs: MutableList<StateAndRef<T>> = mutableListOf()
|
|
||||||
val statesMeta: MutableList<Vault.StateMetadata> = mutableListOf()
|
|
||||||
val otherResults: MutableList<Any> = mutableListOf()
|
|
||||||
val stateRefs = mutableSetOf<StateRef>()
|
|
||||||
|
|
||||||
results.asSequence()
|
|
||||||
.forEachIndexed { index, result ->
|
|
||||||
if (result[0] is VaultSchemaV1.VaultStates) {
|
|
||||||
if (!paging.isDefault && index == paging.pageSize) // skip last result if paged
|
|
||||||
return@forEachIndexed
|
|
||||||
val vaultState = result[0] as VaultSchemaV1.VaultStates
|
|
||||||
val stateRef = StateRef(SecureHash.parse(vaultState.stateRef!!.txId!!), vaultState.stateRef!!.index!!)
|
|
||||||
stateRefs.add(stateRef)
|
|
||||||
statesMeta.add(Vault.StateMetadata(stateRef,
|
|
||||||
vaultState.contractStateClassName,
|
|
||||||
vaultState.recordedTime,
|
|
||||||
vaultState.consumedTime,
|
|
||||||
vaultState.stateStatus,
|
|
||||||
vaultState.notary,
|
|
||||||
vaultState.lockId,
|
|
||||||
vaultState.lockUpdateTime))
|
|
||||||
} else {
|
|
||||||
// TODO: improve typing of returned other results
|
|
||||||
log.debug { "OtherResults: ${Arrays.toString(result.toArray())}" }
|
|
||||||
otherResults.addAll(result.toArray().asList())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stateRefs.isNotEmpty())
|
|
||||||
statesAndRefs.addAll(servicesForResolution.loadStates(stateRefs) as Collection<StateAndRef<T>>)
|
|
||||||
|
|
||||||
return Vault.Page(states = statesAndRefs, statesMetadata = statesMeta, stateTypes = criteriaParser.stateTypes, totalStatesAvailable = totalStates, otherResults = otherResults)
|
|
||||||
} catch (e: java.lang.Exception) {
|
|
||||||
log.error(e.message)
|
|
||||||
throw e.cause ?: e
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query.firstResult = (paging.pageNumber - 1) * paging.pageSize
|
||||||
|
query.maxResults = paging.pageSize + 1 // detection too many results
|
||||||
|
|
||||||
|
// execution
|
||||||
|
val results = query.resultList
|
||||||
|
|
||||||
|
// final pagination check (fail-fast on too many results when no pagination specified)
|
||||||
|
if (paging.isDefault && results.size > DEFAULT_PAGE_SIZE)
|
||||||
|
throw VaultQueryException("Please specify a `PageSpecification` as there are more results [${results.size}] than the default page size [$DEFAULT_PAGE_SIZE]")
|
||||||
|
|
||||||
|
val statesAndRefs: MutableList<StateAndRef<T>> = mutableListOf()
|
||||||
|
val statesMeta: MutableList<Vault.StateMetadata> = mutableListOf()
|
||||||
|
val otherResults: MutableList<Any> = mutableListOf()
|
||||||
|
val stateRefs = mutableSetOf<StateRef>()
|
||||||
|
|
||||||
|
results.asSequence()
|
||||||
|
.forEachIndexed { index, result ->
|
||||||
|
if (result[0] is VaultSchemaV1.VaultStates) {
|
||||||
|
if (!paging.isDefault && index == paging.pageSize) // skip last result if paged
|
||||||
|
return@forEachIndexed
|
||||||
|
val vaultState = result[0] as VaultSchemaV1.VaultStates
|
||||||
|
val stateRef = StateRef(SecureHash.parse(vaultState.stateRef!!.txId!!), vaultState.stateRef!!.index!!)
|
||||||
|
stateRefs.add(stateRef)
|
||||||
|
statesMeta.add(Vault.StateMetadata(stateRef,
|
||||||
|
vaultState.contractStateClassName,
|
||||||
|
vaultState.recordedTime,
|
||||||
|
vaultState.consumedTime,
|
||||||
|
vaultState.stateStatus,
|
||||||
|
vaultState.notary,
|
||||||
|
vaultState.lockId,
|
||||||
|
vaultState.lockUpdateTime))
|
||||||
|
} else {
|
||||||
|
// TODO: improve typing of returned other results
|
||||||
|
log.debug { "OtherResults: ${Arrays.toString(result.toArray())}" }
|
||||||
|
otherResults.addAll(result.toArray().asList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stateRefs.isNotEmpty())
|
||||||
|
statesAndRefs.addAll(servicesForResolution.loadStates(stateRefs) as Collection<StateAndRef<T>>)
|
||||||
|
|
||||||
|
return Vault.Page(states = statesAndRefs, statesMetadata = statesMeta, stateTypes = criteriaParser.stateTypes, totalStatesAvailable = totalStates, otherResults = otherResults)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(VaultQueryException::class)
|
@Throws(VaultQueryException::class)
|
||||||
|
Loading…
Reference in New Issue
Block a user