mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
RPC: make RPCConnection non-internal, as it's a core API. Move docs around so they're on public API not internal API.
This commit is contained in:
parent
e49da94418
commit
c79d14cb6e
@ -1,6 +1,5 @@
|
||||
package net.corda.client.rpc;
|
||||
|
||||
import net.corda.client.rpc.internal.RPCClient;
|
||||
import net.corda.core.concurrent.CordaFuture;
|
||||
import net.corda.core.contracts.Amount;
|
||||
import net.corda.core.messaging.CordaRPCOps;
|
||||
@ -42,7 +41,7 @@ public class CordaRPCJavaClientTest extends NodeBasedTest {
|
||||
|
||||
private StartedNode<Node> node;
|
||||
private CordaRPCClient client;
|
||||
private RPCClient.RPCConnection<CordaRPCOps> connection = null;
|
||||
private RPCConnection<CordaRPCOps> connection = null;
|
||||
private CordaRPCOps rpcProxy;
|
||||
|
||||
private void login(String username, String password) {
|
||||
|
@ -10,31 +10,62 @@ import net.corda.nodeapi.ConnectionDirection
|
||||
import net.corda.nodeapi.internal.serialization.KRYO_RPC_CLIENT_CONTEXT
|
||||
import java.time.Duration
|
||||
|
||||
/** @see RPCClient.RPCConnection */
|
||||
class CordaRPCConnection internal constructor(
|
||||
connection: RPCClient.RPCConnection<CordaRPCOps>
|
||||
) : RPCClient.RPCConnection<CordaRPCOps> by connection
|
||||
/**
|
||||
* This class is essentially just a wrapper for an RPCConnection<CordaRPCOps> and can be treated identically.
|
||||
*
|
||||
* @see RPCConnection
|
||||
*/
|
||||
class CordaRPCConnection internal constructor(connection: RPCConnection<CordaRPCOps>) : RPCConnection<CordaRPCOps> by connection
|
||||
|
||||
/** @see RPCClientConfiguration */
|
||||
data class CordaRPCClientConfiguration(
|
||||
val connectionMaxRetryInterval: Duration
|
||||
) {
|
||||
/**
|
||||
* Can be used to configure the RPC client connection.
|
||||
*
|
||||
* @property connectionMaxRetryInterval How much time to wait between connection retries if the server goes down. This
|
||||
* time will be reached via exponential backoff.
|
||||
*/
|
||||
data class CordaRPCClientConfiguration(val connectionMaxRetryInterval: Duration) {
|
||||
internal fun toRpcClientConfiguration(): RPCClientConfiguration {
|
||||
return RPCClientConfiguration.default.copy(
|
||||
connectionMaxRetryInterval = connectionMaxRetryInterval
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Returns the default configuration we recommend you use.
|
||||
*/
|
||||
@JvmStatic
|
||||
val default = CordaRPCClientConfiguration(
|
||||
connectionMaxRetryInterval = RPCClientConfiguration.default.connectionMaxRetryInterval
|
||||
)
|
||||
val default = CordaRPCClientConfiguration(connectionMaxRetryInterval = RPCClientConfiguration.default.connectionMaxRetryInterval)
|
||||
}
|
||||
}
|
||||
|
||||
/** @see RPCClient */
|
||||
//TODO Add SSL support
|
||||
class CordaRPCClient(
|
||||
/**
|
||||
* An RPC client connects to the specified server and allows you to make calls to the server that perform various
|
||||
* useful tasks. Please see the Client RPC section of docs.corda.net to learn more about how this API works. A brief
|
||||
* description is provided here.
|
||||
*
|
||||
* Calling [start] returns an [RPCConnection] containing a proxy that lets you invoke RPCs on the server. Calls on
|
||||
* it block, and if the server throws an exception then it will be rethrown on the client. Proxies are thread safe and
|
||||
* may be used to invoke multiple RPCs in parallel.
|
||||
*
|
||||
* RPC sends and receives are logged on the net.corda.rpc logger.
|
||||
*
|
||||
* The [CordaRPCOps] defines what client RPCs are available. If an RPC returns an [rx.Observable] anywhere in the object
|
||||
* graph returned then the server-side observable is transparently forwarded to the client side here.
|
||||
* *You are expected to use it*. The server will begin sending messages immediately that will be buffered on the
|
||||
* client, you are expected to drain by subscribing to the returned observer. You can opt-out of this by simply
|
||||
* calling the [net.corda.client.rpc.notUsed] method on it.
|
||||
*
|
||||
* You don't have to explicitly close the observable if you actually subscribe to it: it will close itself and free up
|
||||
* the server-side resources either when the client or JVM itself is shutdown, or when there are no more subscribers to
|
||||
* it. Once all the subscribers to a returned observable are unsubscribed or the observable completes successfully or
|
||||
* with an error, the observable is closed and you can't then re-subscribe again: you'll have to re-request a fresh
|
||||
* observable with another RPC.
|
||||
*
|
||||
* @param hostAndPort The network address to connect to.
|
||||
* @param configuration An optional configuration used to tweak client behaviour.
|
||||
*/
|
||||
class CordaRPCClient @JvmOverloads constructor(
|
||||
hostAndPort: NetworkHostAndPort,
|
||||
configuration: CordaRPCClientConfiguration = CordaRPCClientConfiguration.default,
|
||||
initialiseSerialization: Boolean = true
|
||||
@ -54,10 +85,24 @@ class CordaRPCClient(
|
||||
KRYO_RPC_CLIENT_CONTEXT
|
||||
)
|
||||
|
||||
/**
|
||||
* Logs in to the target server and returns an active connection. The returned connection is a [java.io.Closeable]
|
||||
* and can be used with a try-with-resources statement. If you don't use that, you should use the
|
||||
* [RPCConnection.notifyServerAndClose] or [RPCConnection.forceClose] methods to dispose of the connection object
|
||||
* when done.
|
||||
*
|
||||
* @param username The username to authenticate with.
|
||||
* @param password The password to authenticate with.
|
||||
* @throws RPCException if the server version is too low or if the server isn't reachable within a reasonable timeout.
|
||||
*/
|
||||
fun start(username: String, password: String): CordaRPCConnection {
|
||||
return CordaRPCConnection(rpcClient.start(CordaRPCOps::class.java, username, password))
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper for Kotlin users that simply closes the connection after the block has executed. Be careful not to
|
||||
* over-use this, as setting up and closing connections takes time.
|
||||
*/
|
||||
inline fun <A> use(username: String, password: String, block: (CordaRPCConnection) -> A): A {
|
||||
return start(username, password).use(block)
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
package net.corda.client.rpc
|
||||
|
||||
import net.corda.core.messaging.RPCOps
|
||||
import java.io.Closeable
|
||||
|
||||
/**
|
||||
* Holds a [proxy] object implementing [I] that forwards requests to the RPC server. The server version can be queried
|
||||
* via this interface.
|
||||
*
|
||||
* [Closeable.close] may be used to shut down the connection and release associated resources. It is an
|
||||
* alias for [notifyServerAndClose].
|
||||
*/
|
||||
interface RPCConnection<out I : RPCOps> : Closeable {
|
||||
/**
|
||||
* Holds a synthetic class that automatically forwards method calls to the server, and returns the response.
|
||||
*/
|
||||
val proxy: I
|
||||
|
||||
/** The RPC protocol version reported by the server. */
|
||||
val serverProtocolVersion: Int
|
||||
|
||||
/**
|
||||
* Closes this client gracefully by sending a notification to the server, so it can immediately clean up resources.
|
||||
* If the server is not available this method may block for a short period until it's clear the server is not
|
||||
* coming back.
|
||||
*/
|
||||
fun notifyServerAndClose()
|
||||
|
||||
/**
|
||||
* Closes this client without notifying the server.
|
||||
*
|
||||
* The server will eventually clear out the RPC message queue and disconnect subscribed observers,
|
||||
* but this may take longer than desired, so to conserve resources you should normally use [notifyServerAndClose].
|
||||
* This method is helpful when the node may be shutting down or have already shut down and you don't want to
|
||||
* block waiting for it to come back, which typically happens in integration tests and demos rather than production.
|
||||
*/
|
||||
fun forceClose()
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package net.corda.client.rpc.internal
|
||||
|
||||
import net.corda.client.rpc.RPCConnection
|
||||
import net.corda.client.rpc.RPCException
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.internal.logElapsedTime
|
||||
@ -17,7 +18,6 @@ import net.corda.nodeapi.config.SSLConfiguration
|
||||
import org.apache.activemq.artemis.api.core.SimpleString
|
||||
import org.apache.activemq.artemis.api.core.TransportConfiguration
|
||||
import org.apache.activemq.artemis.api.core.client.ActiveMQClient
|
||||
import java.io.Closeable
|
||||
import java.lang.reflect.Proxy
|
||||
import java.time.Duration
|
||||
|
||||
@ -79,12 +79,6 @@ data class RPCClientConfiguration(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An RPC client that may be used to create connections to an RPC server.
|
||||
*
|
||||
* @param transport The Artemis transport to use to connect to the server.
|
||||
* @param rpcConfiguration Configuration used to tweak client behaviour.
|
||||
*/
|
||||
class RPCClient<I : RPCOps>(
|
||||
val transport: TransportConfiguration,
|
||||
val rpcConfiguration: RPCClientConfiguration = RPCClientConfiguration.default,
|
||||
@ -101,54 +95,6 @@ class RPCClient<I : RPCOps>(
|
||||
private val log = loggerFor<RPCClient<*>>()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds a proxy object implementing [I] that forwards requests to the RPC server.
|
||||
*
|
||||
* [Closeable.close] may be used to shut down the connection and release associated resources.
|
||||
*/
|
||||
interface RPCConnection<out I : RPCOps> : Closeable {
|
||||
val proxy: I
|
||||
/** The RPC protocol version reported by the server */
|
||||
val serverProtocolVersion: Int
|
||||
|
||||
/**
|
||||
* Closes this client without notifying the server.
|
||||
* The server will eventually clear out the RPC message queue and disconnect subscribed observers,
|
||||
* but this may take longer than desired, so to conserve resources you should normally use [notifyServerAndClose].
|
||||
* This method is helpful when the node may be shutting down or
|
||||
* have already shut down and you don't want to block waiting for it to come back.
|
||||
*/
|
||||
fun forceClose()
|
||||
|
||||
/**
|
||||
* Closes this client gracefully by sending a notification to the server, so it can immediately clean up resources.
|
||||
* If the server is not available this method may block for a short period until it's clear the server is not coming back.
|
||||
*/
|
||||
fun notifyServerAndClose()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an [RPCConnection] containing a proxy that lets you invoke RPCs on the server. Calls on it block, and if
|
||||
* the server throws an exception then it will be rethrown on the client. Proxies are thread safe and may be used to
|
||||
* invoke multiple RPCs in parallel.
|
||||
*
|
||||
* RPC sends and receives are logged on the net.corda.rpc logger.
|
||||
*
|
||||
* The [RPCOps] defines what client RPCs are available. If an RPC returns an [Observable] anywhere in the object
|
||||
* graph returned then the server-side observable is transparently forwarded to the client side here.
|
||||
* *You are expected to use it*. The server will begin sending messages immediately that will be buffered on the
|
||||
* client, you are expected to drain by subscribing to the returned observer. You can opt-out of this by simply
|
||||
* calling the [net.corda.client.rpc.notUsed] method on it. You don't have to explicitly close the observable if you actually
|
||||
* subscribe to it: it will close itself and free up the server-side resources either when the client or JVM itself
|
||||
* is shutdown, or when there are no more subscribers to it. Once all the subscribers to a returned observable are
|
||||
* unsubscribed or the observable completes successfully or with an error, the observable is closed and you can't
|
||||
* then re-subscribe again: you'll have to re-request a fresh observable with another RPC.
|
||||
*
|
||||
* @param rpcOpsClass The [Class] of the RPC interface.
|
||||
* @param username The username to authenticate with.
|
||||
* @param password The password to authenticate with.
|
||||
* @throws RPCException if the server version is too low or if the server isn't reachable within the given time.
|
||||
*/
|
||||
fun start(
|
||||
rpcOpsClass: Class<I>,
|
||||
username: String,
|
||||
|
Loading…
Reference in New Issue
Block a user