mirror of
https://github.com/corda/corda.git
synced 2024-12-19 04:57:58 +00:00
Removed SSLConfiguration parameter from CordaRPCClient, thus removing SSL support.
The current use of SSL RPC relies on access to the node's keystore file, and further to that some uses where using the NODE_USER to login on the p2p port.
This commit is contained in:
parent
b4e674c2fe
commit
4df8b427d2
@ -57,7 +57,7 @@ public class CordaRPCJavaClientTest extends NodeBasedTest {
|
|||||||
CordaFuture<StartedNode<Node>> nodeFuture = startNode(getALICE().getName(), 1, services, singletonList(rpcUser), emptyMap());
|
CordaFuture<StartedNode<Node>> nodeFuture = startNode(getALICE().getName(), 1, services, singletonList(rpcUser), emptyMap());
|
||||||
node = nodeFuture.get();
|
node = nodeFuture.get();
|
||||||
node.getInternals().registerCustomSchemas(Collections.singleton(CashSchemaV1.INSTANCE));
|
node.getInternals().registerCustomSchemas(Collections.singleton(CashSchemaV1.INSTANCE));
|
||||||
client = new CordaRPCClient(requireNonNull(node.getInternals().getConfiguration().getRpcAddress()), null, getDefault(), false);
|
client = new CordaRPCClient(requireNonNull(node.getInternals().getConfiguration().getRpcAddress()), getDefault(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -7,7 +7,6 @@ import net.corda.core.messaging.CordaRPCOps
|
|||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.nodeapi.ArtemisTcpTransport.Companion.tcpTransport
|
import net.corda.nodeapi.ArtemisTcpTransport.Companion.tcpTransport
|
||||||
import net.corda.nodeapi.ConnectionDirection
|
import net.corda.nodeapi.ConnectionDirection
|
||||||
import net.corda.nodeapi.config.SSLConfiguration
|
|
||||||
import net.corda.nodeapi.internal.serialization.KRYO_RPC_CLIENT_CONTEXT
|
import net.corda.nodeapi.internal.serialization.KRYO_RPC_CLIENT_CONTEXT
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
|
||||||
@ -34,9 +33,9 @@ data class CordaRPCClientConfiguration(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @see RPCClient */
|
/** @see RPCClient */
|
||||||
|
//TODO Add SSL support
|
||||||
class CordaRPCClient(
|
class CordaRPCClient(
|
||||||
hostAndPort: NetworkHostAndPort,
|
hostAndPort: NetworkHostAndPort,
|
||||||
sslConfiguration: SSLConfiguration? = null,
|
|
||||||
configuration: CordaRPCClientConfiguration = CordaRPCClientConfiguration.default,
|
configuration: CordaRPCClientConfiguration = CordaRPCClientConfiguration.default,
|
||||||
initialiseSerialization: Boolean = true
|
initialiseSerialization: Boolean = true
|
||||||
) {
|
) {
|
||||||
@ -50,7 +49,7 @@ class CordaRPCClient(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val rpcClient = RPCClient<CordaRPCOps>(
|
private val rpcClient = RPCClient<CordaRPCOps>(
|
||||||
tcpTransport(ConnectionDirection.Outbound(), hostAndPort, sslConfiguration),
|
tcpTransport(ConnectionDirection.Outbound(), hostAndPort, config = null),
|
||||||
configuration.toRpcClientConfiguration(),
|
configuration.toRpcClientConfiguration(),
|
||||||
KRYO_RPC_CLIENT_CONTEXT
|
KRYO_RPC_CLIENT_CONTEXT
|
||||||
)
|
)
|
||||||
|
@ -228,6 +228,9 @@ Release 1.0
|
|||||||
|
|
||||||
* ``@RPCSinceVersion``, ``RPCException`` and ``PermissionException`` have moved to ``net.corda.client.rpc``.
|
* ``@RPCSinceVersion``, ``RPCException`` and ``PermissionException`` have moved to ``net.corda.client.rpc``.
|
||||||
|
|
||||||
|
* Current implementation of SSL in ``CordaRPCClient`` has been removed until we have a better solution which doesn't rely
|
||||||
|
on the node's keystore.
|
||||||
|
|
||||||
Milestone 14
|
Milestone 14
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
package net.corda.nodeapi
|
package net.corda.nodeapi
|
||||||
|
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.utilities.toBase58String
|
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.messaging.MessageRecipientGroup
|
import net.corda.core.messaging.MessageRecipientGroup
|
||||||
import net.corda.core.messaging.MessageRecipients
|
import net.corda.core.messaging.MessageRecipients
|
||||||
import net.corda.core.messaging.SingleMessageRecipient
|
import net.corda.core.messaging.SingleMessageRecipient
|
||||||
import net.corda.core.internal.read
|
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
|
import net.corda.core.utilities.toBase58String
|
||||||
import net.corda.nodeapi.config.SSLConfiguration
|
import net.corda.nodeapi.config.SSLConfiguration
|
||||||
import java.security.KeyStore
|
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,22 +83,6 @@ abstract class ArtemisMessagingComponent : SingletonSerializeAsToken() {
|
|||||||
/** The config object is used to pass in the passwords for the certificate KeyStore and TrustStore */
|
/** The config object is used to pass in the passwords for the certificate KeyStore and TrustStore */
|
||||||
abstract val config: SSLConfiguration?
|
abstract val config: SSLConfiguration?
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns nothing if the keystore was opened OK or throws if not. Useful to check the password, as
|
|
||||||
* unfortunately Artemis tends to bury the exception when the password is wrong.
|
|
||||||
*/
|
|
||||||
fun checkStorePasswords() {
|
|
||||||
val config = config ?: return
|
|
||||||
arrayOf(config.sslKeystore, config.nodeKeystore).forEach {
|
|
||||||
it.read {
|
|
||||||
KeyStore.getInstance("JKS").load(it, config.keyStorePassword.toCharArray())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
config.trustStoreFile.read {
|
|
||||||
KeyStore.getInstance("JKS").load(it, config.trustStorePassword.toCharArray())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used for bridges creation.
|
// Used for bridges creation.
|
||||||
fun getArtemisPeerAddress(party: Party, address: NetworkHostAndPort, netMapName: CordaX500Name? = null): ArtemisPeerAddress {
|
fun getArtemisPeerAddress(party: Party, address: NetworkHostAndPort, netMapName: CordaX500Name? = null): ArtemisPeerAddress {
|
||||||
return if (party.name == netMapName) {
|
return if (party.name == netMapName) {
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package net.corda.services.messaging
|
package net.corda.services.messaging
|
||||||
|
|
||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.configureTestSSL
|
|
||||||
import net.corda.testing.messaging.SimpleMQClient
|
import net.corda.testing.messaging.SimpleMQClient
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException
|
|
||||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,11 +23,4 @@ class MQSecurityAsRPCTest : MQSecurityTest() {
|
|||||||
override fun startAttacker(attacker: SimpleMQClient) {
|
override fun startAttacker(attacker: SimpleMQClient) {
|
||||||
attacker.start(extraRPCUsers[0].username, extraRPCUsers[0].password, false)
|
attacker.start(extraRPCUsers[0].username, extraRPCUsers[0].password, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `login to a ssl port as a RPC user`() {
|
|
||||||
assertThatExceptionOfType(ActiveMQSecurityException::class.java).isThrownBy {
|
|
||||||
loginToRPC(alice.internals.configuration.p2pAddress, extraRPCUsers[0], configureTestSSL())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -153,8 +153,8 @@ abstract class MQSecurityTest : NodeBasedTest() {
|
|||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loginToRPC(target: NetworkHostAndPort, rpcUser: User, sslConfiguration: SSLConfiguration? = null): CordaRPCOps {
|
fun loginToRPC(target: NetworkHostAndPort, rpcUser: User): CordaRPCOps {
|
||||||
return CordaRPCClient(target, sslConfiguration, initialiseSerialization = false).start(rpcUser.username, rpcUser.password).proxy
|
return CordaRPCClient(target, initialiseSerialization = false).start(rpcUser.username, rpcUser.password).proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loginToRPCAndGetClientQueue(): String {
|
fun loginToRPCAndGetClientQueue(): String {
|
||||||
|
@ -20,15 +20,11 @@ import net.corda.core.utilities.seconds
|
|||||||
import net.corda.finance.plugin.registerFinanceJSONMappers
|
import net.corda.finance.plugin.registerFinanceJSONMappers
|
||||||
import net.corda.irs.contract.InterestRateSwap
|
import net.corda.irs.contract.InterestRateSwap
|
||||||
import net.corda.irs.utilities.uploadFile
|
import net.corda.irs.utilities.uploadFile
|
||||||
import net.corda.nodeapi.internal.ServiceInfo
|
|
||||||
import net.corda.node.services.config.FullNodeConfiguration
|
import net.corda.node.services.config.FullNodeConfiguration
|
||||||
import net.corda.node.services.transactions.SimpleNotaryService
|
import net.corda.node.services.transactions.SimpleNotaryService
|
||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.DUMMY_BANK_A
|
import net.corda.nodeapi.internal.ServiceInfo
|
||||||
import net.corda.testing.DUMMY_BANK_B
|
import net.corda.testing.*
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
|
||||||
import net.corda.testing.IntegrationTestCategory
|
|
||||||
import net.corda.testing.chooseIdentity
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import net.corda.testing.http.HttpApi
|
import net.corda.testing.http.HttpApi
|
||||||
import org.apache.commons.io.IOUtils
|
import org.apache.commons.io.IOUtils
|
||||||
@ -45,7 +41,7 @@ class IRSDemoTest : IntegrationTestCategory {
|
|||||||
val log = loggerFor<IRSDemoTest>()
|
val log = loggerFor<IRSDemoTest>()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val rpcUser = User("user", "password", emptySet())
|
private val rpcUser = User("user", "password", setOf("ALL"))
|
||||||
private val currentDate: LocalDate = LocalDate.now()
|
private val currentDate: LocalDate = LocalDate.now()
|
||||||
private val futureDate: LocalDate = currentDate.plusMonths(6)
|
private val futureDate: LocalDate = currentDate.plusMonths(6)
|
||||||
private val maxWaitTime: Duration = 60.seconds
|
private val maxWaitTime: Duration = 60.seconds
|
||||||
@ -58,15 +54,16 @@ class IRSDemoTest : IntegrationTestCategory {
|
|||||||
providedName = DUMMY_NOTARY.name,
|
providedName = DUMMY_NOTARY.name,
|
||||||
advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))),
|
advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))),
|
||||||
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = listOf(rpcUser)),
|
startNode(providedName = DUMMY_BANK_A.name, rpcUsers = listOf(rpcUser)),
|
||||||
startNode(providedName = DUMMY_BANK_B.name)).map { it.getOrThrow() }
|
startNode(providedName = DUMMY_BANK_B.name))
|
||||||
|
.map { it.getOrThrow() }
|
||||||
|
|
||||||
log.info("All nodes started")
|
log.info("All nodes started")
|
||||||
|
|
||||||
val controllerAddrFuture = startWebserver(controller)
|
val (controllerAddr, nodeAAddr, nodeBAddr) = listOf(
|
||||||
val nodeAAddrFuture = startWebserver(nodeA)
|
startWebserver(controller),
|
||||||
val nodeBAddrFuture = startWebserver(nodeB)
|
startWebserver(nodeA),
|
||||||
val (controllerAddr, nodeAAddr, nodeBAddr) =
|
startWebserver(nodeB))
|
||||||
listOf(controllerAddrFuture, nodeAAddrFuture, nodeBAddrFuture).map { it.getOrThrow().listenAddress }
|
.map { it.getOrThrow().listenAddress }
|
||||||
|
|
||||||
log.info("All webservers started")
|
log.info("All webservers started")
|
||||||
|
|
||||||
|
@ -23,16 +23,14 @@ import net.corda.core.utilities.*
|
|||||||
import net.corda.node.internal.Node
|
import net.corda.node.internal.Node
|
||||||
import net.corda.node.internal.NodeStartup
|
import net.corda.node.internal.NodeStartup
|
||||||
import net.corda.node.internal.StartedNode
|
import net.corda.node.internal.StartedNode
|
||||||
import net.corda.nodeapi.internal.ServiceInfo
|
|
||||||
import net.corda.nodeapi.internal.ServiceType
|
|
||||||
import net.corda.node.services.config.*
|
import net.corda.node.services.config.*
|
||||||
import net.corda.node.services.network.NetworkMapService
|
import net.corda.node.services.network.NetworkMapService
|
||||||
import net.corda.node.services.transactions.RaftValidatingNotaryService
|
import net.corda.node.services.transactions.RaftValidatingNotaryService
|
||||||
import net.corda.node.utilities.ServiceIdentityGenerator
|
import net.corda.node.utilities.ServiceIdentityGenerator
|
||||||
import net.corda.nodeapi.ArtemisMessagingComponent
|
|
||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.nodeapi.config.SSLConfiguration
|
|
||||||
import net.corda.nodeapi.config.parseAs
|
import net.corda.nodeapi.config.parseAs
|
||||||
|
import net.corda.nodeapi.internal.ServiceInfo
|
||||||
|
import net.corda.nodeapi.internal.ServiceType
|
||||||
import net.corda.nodeapi.internal.addShutdownHook
|
import net.corda.nodeapi.internal.addShutdownHook
|
||||||
import net.corda.testing.*
|
import net.corda.testing.*
|
||||||
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
|
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
|
||||||
@ -178,6 +176,10 @@ interface DriverDSLInternalInterface : DriverDSLExposedInterface {
|
|||||||
|
|
||||||
sealed class NodeHandle {
|
sealed class NodeHandle {
|
||||||
abstract val nodeInfo: NodeInfo
|
abstract val nodeInfo: NodeInfo
|
||||||
|
/**
|
||||||
|
* Interface to the node's RPC system. The first RPC user will be used to login if are any, otherwise a default one
|
||||||
|
* will be added and that will be used.
|
||||||
|
*/
|
||||||
abstract val rpc: CordaRPCOps
|
abstract val rpc: CordaRPCOps
|
||||||
abstract val configuration: FullNodeConfiguration
|
abstract val configuration: FullNodeConfiguration
|
||||||
abstract val webAddress: NetworkHostAndPort
|
abstract val webAddress: NetworkHostAndPort
|
||||||
@ -627,20 +629,21 @@ class DriverDSL(
|
|||||||
_executorService?.shutdownNow()
|
_executorService?.shutdownNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun establishRpc(nodeAddress: NetworkHostAndPort, sslConfig: SSLConfiguration, processDeathFuture: CordaFuture<out Process>): CordaFuture<CordaRPCOps> {
|
private fun establishRpc(config: FullNodeConfiguration, processDeathFuture: CordaFuture<out Process>): CordaFuture<CordaRPCOps> {
|
||||||
val client = CordaRPCClient(nodeAddress, sslConfig, initialiseSerialization = false)
|
val rpcAddress = config.rpcAddress!!
|
||||||
|
val client = CordaRPCClient(rpcAddress, initialiseSerialization = false)
|
||||||
val connectionFuture = poll(executorService, "RPC connection") {
|
val connectionFuture = poll(executorService, "RPC connection") {
|
||||||
try {
|
try {
|
||||||
client.start(ArtemisMessagingComponent.NODE_USER, ArtemisMessagingComponent.NODE_USER)
|
client.start(config.rpcUsers[0].username, config.rpcUsers[0].password)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (processDeathFuture.isDone) throw e
|
if (processDeathFuture.isDone) throw e
|
||||||
log.error("Exception $e, Retrying RPC connection at $nodeAddress")
|
log.error("Exception $e, Retrying RPC connection at $rpcAddress")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return firstOf(connectionFuture, processDeathFuture) {
|
return firstOf(connectionFuture, processDeathFuture) {
|
||||||
if (it == processDeathFuture) {
|
if (it == processDeathFuture) {
|
||||||
throw ListenProcessDeathException(nodeAddress, processDeathFuture.getOrThrow())
|
throw ListenProcessDeathException(rpcAddress, processDeathFuture.getOrThrow())
|
||||||
}
|
}
|
||||||
val connection = connectionFuture.getOrThrow()
|
val connection = connectionFuture.getOrThrow()
|
||||||
shutdownManager.registerShutdown(connection::close)
|
shutdownManager.registerShutdown(connection::close)
|
||||||
@ -696,7 +699,7 @@ class DriverDSL(
|
|||||||
"extraAdvertisedServiceIds" to advertisedServices.map { it.toString() },
|
"extraAdvertisedServiceIds" to advertisedServices.map { it.toString() },
|
||||||
"networkMapService" to networkMapServiceConfigLookup(name),
|
"networkMapService" to networkMapServiceConfigLookup(name),
|
||||||
"useTestClock" to useTestClock,
|
"useTestClock" to useTestClock,
|
||||||
"rpcUsers" to rpcUsers.map { it.toMap() },
|
"rpcUsers" to if (rpcUsers.isEmpty()) defaultRpcUserList else rpcUsers.map { it.toMap() },
|
||||||
"verifierType" to verifierType.name
|
"verifierType" to verifierType.name
|
||||||
) + customOverrides
|
) + customOverrides
|
||||||
)
|
)
|
||||||
@ -709,14 +712,14 @@ class DriverDSL(
|
|||||||
portAllocation.nextHostAndPort() // rpcAddress
|
portAllocation.nextHostAndPort() // rpcAddress
|
||||||
val webAddress = portAllocation.nextHostAndPort()
|
val webAddress = portAllocation.nextHostAndPort()
|
||||||
val name = CordaX500Name.parse(node.name)
|
val name = CordaX500Name.parse(node.name)
|
||||||
|
val rpcUsers = node.rpcUsers
|
||||||
val config = ConfigHelper.loadConfig(
|
val config = ConfigHelper.loadConfig(
|
||||||
baseDirectory = baseDirectory(name),
|
baseDirectory = baseDirectory(name),
|
||||||
allowMissingConfig = true,
|
allowMissingConfig = true,
|
||||||
configOverrides = node.config + mapOf(
|
configOverrides = node.config + mapOf(
|
||||||
"extraAdvertisedServiceIds" to node.advertisedServices,
|
"extraAdvertisedServiceIds" to node.advertisedServices,
|
||||||
"networkMapService" to networkMapServiceConfigLookup(name),
|
"networkMapService" to networkMapServiceConfigLookup(name),
|
||||||
"rpcUsers" to node.rpcUsers,
|
"rpcUsers" to if (rpcUsers.isEmpty()) defaultRpcUserList else rpcUsers,
|
||||||
"notaryClusterAddresses" to node.notaryClusterAddresses
|
"notaryClusterAddresses" to node.notaryClusterAddresses
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -808,6 +811,7 @@ class DriverDSL(
|
|||||||
|
|
||||||
override fun startDedicatedNetworkMapService(startInProcess: Boolean?): CordaFuture<NodeHandle> {
|
override fun startDedicatedNetworkMapService(startInProcess: Boolean?): CordaFuture<NodeHandle> {
|
||||||
val webAddress = portAllocation.nextHostAndPort()
|
val webAddress = portAllocation.nextHostAndPort()
|
||||||
|
val rpcAddress = portAllocation.nextHostAndPort()
|
||||||
val networkMapLegalName = networkMapStartStrategy.legalName
|
val networkMapLegalName = networkMapStartStrategy.legalName
|
||||||
val config = ConfigHelper.loadConfig(
|
val config = ConfigHelper.loadConfig(
|
||||||
baseDirectory = baseDirectory(networkMapLegalName),
|
baseDirectory = baseDirectory(networkMapLegalName),
|
||||||
@ -817,6 +821,8 @@ class DriverDSL(
|
|||||||
// TODO: remove the webAddress as NMS doesn't need to run a web server. This will cause all
|
// TODO: remove the webAddress as NMS doesn't need to run a web server. This will cause all
|
||||||
// node port numbers to be shifted, so all demos and docs need to be updated accordingly.
|
// node port numbers to be shifted, so all demos and docs need to be updated accordingly.
|
||||||
"webAddress" to webAddress.toString(),
|
"webAddress" to webAddress.toString(),
|
||||||
|
"rpcAddress" to rpcAddress.toString(),
|
||||||
|
"rpcUsers" to defaultRpcUserList,
|
||||||
"p2pAddress" to dedicatedNetworkMapAddress.toString(),
|
"p2pAddress" to dedicatedNetworkMapAddress.toString(),
|
||||||
"useTestClock" to useTestClock,
|
"useTestClock" to useTestClock,
|
||||||
"extraAdvertisedServiceIds" to listOf(ServiceInfo(NetworkMapService.type).toString())
|
"extraAdvertisedServiceIds" to listOf(ServiceInfo(NetworkMapService.type).toString())
|
||||||
@ -838,7 +844,7 @@ class DriverDSL(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
return nodeAndThreadFuture.flatMap { (node, thread) ->
|
return nodeAndThreadFuture.flatMap { (node, thread) ->
|
||||||
establishRpc(nodeConfiguration.p2pAddress, nodeConfiguration, openFuture()).flatMap { rpc ->
|
establishRpc(nodeConfiguration, openFuture()).flatMap { rpc ->
|
||||||
rpc.waitUntilNetworkReady().map {
|
rpc.waitUntilNetworkReady().map {
|
||||||
NodeHandle.InProcess(rpc.nodeInfo(), rpc, nodeConfiguration, webAddress, node, thread)
|
NodeHandle.InProcess(rpc.nodeInfo(), rpc, nodeConfiguration, webAddress, node, thread)
|
||||||
}
|
}
|
||||||
@ -852,8 +858,7 @@ class DriverDSL(
|
|||||||
val processDeathFuture = poll(executorService, "process death") {
|
val processDeathFuture = poll(executorService, "process death") {
|
||||||
if (process.isAlive) null else process
|
if (process.isAlive) null else process
|
||||||
}
|
}
|
||||||
// We continue to use SSL enabled port for RPC when its for node user.
|
establishRpc(nodeConfiguration, processDeathFuture).flatMap { rpc ->
|
||||||
establishRpc(nodeConfiguration.p2pAddress, nodeConfiguration, processDeathFuture).flatMap { rpc ->
|
|
||||||
// Call waitUntilNetworkReady in background in case RPC is failing over:
|
// Call waitUntilNetworkReady in background in case RPC is failing over:
|
||||||
val networkMapFuture = executorService.fork {
|
val networkMapFuture = executorService.fork {
|
||||||
rpc.waitUntilNetworkReady()
|
rpc.waitUntilNetworkReady()
|
||||||
@ -877,6 +882,8 @@ class DriverDSL(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private val defaultRpcUserList = listOf(User("default", "default", setOf("ALL")).toMap())
|
||||||
|
|
||||||
private val names = arrayOf(
|
private val names = arrayOf(
|
||||||
ALICE.name,
|
ALICE.name,
|
||||||
BOB.name,
|
BOB.name,
|
||||||
|
@ -235,7 +235,7 @@ class NodeConfigTest {
|
|||||||
val webConfig = WebServerConfig(baseDir, nodeConfig)
|
val webConfig = WebServerConfig(baseDir, nodeConfig)
|
||||||
|
|
||||||
assertEquals(localPort(20001), webConfig.webAddress)
|
assertEquals(localPort(20001), webConfig.webAddress)
|
||||||
assertEquals(localPort(10001), webConfig.p2pAddress)
|
assertEquals(localPort(40002), webConfig.rpcAddress)
|
||||||
assertEquals("trustpass", webConfig.trustStorePassword)
|
assertEquals("trustpass", webConfig.trustStorePassword)
|
||||||
assertEquals("cordacadevpass", webConfig.keyStorePassword)
|
assertEquals("cordacadevpass", webConfig.keyStorePassword)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.webserver
|
|||||||
|
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
|
import net.corda.nodeapi.User
|
||||||
import net.corda.nodeapi.config.NodeSSLConfiguration
|
import net.corda.nodeapi.config.NodeSSLConfiguration
|
||||||
import net.corda.nodeapi.config.getValue
|
import net.corda.nodeapi.config.getValue
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@ -15,6 +16,7 @@ class WebServerConfig(override val baseDirectory: Path, val config: Config) : No
|
|||||||
val exportJMXto: String get() = "http"
|
val exportJMXto: String get() = "http"
|
||||||
val useHTTPS: Boolean by config
|
val useHTTPS: Boolean by config
|
||||||
val myLegalName: String by config
|
val myLegalName: String by config
|
||||||
val p2pAddress: NetworkHostAndPort by config // TODO: Use RPC port instead of P2P port (RPC requires authentication, P2P does not)
|
val rpcAddress: NetworkHostAndPort by config
|
||||||
val webAddress: NetworkHostAndPort by config
|
val webAddress: NetworkHostAndPort by config
|
||||||
|
val rpcUsers: List<User> by config
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import net.corda.client.jackson.JacksonSupport
|
|||||||
import net.corda.client.rpc.CordaRPCClient
|
import net.corda.client.rpc.CordaRPCClient
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.nodeapi.ArtemisMessagingComponent
|
|
||||||
import net.corda.webserver.WebServerConfig
|
import net.corda.webserver.WebServerConfig
|
||||||
import net.corda.webserver.converters.CordaConverterProvider
|
import net.corda.webserver.converters.CordaConverterProvider
|
||||||
import net.corda.webserver.services.WebServerPluginRegistry
|
import net.corda.webserver.services.WebServerPluginRegistry
|
||||||
@ -26,6 +25,7 @@ import org.slf4j.LoggerFactory
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.Writer
|
import java.io.Writer
|
||||||
import java.lang.reflect.InvocationTargetException
|
import java.lang.reflect.InvocationTargetException
|
||||||
|
import java.nio.file.NoSuchFileException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
import javax.ws.rs.core.MediaType
|
import javax.ws.rs.core.MediaType
|
||||||
@ -187,12 +187,12 @@ class NodeWebServer(val config: WebServerConfig) {
|
|||||||
try {
|
try {
|
||||||
return connectLocalRpcAsNodeUser()
|
return connectLocalRpcAsNodeUser()
|
||||||
} catch (e: ActiveMQNotConnectedException) {
|
} catch (e: ActiveMQNotConnectedException) {
|
||||||
log.debug("Could not connect to ${config.p2pAddress} 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
|
||||||
// Keep the fully qualified package name due to collisions with the Kotlin stdlib
|
// Keep the fully qualified package name due to collisions with the Kotlin stdlib
|
||||||
// exception of the same name
|
// exception of the same name
|
||||||
} catch (e: java.nio.file.NoSuchFileException) {
|
} catch (e: NoSuchFileException) {
|
||||||
log.debug("Tried to open a file that doesn't yet exist, retrying", e)
|
log.debug("Tried to open a file that doesn't yet exist, retrying", e)
|
||||||
Thread.sleep(retryDelay)
|
Thread.sleep(retryDelay)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
@ -205,9 +205,10 @@ class NodeWebServer(val config: WebServerConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun connectLocalRpcAsNodeUser(): CordaRPCOps {
|
private fun connectLocalRpcAsNodeUser(): CordaRPCOps {
|
||||||
log.info("Connecting to node at ${config.p2pAddress} as node user")
|
val rpcUser = config.rpcUsers.firstOrNull() ?: throw IllegalArgumentException("The node config has not specified any RPC users")
|
||||||
val client = CordaRPCClient(config.p2pAddress, config)
|
log.info("Connecting to node at ${config.rpcAddress} as $rpcUser")
|
||||||
val connection = client.start(ArtemisMessagingComponent.NODE_USER, ArtemisMessagingComponent.NODE_USER)
|
val client = CordaRPCClient(config.rpcAddress)
|
||||||
|
val connection = client.start(rpcUser.username, rpcUser.password)
|
||||||
return connection.proxy
|
return connection.proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user