Corda 3513 rpc flow without permission (#5828)

* CORDA-3513: Don't try to reconnect for PermissionExceptions

* CORDA-3513: Don't try to reconnect for PermissionExceptions

* CORDA-3513: Add test for not reconnecting for PermissionExceptions

* CORDA-3513: Update exception message and test
This commit is contained in:
Ryan Fowler 2020-01-07 11:35:45 +00:00 committed by Matthew Nesbit
parent 5df5d01f14
commit e0eac8fa0d
2 changed files with 27 additions and 3 deletions

View File

@ -303,9 +303,7 @@ class ReconnectingCordaRPCOps private constructor(
* A negative number for [maxNumberOfAttempts] means an unlimited number of retries will be performed.
*/
private fun doInvoke(method: Method, args: Array<out Any>?, maxNumberOfAttempts: Int): Any? {
if (reconnectingRPCConnection.isClosed()) {
throw RPCException("Cannot execute RPC command after client has shut down.")
}
checkIfClosed()
var remainingAttempts = maxNumberOfAttempts
var lastException: Throwable? = null
while (remainingAttempts != 0) {
@ -331,6 +329,9 @@ class ReconnectingCordaRPCOps private constructor(
Thread.sleep(1000) // TODO - explain why this sleep is necessary
checkIfIsStartFlow(method, e)
}
is PermissionException -> {
throw RPCException("User does not have permission to perform operation ${method.name}.", e)
}
else -> {
log.warn("Failed to perform operation ${method.name}. Unknown error. Retrying....", e)
reconnectingRPCConnection.reconnectOnError(e)
@ -345,6 +346,12 @@ class ReconnectingCordaRPCOps private constructor(
throw MaxRpcRetryException(maxNumberOfAttempts, lastException)
}
private fun checkIfClosed() {
if (reconnectingRPCConnection.isClosed()) {
throw RPCException("Cannot execute RPC command after client has shut down.")
}
}
override fun invoke(proxy: Any, method: Method, args: Array<out Any>?): Any? {
return when (method.returnType) {
DataFeed::class.java -> {

View File

@ -184,6 +184,23 @@ class FlowRetryTest {
}
}
}
@Test
fun `Permission exceptions are not retried and propagate`() {
val user = User("mark", "dadada", setOf())
driver(DriverParameters(isDebug = true, startNodesInProcess = isQuasarAgentSpecified())) {
val nodeAHandle = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)).getOrThrow()
CordaRPCClient(nodeAHandle.rpcAddress).start(user.username, user.password).use {
assertThatExceptionOfType(CordaRuntimeException::class.java).isThrownBy {
it.proxy.startFlow(::AsyncRetryFlow).returnValue.getOrThrow()
}.withMessageStartingWith("User not authorized to perform RPC call")
// This stays at -1 since the flow never even got called
assertEquals(-1, GeneralExternalFailureFlow.retryCount)
}
}
}
}
fun isQuasarAgentSpecified(): Boolean {