mirror of
https://github.com/corda/corda.git
synced 2025-06-17 22:58:19 +00:00
[CORDA-1397]: Fixed incorrect exception handling in NodeVaultService._query()
. (#3043)
This commit is contained in:
committed by
GitHub
parent
5565b3e80d
commit
92922b874c
@ -6,6 +6,9 @@ release, see :doc:`upgrade-notes`.
|
|||||||
|
|
||||||
Unreleased
|
Unreleased
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
* Fixed incorrect exception handling in ``NodeVaultService._query()``.
|
||||||
|
|
||||||
* Avoided a memory leak deriving from incorrect MappedSchema caching strategy.
|
* Avoided a memory leak deriving from incorrect MappedSchema caching strategy.
|
||||||
|
|
||||||
* Added program line argument ``on-unknown-config-keys`` to allow specifying behaviour on unknown node configuration property keys.
|
* Added program line argument ``on-unknown-config-keys`` to allow specifying behaviour on unknown node configuration property keys.
|
||||||
|
@ -406,65 +406,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)
|
||||||
|
Reference in New Issue
Block a user