mirror of
https://github.com/corda/corda.git
synced 2025-04-26 05:49:44 +00:00
Merge remote-tracking branch 'remotes/open/master' into merges/may-21-17-24
# Conflicts: # client/rpc/src/main/kotlin/net/corda/client/rpc/PermissionException.kt
This commit is contained in:
commit
ee45c8280d
@ -6563,7 +6563,7 @@ public final class net.corda.client.rpc.CordaRPCConnection extends java.lang.Obj
|
|||||||
public int getServerProtocolVersion()
|
public int getServerProtocolVersion()
|
||||||
public void notifyServerAndClose()
|
public void notifyServerAndClose()
|
||||||
##
|
##
|
||||||
public final class net.corda.client.rpc.PermissionException extends net.corda.core.CordaRuntimeException implements net.corda.nodeapi.exceptions.RpcSerializableError
|
public final class net.corda.client.rpc.PermissionException extends net.corda.core.CordaRuntimeException implements net.corda.nodeapi.exceptions.RpcSerializableError, net.corda.core.ClientRelevantError
|
||||||
public <init>(String)
|
public <init>(String)
|
||||||
##
|
##
|
||||||
@DoNotImplement
|
@DoNotImplement
|
||||||
|
@ -33,7 +33,6 @@ import net.corda.testing.node.User
|
|||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.internal.toDatabaseSchemaName
|
import net.corda.testing.internal.toDatabaseSchemaName
|
||||||
import net.corda.testing.node.internal.NodeBasedTest
|
import net.corda.testing.node.internal.NodeBasedTest
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
|
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException
|
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||||
@ -121,7 +120,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
|
|||||||
}
|
}
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
} catch (e: ActiveMQNotConnectedException) {
|
} catch (e: RPCException) {
|
||||||
println("... node is not running.")
|
println("... node is not running.")
|
||||||
nodeIsShut.onCompleted()
|
nodeIsShut.onCompleted()
|
||||||
} catch (e: ActiveMQSecurityException) {
|
} catch (e: ActiveMQSecurityException) {
|
||||||
|
@ -24,13 +24,13 @@ import net.corda.node.services.messaging.RPCServerConfiguration
|
|||||||
import net.corda.nodeapi.RPCApi
|
import net.corda.nodeapi.RPCApi
|
||||||
import net.corda.nodeapi.eventually
|
import net.corda.nodeapi.eventually
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
|
import net.corda.testing.core.freePort
|
||||||
import net.corda.testing.internal.testThreadFactory
|
import net.corda.testing.internal.testThreadFactory
|
||||||
import net.corda.testing.node.internal.*
|
import net.corda.testing.node.internal.*
|
||||||
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration
|
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration
|
||||||
import org.apache.activemq.artemis.api.core.SimpleString
|
import org.apache.activemq.artemis.api.core.SimpleString
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.*
|
||||||
import org.junit.Assert.assertTrue
|
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
@ -336,6 +336,21 @@ class RPCStabilityTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `client throws RPCException after initial connection attempt fails`() {
|
||||||
|
val client = CordaRPCClient(NetworkHostAndPort("localhost", freePort()))
|
||||||
|
var exceptionMessage: String? = null
|
||||||
|
try {
|
||||||
|
client.start("user", "pass").proxy
|
||||||
|
} catch (e1: RPCException) {
|
||||||
|
exceptionMessage = e1.message
|
||||||
|
} catch (e2: Exception) {
|
||||||
|
fail("Expected RPCException to be thrown. Received ${e2.javaClass.simpleName} instead.")
|
||||||
|
}
|
||||||
|
assertNotNull(exceptionMessage)
|
||||||
|
assertEquals("Cannot connect to server(s). Tried with all available servers.", exceptionMessage)
|
||||||
|
}
|
||||||
|
|
||||||
interface ServerOps : RPCOps {
|
interface ServerOps : RPCOps {
|
||||||
fun serverId(): String
|
fun serverId(): String
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,16 @@
|
|||||||
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
* Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("DEPRECATION")
|
||||||
|
|
||||||
package net.corda.client.rpc
|
package net.corda.client.rpc
|
||||||
|
|
||||||
import net.corda.core.CordaRuntimeException
|
import net.corda.core.CordaRuntimeException
|
||||||
import net.corda.core.ClientRelevantError
|
import net.corda.core.ClientRelevantError
|
||||||
|
import net.corda.nodeapi.exceptions.RpcSerializableError
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown to indicate that the calling user does not have permission for something they have requested (for example
|
* Thrown to indicate that the calling user does not have permission for something they have requested (for example
|
||||||
* calling a method).
|
* calling a method).
|
||||||
*/
|
*/
|
||||||
class PermissionException(message: String) : CordaRuntimeException(message), ClientRelevantError
|
class PermissionException(message: String) : CordaRuntimeException(message), RpcSerializableError, ClientRelevantError
|
@ -38,6 +38,7 @@ import net.corda.core.utilities.getOrThrow
|
|||||||
import net.corda.nodeapi.RPCApi
|
import net.corda.nodeapi.RPCApi
|
||||||
import net.corda.nodeapi.internal.DeduplicationChecker
|
import net.corda.nodeapi.internal.DeduplicationChecker
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQException
|
import org.apache.activemq.artemis.api.core.ActiveMQException
|
||||||
|
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
|
||||||
import org.apache.activemq.artemis.api.core.RoutingType
|
import org.apache.activemq.artemis.api.core.RoutingType
|
||||||
import org.apache.activemq.artemis.api.core.SimpleString
|
import org.apache.activemq.artemis.api.core.SimpleString
|
||||||
import org.apache.activemq.artemis.api.core.client.ActiveMQClient.DEFAULT_ACK_BATCH_SIZE
|
import org.apache.activemq.artemis.api.core.client.ActiveMQClient.DEFAULT_ACK_BATCH_SIZE
|
||||||
@ -224,7 +225,11 @@ class RPCClientProxyHandler(
|
|||||||
// If there's only one available, that one will be retried continuously as configured in rpcConfiguration.
|
// If there's only one available, that one will be retried continuously as configured in rpcConfiguration.
|
||||||
// There is no failover on first attempt, meaning that if a connection cannot be established, the serverLocator
|
// There is no failover on first attempt, meaning that if a connection cannot be established, the serverLocator
|
||||||
// will try another transport if it exists or throw an exception otherwise.
|
// will try another transport if it exists or throw an exception otherwise.
|
||||||
sessionFactory = serverLocator.createSessionFactory()
|
try {
|
||||||
|
sessionFactory = serverLocator.createSessionFactory()
|
||||||
|
} catch (e: ActiveMQNotConnectedException) {
|
||||||
|
throw (RPCException("Cannot connect to server(s). Tried with all available servers.", e))
|
||||||
|
}
|
||||||
// Depending on how the client is constructed, connection failure is treated differently
|
// Depending on how the client is constructed, connection failure is treated differently
|
||||||
if (serverLocator.staticTransportConfigurations.size == 1) {
|
if (serverLocator.staticTransportConfigurations.size == 1) {
|
||||||
sessionFactory!!.addFailoverListener(this::failoverHandler)
|
sessionFactory!!.addFailoverListener(this::failoverHandler)
|
||||||
|
@ -14,6 +14,7 @@ import net.corda.core.CordaRuntimeException
|
|||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.ClientRelevantError
|
import net.corda.core.ClientRelevantError
|
||||||
import net.corda.core.flows.IdentifiableException
|
import net.corda.core.flows.IdentifiableException
|
||||||
|
import net.corda.core.serialization.CordaSerializable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown to indicate that an attachment was already uploaded to a Corda node.
|
* Thrown to indicate that an attachment was already uploaded to a Corda node.
|
||||||
@ -56,4 +57,11 @@ class OutdatedNetworkParameterHashException(old: SecureHash, new: SecureHash) :
|
|||||||
/**
|
/**
|
||||||
* Thrown to indicate that the command was rejected by the node, typically due to a special temporary mode.
|
* Thrown to indicate that the command was rejected by the node, typically due to a special temporary mode.
|
||||||
*/
|
*/
|
||||||
class RejectedCommandException(message: String) : CordaRuntimeException(message), ClientRelevantError
|
class RejectedCommandException(message: String) : CordaRuntimeException(message), ClientRelevantError
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows an implementing [Throwable] to be propagated to RPC clients.
|
||||||
|
*/
|
||||||
|
@Deprecated("Use ClientRelevantError instead.", replaceWith = ReplaceWith("ClientRelevantError"))
|
||||||
|
@CordaSerializable
|
||||||
|
interface RpcSerializableError
|
@ -11,6 +11,7 @@
|
|||||||
package net.corda.node.services.rpc
|
package net.corda.node.services.rpc
|
||||||
|
|
||||||
import net.corda.client.rpc.CordaRPCClient
|
import net.corda.client.rpc.CordaRPCClient
|
||||||
|
import net.corda.client.rpc.RPCException
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.node.services.Permissions.Companion.all
|
import net.corda.node.services.Permissions.Companion.all
|
||||||
@ -33,7 +34,6 @@ import net.corda.testing.internal.saveToTrustStore
|
|||||||
import net.corda.testing.internal.useSslRpcOverrides
|
import net.corda.testing.internal.useSslRpcOverrides
|
||||||
import net.corda.testing.node.User
|
import net.corda.testing.node.User
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQException
|
import org.apache.activemq.artemis.api.core.ActiveMQException
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
|
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException
|
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException
|
||||||
import org.assertj.core.api.Assertions
|
import org.assertj.core.api.Assertions
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
@ -115,7 +115,7 @@ class RpcSslTest : IntegrationTest() {
|
|||||||
successful = true
|
successful = true
|
||||||
}
|
}
|
||||||
connection.close()
|
connection.close()
|
||||||
}.isInstanceOf(ActiveMQNotConnectedException::class.java)
|
}.isInstanceOf(RPCException::class.java)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ class RpcSslTest : IntegrationTest() {
|
|||||||
clientAdmin.start(NODE_RPC_USER, NODE_RPC_USER).use { connection ->
|
clientAdmin.start(NODE_RPC_USER, NODE_RPC_USER).use { connection ->
|
||||||
connection.proxy.nodeInfo()
|
connection.proxy.nodeInfo()
|
||||||
}
|
}
|
||||||
}.isInstanceOf(ActiveMQException::class.java)
|
}.isInstanceOf(RPCException::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
package net.corda.node.services.rpc
|
package net.corda.node.services.rpc
|
||||||
|
|
||||||
|
import net.corda.client.rpc.RPCException
|
||||||
import net.corda.client.rpc.internal.RPCClient
|
import net.corda.client.rpc.internal.RPCClient
|
||||||
import net.corda.core.context.AuthServiceId
|
import net.corda.core.context.AuthServiceId
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
@ -34,7 +35,6 @@ import net.corda.testing.internal.createNodeSslConfig
|
|||||||
import net.corda.testing.internal.saveToKeyStore
|
import net.corda.testing.internal.saveToKeyStore
|
||||||
import net.corda.testing.internal.saveToTrustStore
|
import net.corda.testing.internal.saveToTrustStore
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQConnectionTimedOutException
|
import org.apache.activemq.artemis.api.core.ActiveMQConnectionTimedOutException
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
|
|
||||||
import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl
|
import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
@ -99,7 +99,7 @@ class ArtemisRpcTests {
|
|||||||
|
|
||||||
assertThatThrownBy {
|
assertThatThrownBy {
|
||||||
testSslCommunication(createNodeSslConfig(tempFolder.root.toPath()), brokerSslOptions, true, clientSslOptions)
|
testSslCommunication(createNodeSslConfig(tempFolder.root.toPath()), brokerSslOptions, true, clientSslOptions)
|
||||||
}.isInstanceOf(ActiveMQNotConnectedException::class.java)
|
}.isInstanceOf(RPCException::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun testSslCommunication(nodeSSlconfig: SSLConfiguration, brokerSslOptions: BrokerRpcSslOptions?, useSslForBroker: Boolean, clientSslOptions: ClientRpcSslOptions?, address: NetworkHostAndPort = ports.nextHostAndPort(),
|
private fun testSslCommunication(nodeSSlconfig: SSLConfiguration, brokerSslOptions: BrokerRpcSslOptions?, useSslForBroker: Boolean, clientSslOptions: ClientRpcSslOptions?, address: NetworkHostAndPort = ports.nextHostAndPort(),
|
||||||
|
@ -13,10 +13,10 @@ package net.corda.irs.web
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import net.corda.client.jackson.JacksonSupport
|
import net.corda.client.jackson.JacksonSupport
|
||||||
import net.corda.client.rpc.CordaRPCClient
|
import net.corda.client.rpc.CordaRPCClient
|
||||||
|
import net.corda.client.rpc.RPCException
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.finance.plugin.registerFinanceJSONMappers
|
import net.corda.finance.plugin.registerFinanceJSONMappers
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
|
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.beans.factory.annotation.Value
|
import org.springframework.beans.factory.annotation.Value
|
||||||
@ -49,7 +49,7 @@ class IrsDemoWebApplication {
|
|||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
return CordaRPCClient(NetworkHostAndPort.parse(cordaHost)).start(cordaUser, cordaPassword).proxy
|
return CordaRPCClient(NetworkHostAndPort.parse(cordaHost)).start(cordaUser, cordaPassword).proxy
|
||||||
} catch (ex: ActiveMQNotConnectedException) {
|
} catch (ex: RPCException) {
|
||||||
if (maxRetries-- > 0) {
|
if (maxRetries-- > 0) {
|
||||||
Thread.sleep(1000)
|
Thread.sleep(1000)
|
||||||
} else {
|
} else {
|
||||||
|
@ -13,6 +13,7 @@ package net.corda.tools.shell
|
|||||||
import com.google.common.io.Files
|
import com.google.common.io.Files
|
||||||
import com.jcraft.jsch.ChannelExec
|
import com.jcraft.jsch.ChannelExec
|
||||||
import com.jcraft.jsch.JSch
|
import com.jcraft.jsch.JSch
|
||||||
|
import net.corda.client.rpc.RPCException
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
@ -37,7 +38,6 @@ import net.corda.testing.internal.saveToKeyStore
|
|||||||
import net.corda.testing.internal.saveToTrustStore
|
import net.corda.testing.internal.saveToTrustStore
|
||||||
import net.corda.testing.internal.useSslRpcOverrides
|
import net.corda.testing.internal.useSslRpcOverrides
|
||||||
import net.corda.testing.node.User
|
import net.corda.testing.node.User
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
|
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException
|
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
@ -143,7 +143,7 @@ class InteractiveShellIntegrationTest : IntegrationTest() {
|
|||||||
|
|
||||||
InteractiveShell.startShell(conf)
|
InteractiveShell.startShell(conf)
|
||||||
|
|
||||||
assertThatThrownBy { InteractiveShell.nodeInfo() }.isInstanceOf(ActiveMQNotConnectedException::class.java)
|
assertThatThrownBy { InteractiveShell.nodeInfo() }.isInstanceOf(RPCException::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ package net.corda.webserver.internal
|
|||||||
import com.google.common.html.HtmlEscapers.htmlEscaper
|
import com.google.common.html.HtmlEscapers.htmlEscaper
|
||||||
import net.corda.client.jackson.JacksonSupport
|
import net.corda.client.jackson.JacksonSupport
|
||||||
import net.corda.client.rpc.CordaRPCClient
|
import net.corda.client.rpc.CordaRPCClient
|
||||||
|
import net.corda.client.rpc.RPCException
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.webserver.WebServerConfig
|
import net.corda.webserver.WebServerConfig
|
||||||
@ -23,7 +24,6 @@ import net.corda.webserver.servlets.CorDappInfoServlet
|
|||||||
import net.corda.webserver.servlets.DataUploadServlet
|
import net.corda.webserver.servlets.DataUploadServlet
|
||||||
import net.corda.webserver.servlets.ObjectMapperConfig
|
import net.corda.webserver.servlets.ObjectMapperConfig
|
||||||
import net.corda.webserver.servlets.ResponseFilter
|
import net.corda.webserver.servlets.ResponseFilter
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
|
|
||||||
import org.eclipse.jetty.server.Connector
|
import org.eclipse.jetty.server.Connector
|
||||||
import org.eclipse.jetty.server.HttpConfiguration
|
import org.eclipse.jetty.server.HttpConfiguration
|
||||||
import org.eclipse.jetty.server.HttpConnectionFactory
|
import org.eclipse.jetty.server.HttpConnectionFactory
|
||||||
@ -188,7 +188,7 @@ class NodeWebServer(val config: WebServerConfig) {
|
|||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
return connectLocalRpcAsNodeUser()
|
return connectLocalRpcAsNodeUser()
|
||||||
} catch (e: ActiveMQNotConnectedException) {
|
} catch (e: RPCException) {
|
||||||
log.debug("Could not connect to ${config.rpcAddress} due to exception: ", e)
|
log.debug("Could not connect to ${config.rpcAddress} due to exception: ", e)
|
||||||
Thread.sleep(retryDelay)
|
Thread.sleep(retryDelay)
|
||||||
// This error will happen if the server has yet to create the keystore
|
// This error will happen if the server has yet to create the keystore
|
||||||
|
Loading…
x
Reference in New Issue
Block a user