public class NodeMessagingClient extends ArtemisMessagingComponent implements MessagingServiceInternal
This class implements the interface MessagingService
API using Apache Artemis, the successor to their ActiveMQ product.
Artemis is a message queue broker and here we run a client connecting to the specified broker instance
class ArtemisMessagingServer
. It's primarily concerned with peer-to-peer messaging.
Message handlers are run on the provided interface AffinityExecutor
synchronously, that is, the Artemis callback threads
are blocked until the handler is scheduled and completed. This allows backpressure to propagate from the given
executor through into Artemis and from there, back through to senders.
An implementation of interface CordaRPCOps
can be provided. If given, clients using the CordaMQClient RPC library can
invoke methods on the provided implementation. There is more documentation on this in the docsite and the
CordaRPCClient class.
Modifier and Type | Class and Description |
---|---|
static class |
NodeMessagingClient.Companion |
static class |
NodeMessagingClient.Handler
A registration to handle messages of different types
|
ArtemisMessagingComponent.ConnectionDirection, ArtemisMessagingComponent.NetworkMapAddress, ArtemisMessagingComponent.NodeAddress, ArtemisMessagingComponent.ServiceAddress
Modifier and Type | Field and Description |
---|---|
static NodeMessagingClient.Companion |
Companion |
static java.lang.String |
SESSION_ID_PROPERTY |
static java.lang.String |
TOPIC_PROPERTY |
CLIENTS_PREFIX, INTERNAL_PREFIX, NETWORK_MAP_QUEUE, NODE_USER, NOTIFICATIONS_ADDRESS, P2P_QUEUE, PEERS_PREFIX, PEER_USER, RPC_QUEUE_REMOVALS_QUEUE, RPC_REQUESTS_QUEUE, SERVICES_PREFIX, VERIFY_PEER_COMMON_NAME
Constructor and Description |
---|
NodeMessagingClient(NodeConfiguration config,
com.google.common.net.HostAndPort serverHostPort,
CompositeKey myIdentity,
AffinityExecutor nodeExecutor,
org.jetbrains.exposed.sql.Database database,
com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> networkMapRegistrationFuture)
This class implements the
interface MessagingService API using Apache Artemis, the successor to their ActiveMQ product.
Artemis is a message queue broker and here we run a client connecting to the specified broker instance
class ArtemisMessagingServer . It's primarily concerned with peer-to-peer messaging. |
Modifier and Type | Method and Description |
---|---|
MessageHandlerRegistration |
addMessageHandler(java.lang.String topic,
long sessionID,
kotlin.jvm.functions.Function2<? super net.corda.core.messaging.ReceivedMessage,? super net.corda.core.messaging.MessageHandlerRegistration,kotlin.Unit> callback)
The provided function will be invoked for each received message whose topic matches the given string. The callback
will run on threads provided by the messaging service, and the callback is expected to be thread safe as a result.
|
MessageHandlerRegistration |
addMessageHandler(TopicSession topicSession,
kotlin.jvm.functions.Function2<? super net.corda.core.messaging.ReceivedMessage,? super net.corda.core.messaging.MessageHandlerRegistration,kotlin.Unit> callback)
The provided function will be invoked for each received message whose topic and session matches. The callback
will run on the main server thread provided when the messaging service is constructed, and a database
transaction is set up for you automatically.
|
Message |
createMessage(TopicSession topicSession,
byte[] data,
java.util.UUID uuid)
Returns an initialised
interface Message with the current time, etc, already filled in. |
MessageRecipients |
getAddressOfParty(PartyInfo partyInfo)
Given information about either a specific node or a service returns its corresponding address
|
NodeConfiguration |
getConfig()
The config object is used to pass in the passwords for the certificate KeyStore and TrustStore
|
org.jetbrains.exposed.sql.Database |
getDatabase() |
SingleMessageRecipient |
getMyAddress()
Apart from the NetworkMapService this is the only other address accessible to the node outside of lookups against the NetworkMapCache.
|
CompositeKey |
getMyIdentity() |
com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> |
getNetworkMapRegistrationFuture() |
AffinityExecutor |
getNodeExecutor() |
com.google.common.net.HostAndPort |
getServerHostPort() |
void |
removeMessageHandler(MessageHandlerRegistration registration)
Removes a handler given the object returned from addMessageHandler. The callback will no longer be invoked once
this method has returned, although executions that are currently in flight will not be interrupted.
|
void |
run()
Starts the p2p event loop: this method only returns once
NodeMessagingClient.stop has been called. |
void |
send(Message message,
MessageRecipients target)
Sends a message to the given receiver. The details of how receivers are identified is up to the messaging
implementation: the type system provides an opaque high level view, with more fine grained control being
available via type casting. Once this function returns the message is queued for delivery but not necessarily
delivered: if the recipients are offline then the message could be queued hours or days later.
|
void |
start(RPCOps rpcOps,
RPCUserService userService) |
void |
stop()
Initiates shutdown: if called from a thread that isn't controlled by the executor passed to the constructor
then this will block until all in-flight messages have finished being handled and acknowledged. If called
from a thread that's a part of the
interface AffinityExecutor given to the constructor, it returns immediately and
shutdown is asynchronous. |
checkStorePasswords, expectedOnDefaultFileSystem, getConfig, tcpTransport, toHostAndPort
toToken
stop
addMessageHandler, addMessageHandler, createMessage, getAddressOfParty, getMyAddress, removeMessageHandler, send
toToken
public static java.lang.String TOPIC_PROPERTY
public static java.lang.String SESSION_ID_PROPERTY
public static NodeMessagingClient.Companion Companion
public NodeMessagingClient(NodeConfiguration config, com.google.common.net.HostAndPort serverHostPort, CompositeKey myIdentity, AffinityExecutor nodeExecutor, org.jetbrains.exposed.sql.Database database, com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> networkMapRegistrationFuture)
This class implements the interface MessagingService
API using Apache Artemis, the successor to their ActiveMQ product.
Artemis is a message queue broker and here we run a client connecting to the specified broker instance
class ArtemisMessagingServer
. It's primarily concerned with peer-to-peer messaging.
Message handlers are run on the provided interface AffinityExecutor
synchronously, that is, the Artemis callback threads
are blocked until the handler is scheduled and completed. This allows backpressure to propagate from the given
executor through into Artemis and from there, back through to senders.
An implementation of interface CordaRPCOps
can be provided. If given, clients using the CordaMQClient RPC library can
invoke methods on the provided implementation. There is more documentation on this in the docsite and the
CordaRPCClient class.
config
- The config object is used to pass in the passwords for the certificate KeyStore and TrustStoreserverHostPort
- The address of the broker instance to connect to (might be running in the same process)myIdentity
- Either the public key to be used as the ArtemisMQ address and queue name for the node globally, or null to indicate
that this is a NetworkMapService node which will be bound globally to the name "networkmap"nodeExecutor
- An executor to run received message tasks upon.interface MessagingService
,
class ArtemisMessagingServer
,
interface AffinityExecutor
,
interface CordaRPCOps
public SingleMessageRecipient getMyAddress()
Apart from the NetworkMapService this is the only other address accessible to the node outside of lookups against the NetworkMapCache.
public void start(RPCOps rpcOps, RPCUserService userService)
public void run()
Starts the p2p event loop: this method only returns once NodeMessagingClient.stop
has been called.
This actually runs as two sequential loops. The first subscribes for and receives only network map messages until we get our network map fetch response. At that point the filtering consumer is closed and we proceed to the second loop and consume all messages via a new consumer without a filter applied.
NodeMessagingClient.stop
public void stop()
Initiates shutdown: if called from a thread that isn't controlled by the executor passed to the constructor
then this will block until all in-flight messages have finished being handled and acknowledged. If called
from a thread that's a part of the interface AffinityExecutor
given to the constructor, it returns immediately and
shutdown is asynchronous.
interface AffinityExecutor
public void send(Message message, MessageRecipients target)
Sends a message to the given receiver. The details of how receivers are identified is up to the messaging implementation: the type system provides an opaque high level view, with more fine grained control being available via type casting. Once this function returns the message is queued for delivery but not necessarily delivered: if the recipients are offline then the message could be queued hours or days later.
There is no way to know if a message has been received. If your flow requires this, you need the recipient to send an ACK message back.
public MessageHandlerRegistration addMessageHandler(java.lang.String topic, long sessionID, kotlin.jvm.functions.Function2<? super net.corda.core.messaging.ReceivedMessage,? super net.corda.core.messaging.MessageHandlerRegistration,kotlin.Unit> callback)
The provided function will be invoked for each received message whose topic matches the given string. The callback will run on threads provided by the messaging service, and the callback is expected to be thread safe as a result.
The returned object is an opaque handle that may be used to un-register handlers later with NodeMessagingClient.removeMessageHandler
.
The handle is passed to the callback as well, to avoid race conditions whereby the callback wants to unregister
itself and yet addMessageHandler hasn't returned the handle yet.
topic
- identifier for the general subject of the message, for example "platform.network_map.fetch".
The topic can be the empty string to match all messages (session ID must be DEFAULT_SESSION_ID).sessionID
- identifier for the session the message is part of. For services listening before
a session is established, use DEFAULT_SESSION_ID.NodeMessagingClient.removeMessageHandler
public MessageHandlerRegistration addMessageHandler(TopicSession topicSession, kotlin.jvm.functions.Function2<? super net.corda.core.messaging.ReceivedMessage,? super net.corda.core.messaging.MessageHandlerRegistration,kotlin.Unit> callback)
The provided function will be invoked for each received message whose topic and session matches. The callback will run on the main server thread provided when the messaging service is constructed, and a database transaction is set up for you automatically.
The returned object is an opaque handle that may be used to un-register handlers later with NodeMessagingClient.removeMessageHandler
.
The handle is passed to the callback as well, to avoid race conditions whereby the callback wants to unregister
itself and yet addMessageHandler hasn't returned the handle yet.
topicSession
- identifier for the topic and session to listen for messages arriving on.NodeMessagingClient.removeMessageHandler
public void removeMessageHandler(MessageHandlerRegistration registration)
Removes a handler given the object returned from addMessageHandler. The callback will no longer be invoked once this method has returned, although executions that are currently in flight will not be interrupted.
public Message createMessage(TopicSession topicSession, byte[] data, java.util.UUID uuid)
Returns an initialised interface Message
with the current time, etc, already filled in.
topicSession
- identifier for the topic and session the message is sent to.interface Message
public MessageRecipients getAddressOfParty(PartyInfo partyInfo)
Given information about either a specific node or a service returns its corresponding address
public NodeConfiguration getConfig()
The config object is used to pass in the passwords for the certificate KeyStore and TrustStore
public com.google.common.net.HostAndPort getServerHostPort()
public CompositeKey getMyIdentity()
public AffinityExecutor getNodeExecutor()
public org.jetbrains.exposed.sql.Database getDatabase()
public com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> getNetworkMapRegistrationFuture()