ENT-6414 reattachFlowWithClientId throws NullPointerException if user specifies non-existent client ID (#7044)

This commit is contained in:
Kyriakos Tharrouniatis 2022-01-25 14:42:45 +00:00 committed by GitHub
parent e40cd22c4f
commit a02f2e9f6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 2 deletions

View File

@ -50,6 +50,7 @@ import kotlin.concurrent.thread
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
import kotlin.test.assertNull
import kotlin.test.assertTrue
class CordaRPCClientReconnectionTest {
@ -595,6 +596,29 @@ class CordaRPCClientReconnectionTest {
}
}
@Test(timeout=300_000)
fun `reconnecting 'reattachFlowWithClientId' rpc works if called with non-existent client id`() {
driver(DriverParameters(inMemoryDB = false, cordappsForAllNodes = listOf(this.enclosedCordapp()))) {
val address = NetworkHostAndPort("localhost", portAllocator.nextPort())
fun startNode(additionalCustomOverrides: Map<String, Any?> = emptyMap()): NodeHandle {
return startNode(
providedName = CHARLIE_NAME,
rpcUsers = listOf(CordaRPCClientTest.rpcUser),
customOverrides = mapOf("rpcSettings.address" to address.toString()) + additionalCustomOverrides
).getOrThrow()
}
val node = startNode()
val client = CordaRPCClient(node.rpcAddress, config)
(client.start(rpcUser.username, rpcUser.password, gracefulReconnect = gracefulReconnect)).use {
val rpcOps = it.proxy as ReconnectingCordaRPCOps
val nonExistentClientId = UUID.randomUUID().toString()
val flowHandle = rpcOps.reattachFlowWithClientId<Any>(nonExistentClientId)
assertNull(flowHandle)
}
}
}
@StartableByRPC
class SimpleFlow : FlowLogic<Int>() {

View File

@ -391,10 +391,11 @@ class ReconnectingCordaRPCOps private constructor(
initialFeed.copy(updates = observable)
}
FlowHandleWithClientId::class.java -> {
val initialHandle: FlowHandleWithClientId<Any?> = uncheckedCast(doInvoke(method, args,
// initialHandle can be null. See @CordaRPCOps.reattachFlowWithClientId.
val initialHandle: FlowHandleWithClientId<Any?>? = uncheckedCast(doInvoke(method, args,
reconnectingRPCConnection.gracefulReconnect.maxAttempts))
val initialFuture = initialHandle.returnValue
val initialFuture = initialHandle?.returnValue ?: return null
// This is the future that is returned to the client. It will get carried until we reconnect to the node.
val returnFuture = openFuture<Any?>()