Class RoutingTableImpl
- All Implemented Interfaces:
ClusterEventListener
,Module
,RoutingTable
When running inside of a cluster the routing table will also keep references to routes
hosted in other cluster nodes. A RemotePacketRouter
will be use to route packets
to routes hosted in other cluster nodes.
Failure to route a packet will end up sending IQRouter.routingFailed(JID, Packet)
,
MessageRouter.routingFailed(JID, Packet)
or PresenceRouter.routingFailed(JID, Packet)
depending on the packet type that tried to be sent.
- Author:
- Gaston Dombiak
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoid
addClientRoute
(org.xmpp.packet.JID route, LocalClientSession destination) Adds a route to the routing table for the specified client session.void
addComponentRoute
(org.xmpp.packet.JID route, RoutableChannelHandler destination) Adds a route to the routing table for the specified internal or external component.void
void
addServerRoute
(DomainPair address, LocalOutgoingServerSession destination) Adds a route to the routing table for the specified outgoing server session, or replaces a pre-existing one.void
broadcastPacket
(org.xmpp.packet.Message packet, boolean onlyLocal) Broadcasts the specified message to connected client sessions to the local node or across the cluster.Verifies thatusersCache
,localClientRoutingTable
androuteOwnersByClusterNode
are in a consistent state.Verifies thatcomponentsCache
,localComponentRoutingTable
andcomponentsByClusterNode
are in a consistent state.Verifies thatserversCache
,localServerRoutingTable
ands2sDomainPairsByClusterNode
are in a consistent state.Verifies thatusersSessionsCache
andusersCache
are in a consistent state.getClientRoute
(org.xmpp.packet.JID jid) Returns the client session associated to the specified XMPP address ornull
if none was found.getClientsRoutes
(boolean onlyLocal) Returns collection of client sessions authenticated with the server.Returns domains of components hosted by the server.Returns theRemotePacketRouter
to use for delivering packets to entities hosted in remote nodes of the cluster ornull
if none was set.List<org.xmpp.packet.JID>
getRoutes
(org.xmpp.packet.JID route, org.xmpp.packet.JID requester) Returns the list of routes associated to the specified route address.Returns a collection with the hostnames of the remote servers that currently may receive packets sent from this server.getServerRoute
(DomainPair jids) Returns the outgoing server session associated to the specified XMPP address ornull
if none was found.int
Returns the number of outgoing server sessions hosted in this JVM.boolean
hasClientRoute
(org.xmpp.packet.JID jid) Returns true if a registered user or anonymous user with the specified full JID is currently logged.boolean
hasComponentRoute
(org.xmpp.packet.JID jid) Returns true if an internal or external component is hosting the specified address.boolean
hasServerRoute
(DomainPair pair) Returns true if an outgoing server session exists to the specified remote server.void
initialize
(XMPPServer server) Initializes the basic module.boolean
isAnonymousRoute
(org.xmpp.packet.JID jid) Deprecated, for removal: This API element is subject to removal in a future version.boolean
isLocalRoute
(org.xmpp.packet.JID jid) Returns true if the specified address belongs to a route that is hosted by this JVM.void
Notification event indicating that this JVM is now part of a cluster.void
joinedCluster
(byte[] nodeID) Notification event indicating that another JVM is now part of a cluster.void
Notification event indicating that this JVM is no longer part of the cluster.void
leftCluster
(byte[] nodeID) Notification event indicating that another JVM is no longer part of the cluster.void
Notification event indicating that this JVM is now the senior cluster member.boolean
removeClientRoute
(org.xmpp.packet.JID route) Returns true if a route of a client session has been successfully removed.boolean
removeComponentRoute
(org.xmpp.packet.JID route) Returns true if a route of a component has been successfully removed.boolean
removeServerRoute
(DomainPair route) Returns true if a route to an outgoing server has been successfully removed.boolean
removeServerRoute
(DomainPair route, NodeID nodeID) Alternative toremoveServerRoute(DomainPair)
that can be used to remove a route hosted on another cluster node.void
routePacket
(org.xmpp.packet.JID jid, org.xmpp.packet.Packet packet) Routes a packet to the specified address.void
setRemotePacketRouter
(RemotePacketRouter remotePacketRouter) Sets theRemotePacketRouter
to use for delivering packets to entities hosted in remote nodes of the cluster.void
start()
Starts the basic module.void
stop()
Stops the basic module.Methods inherited from class org.jivesoftware.openfire.container.BasicModule
destroy, getName
-
Field Details
-
C2S_CACHE_NAME
- See Also:
-
S2S_CACHE_NAME
- See Also:
-
COMPONENT_CACHE_NAME
- See Also:
-
C2S_SESSION_NAME
- See Also:
-
-
Constructor Details
-
RoutingTableImpl
public RoutingTableImpl()
-
-
Method Details
-
addServerRoute
Description copied from interface:RoutingTable
Adds a route to the routing table for the specified outgoing server session, or replaces a pre-existing one. When running inside a cluster, this method must be invoked on the cluster node that is actually holding the physical connection to the remote server. Additionally, replacing a pre-existing server session can only occur on the same cluster node as the one that was holding the original session. A runtime exception is thrown when another cluster node attempts to replace the session.- Specified by:
addServerRoute
in interfaceRoutingTable
- Parameters:
address
- the address associated to the route.destination
- the outgoing server session.
-
addComponentRoute
Description copied from interface:RoutingTable
Adds a route to the routing table for the specified internal or external component.When running inside of a cluster this message
must
be sent from the cluster node that is actually hosting the component. The component may be available in all or some of cluster nodes. The routing table will keep track of all nodes hosting the component.- Specified by:
addComponentRoute
in interfaceRoutingTable
- Parameters:
route
- the address associated to the route.destination
- the component.
-
addClientRoute
Description copied from interface:RoutingTable
Adds a route to the routing table for the specified client session. The client session will be added as soon as the user has finished authenticating with the server. Moreover, when the user becomes available or unavailable then the routing table will get updated again. When running inside of a cluster this messagemust
be sent from the cluster node that is actually holding the client session.- Specified by:
addClientRoute
in interfaceRoutingTable
- Parameters:
route
- the address (a full JID) associated to the route.destination
- the client session.
-
broadcastPacket
public void broadcastPacket(org.xmpp.packet.Message packet, boolean onlyLocal) Description copied from interface:RoutingTable
Broadcasts the specified message to connected client sessions to the local node or across the cluster. Both available and unavailable client sessions will receive the message.- Specified by:
broadcastPacket
in interfaceRoutingTable
- Parameters:
packet
- the message to broadcast.onlyLocal
- true if only client sessions connect to the local JVM will get the message.
-
routePacket
public void routePacket(org.xmpp.packet.JID jid, org.xmpp.packet.Packet packet) throws PacketException Description copied from interface:RoutingTable
Routes a packet to the specified address. The packet destination can be a user on the local server, a component, or a foreign server.When routing a packet to a remote server then a new outgoing connection will be created to the remote server if none was found and the packet will be delivered. If an existing outgoing connection already exists then it will be used for delivering the packet. Moreover, when running inside of a cluster the node that has the actual outgoing connection will be requested to deliver the requested packet.
Packets routed to components will only be sent if the internal or external component is connected to the server. Moreover, when running inside of a cluster the node that is hosting the component will be requested to deliver the requested packet. It will be first checked if the component is available in this JVM and if not then the first cluster node found hosting the component will be used.
Packets routed to users will be delivered if the user is connected to the server. Depending on the packet type and the sender of the packet only available or all user sessions could be considered. For instance,
Messages
andPresences
are only sent to available client sessions whilstIQs
originated to the server can be sent to available or unavailable sessions. When running inside of a cluster the node that is hosting the user session will be requested to deliver the requested packet.- Specified by:
routePacket
in interfaceRoutingTable
- Parameters:
jid
- the recipient of the packet to route.packet
- the packet to route.- Throws:
PacketException
- thrown if the packet is malformed (results in the sender's session being shutdown).
-
getClientRoute
Description copied from interface:RoutingTable
Returns the client session associated to the specified XMPP address ornull
if none was found. When running inside of a cluster and a remote node is hosting the client session then a session surrage will be returned.- Specified by:
getClientRoute
in interfaceRoutingTable
- Parameters:
jid
- the address of the session.- Returns:
- the client session associated to the specified XMPP address or null if none was found.
-
getClientsRoutes
Description copied from interface:RoutingTable
Returns collection of client sessions authenticated with the server. When running inside of a cluster the returned sessions will include sessions connected to this JVM and also other cluster nodes. TODO Prevent usage of this message and change original requirement to avoid having to load all sessions. TODO This may not scale when hosting millions of sessions.- Specified by:
getClientsRoutes
in interfaceRoutingTable
- Parameters:
onlyLocal
- true if only client sessions connected to this JVM must be considered.- Returns:
- collection of client sessions authenticated with the server.
-
getServerRoute
Description copied from interface:RoutingTable
Returns the outgoing server session associated to the specified XMPP address ornull
if none was found. When running inside of a cluster and a remote node is hosting the session then a session surrage will be returned.- Specified by:
getServerRoute
in interfaceRoutingTable
- Parameters:
jids
- DomainPair that specifies the local/remote server address.- Returns:
- the outgoing server session associated to the specified XMPP address or null if none was found.
-
getServerHostnames
Description copied from interface:RoutingTable
Returns a collection with the hostnames of the remote servers that currently may receive packets sent from this server.- Specified by:
getServerHostnames
in interfaceRoutingTable
- Returns:
- a collection with the hostnames of the remote servers that currently may receive packets sent from this server.
-
getServerRoutes
- Specified by:
getServerRoutes
in interfaceRoutingTable
-
getServerSessionsCount
public int getServerSessionsCount()Description copied from interface:RoutingTable
Returns the number of outgoing server sessions hosted in this JVM. When running inside of a cluster you will need to get this value for each cluster node to learn the total number of outgoing server sessions.- Specified by:
getServerSessionsCount
in interfaceRoutingTable
- Returns:
- the number of outgoing server sessions hosted in this JVM.
-
getComponentsDomains
Description copied from interface:RoutingTable
Returns domains of components hosted by the server. When running in a cluster, domains of components running in any node will be returned.- Specified by:
getComponentsDomains
in interfaceRoutingTable
- Returns:
- domains of components hosted by the server.
-
hasClientRoute
public boolean hasClientRoute(org.xmpp.packet.JID jid) Description copied from interface:RoutingTable
Returns true if a registered user or anonymous user with the specified full JID is currently logged. When running inside of a cluster a true value will be returned as long as the user is connected to any cluster node. // TODO Should we care about available or not available????- Specified by:
hasClientRoute
in interfaceRoutingTable
- Parameters:
jid
- the full JID of the user.- Returns:
- true if a registered user or anonymous user with the specified full JID is currently logged.
-
isAnonymousRoute
@Deprecated(forRemoval=true, since="5.0.0") public boolean isAnonymousRoute(org.xmpp.packet.JID jid) Deprecated, for removal: This API element is subject to removal in a future version.Description copied from interface:RoutingTable
Returns true if an anonymous user with the specified full JID is currently logged. When running inside of a cluster a true value will be returned as long as the user is connected to any cluster node.- Specified by:
isAnonymousRoute
in interfaceRoutingTable
- Parameters:
jid
- the full JID of the anonymous user.- Returns:
- true if an anonymous user with the specified full JID is currently logged.
-
isLocalRoute
public boolean isLocalRoute(org.xmpp.packet.JID jid) Description copied from interface:RoutingTable
Returns true if the specified address belongs to a route that is hosted by this JVM. When running inside of a cluster each cluster node will host routes to local resources. A false value could either mean that the route is not hosted by this JVM but other cluster node or that there is no route to the specified address. UseXMPPServer.isLocal(org.xmpp.packet.JID)
to figure out if the address belongs to tge domain hosted by this server.- Specified by:
isLocalRoute
in interfaceRoutingTable
- Parameters:
jid
- the address of the route.- Returns:
- true if the specified address belongs to a route that is hosted by this JVM.
-
hasServerRoute
Description copied from interface:RoutingTable
Returns true if an outgoing server session exists to the specified remote server. The JID can be a full JID or a bare JID since only the domain of the specified address will be used to look up the route.When running inside of a cluster the look up will be done in all the cluster. So as long as a node has a connection to the remote server a true value will be returned.
- Specified by:
hasServerRoute
in interfaceRoutingTable
- Parameters:
pair
- DomainPair that specifies the local/remote server address.- Returns:
- true if an outgoing server session exists to the specified remote server.
-
hasComponentRoute
public boolean hasComponentRoute(org.xmpp.packet.JID jid) Description copied from interface:RoutingTable
Returns true if an internal or external component is hosting the specified address. The JID can be a full JID or a bare JID since only the domain of the specified address will be used to look up the route.When running inside of a cluster the look up will be done in all the cluster. So as long as a node is hosting the component a true value will be returned.
- Specified by:
hasComponentRoute
in interfaceRoutingTable
- Parameters:
jid
- JID that specifies the component address.- Returns:
- true if an internal or external component is hosting the specified address.
-
getRoutes
public List<org.xmpp.packet.JID> getRoutes(org.xmpp.packet.JID route, org.xmpp.packet.JID requester) Description copied from interface:RoutingTable
Returns the list of routes associated to the specified route address. When asking for routes to a remote server then the requested JID will be included as the only value of the returned collection. It is indifferent if an outgoing session to the specified remote server exists or not.When asking for routes to client sessions the specified route address could either be a full JID of a bare JID. In the case of a full JID, a single element will be included in the answer in case the specified full JID exists or an empty collection if the full JID does not exist. Moreover, when passing a bare JID a list of full JIDs will be returned for each available resource associated to the bare JID. In any case, only JIDs of
available
client sessions are returned. However, there is an exception with directed presences. Unavailable routes may be returned if and only if the owner of the route sent a directed presence to the requester thus becoming available to the requester. If requester isnull
then only available resources are considered.When asking for routes to components a single element will be returned in the answer only if an internal or external component is found for the specified route address. If no component was found then an empty collection will be returned.
- Specified by:
getRoutes
in interfaceRoutingTable
- Parameters:
route
- The address we want a route to.requester
- The address of the entity requesting the routes or null if we don't care about directed presences.- Returns:
- list of routes associated to the specified route address.
-
removeClientRoute
public boolean removeClientRoute(org.xmpp.packet.JID route) Description copied from interface:RoutingTable
Returns true if a route of a client session has been successfully removed. When running inside of a cluster this messagemust
be sent from the cluster node that is actually hosting the client session.- Specified by:
removeClientRoute
in interfaceRoutingTable
- Parameters:
route
- the route to remove.- Returns:
- true if a route of a client session has been successfully removed.
-
removeServerRoute
Description copied from interface:RoutingTable
Returns true if a route to an outgoing server has been successfully removed. When running inside of a cluster this messagemust
be sent from the cluster node that is actually holding the physical connection to the remote server.- Specified by:
removeServerRoute
in interfaceRoutingTable
- Parameters:
route
- the route to remove.- Returns:
- true if the route was successfully removed.
-
removeServerRoute
Alternative toremoveServerRoute(DomainPair)
that can be used to remove a route hosted on another cluster node. This method should only be used when recovering from cluster composition change. -
removeComponentRoute
public boolean removeComponentRoute(org.xmpp.packet.JID route) Description copied from interface:RoutingTable
Returns true if a route of a component has been successfully removed. Both internal and external components have a route in the table. When running inside of a cluster this messagemust
be sent from the cluster node that is actually hosting the component.- Specified by:
removeComponentRoute
in interfaceRoutingTable
- Parameters:
route
- the route to remove.- Returns:
- true if a route of a component has been successfully removed.
-
setRemotePacketRouter
Description copied from interface:RoutingTable
Sets theRemotePacketRouter
to use for delivering packets to entities hosted in remote nodes of the cluster.- Specified by:
setRemotePacketRouter
in interfaceRoutingTable
- Parameters:
remotePacketRouter
- the RemotePacketRouter to use for delivering packets to entities hosted in remote nodes of the cluster.
-
getRemotePacketRouter
Description copied from interface:RoutingTable
Returns theRemotePacketRouter
to use for delivering packets to entities hosted in remote nodes of the cluster ornull
if none was set.- Specified by:
getRemotePacketRouter
in interfaceRoutingTable
- Returns:
- the RemotePacketRouter to use for delivering packets to entities hosted in remote nodes of the cluster.
-
initialize
Description copied from class:BasicModule
Initializes the basic module.
Inheriting classes that choose to override this method MUST call this initialize() method before accessing BasicModule resources.
- Specified by:
initialize
in interfaceModule
- Overrides:
initialize
in classBasicModule
- Parameters:
server
- the server hosting this module.
-
start
Description copied from class:BasicModule
Starts the basic module.
Inheriting classes that choose to override this method MUST call this start() method before accessing BasicModule resources.
- Specified by:
start
in interfaceModule
- Overrides:
start
in classBasicModule
- Throws:
IllegalStateException
- If start is called before initialize successfully returns
-
stop
public void stop()Description copied from class:BasicModule
Stops the basic module.
Inheriting classes that choose to override this method MUST call this stop() method before accessing BasicModule resources.
- Specified by:
stop
in interfaceModule
- Overrides:
stop
in classBasicModule
-
clusteringStateConsistencyReportForServerRoutes
public com.google.common.collect.Multimap<String,String> clusteringStateConsistencyReportForServerRoutes()Verifies thatserversCache
,localServerRoutingTable
ands2sDomainPairsByClusterNode
are in a consistent state. Note that this operation can be costly in terms of resource usage. Use with caution in large / busy systems. The returned multi-map can contain up to four keys: info, fail, pass, data. All entry values are a human readable description of a checked characteristic. When the state is consistent, no 'fail' entries will be returned.- Returns:
- A consistency state report.
- See Also:
-
which is the cache that is used tho share data with other cluster nodes.
which holds content added to the cache by the local cluster node.
which holds content added to the cache by cluster nodes other than the local node.
-
clusteringStateConsistencyReportForComponentRoutes
public com.google.common.collect.Multimap<String,String> clusteringStateConsistencyReportForComponentRoutes()Verifies thatcomponentsCache
,localComponentRoutingTable
andcomponentsByClusterNode
are in a consistent state. Note that this operation can be costly in terms of resource usage. Use with caution in large / busy systems. The returned multi-map can contain up to four keys: info, fail, pass, data. All entry values are a human readable description of a checked characteristic. When the state is consistent, no 'fail' entries will be returned.- Returns:
- A consistency state report.
- See Also:
-
which is the cache that is used tho share data with other cluster nodes.
which holds content added to the cache by the local cluster node.
which holds content added to the cache by cluster nodes other than the local node.
-
clusteringStateConsistencyReportForClientRoutes
public com.google.common.collect.Multimap<String,String> clusteringStateConsistencyReportForClientRoutes()Verifies thatusersCache
,localClientRoutingTable
androuteOwnersByClusterNode
are in a consistent state. Note that this operation can be costly in terms of resource usage. Use with caution in large / busy systems. The returned multi-map can contain up to four keys: info, fail, pass, data. All entry values are a human readable description of a checked characteristic. When the state is consistent, no 'fail' entries will be returned.- Returns:
- A consistency state report.
- See Also:
-
which is the cache that is used tho share data with other cluster nodes.
which holds content added to the cache by the local cluster node.
which holds content added to the cache by cluster nodes other than the local node.
-
clusteringStateConsistencyReportForUsersSessions
public com.google.common.collect.Multimap<String,String> clusteringStateConsistencyReportForUsersSessions()Verifies thatusersSessionsCache
andusersCache
are in a consistent state. Note that this operation can be costly in terms of resource usage. Use with caution in large / busy systems. The returned multi-map can contain up to four keys: info, fail, pass, data. All entry values are a human readable description of a checked characteristic. When the state is consistent, no 'fail' entries will be returned.- Returns:
- A consistency state report.
- See Also:
-
which tracks user sessions.
which the cache that is used tho share data with other cluster nodes.
-
joinedCluster
public void joinedCluster()Description copied from interface:ClusterEventListener
Notification event indicating that this JVM is now part of a cluster. At this point theXMPPServer.getNodeID()
holds the new nodeID value.When joining the cluster as the senior cluster member the
ClusterEventListener.markedAsSeniorClusterMember()
event will be sent right after this event.At this point the CacheFactory holds clustered caches. That means that modifications to the caches will be reflected in the cluster. The clustered caches were just obtained from the cluster and no local cached data was automatically moved.
It is generally advisable that implementations of this method:- enrich clustered cache data, by (re)adding data from this JVM/cluster node to relevant caches
- invoke applicable event listeners, to reflect changes in availability of data on other cluster nodes.
- Specified by:
joinedCluster
in interfaceClusterEventListener
-
joinedCluster
public void joinedCluster(byte[] nodeID) Description copied from interface:ClusterEventListener
Notification event indicating that another JVM is now part of a cluster.At this point the CacheFactory of the new node holds clustered caches. That means that modifications to the caches of this JVM will be reflected in the cluster and in particular in the new node.
- Specified by:
joinedCluster
in interfaceClusterEventListener
- Parameters:
nodeID
- ID of the node that joined the cluster.
-
leftCluster
public void leftCluster()Description copied from interface:ClusterEventListener
Notification event indicating that this JVM is no longer part of the cluster. This could happen when disabling clustering support, removing the enterprise plugin that provides clustering support or connection to cluster got lost.Moreover, if we were in a "split brain" scenario (ie. separated cluster islands) and the island were this JVM belonged was marked as "old" then all nodes of that island will get the
left cluster event
andjoined cluster events
. That means that caches will be reset and thus will need to be repopulated again with fresh data from this JVM. This also includes the case where this JVM was the senior cluster member and when the islands met again then this JVM stopped being the senior member.At this point the CacheFactory holds local caches. That means that modifications to the caches will only affect this JVM. It is generally advisable that implementations of this method:
- restore relevant caches content, by repopulating the caches with data from this JVM/cluster node
- invoke applicable event listeners, to reflect changes in availability of data on other cluster nodes.
- Specified by:
leftCluster
in interfaceClusterEventListener
-
leftCluster
public void leftCluster(byte[] nodeID) Description copied from interface:ClusterEventListener
Notification event indicating that another JVM is no longer part of the cluster. This could happen when disabling clustering support, removing the enterprise plugin that provides clustering support or connection to cluster got lost.Moreover, if we were in a "split brain" scenario (ie. separated cluster islands) and the island were the other JVM belonged was marked as "old" then all nodes of that island will get the
left cluster event
andjoined cluster events
. That means that caches will be reset and thus will need to be repopulated again with fresh data from this JVM. This also includes the case where the other JVM was the senior cluster member and when the islands met again then the other JVM stopped being the senior member.At this point the CacheFactory of the leaving node holds local caches. That means that modifications to the caches of this JVM will not affect the leaving node but other cluster members. It is generally advisable that implementations of this method invoke applicable event listeners, to reflect changes in availability of data (related to the node that left). Often, this action is orchestrated by only one of the remaining cluster nodes: the senior member.
- Specified by:
leftCluster
in interfaceClusterEventListener
- Parameters:
nodeID
- ID of the node that is left the cluster.
-
markedAsSeniorClusterMember
public void markedAsSeniorClusterMember()Description copied from interface:ClusterEventListener
Notification event indicating that this JVM is now the senior cluster member. This could either happen when initially joining the cluster or when the senior cluster member node left the cluster and this JVM was marked as the new senior cluster member.Moreover, in the case of a "split brain" scenario (ie. separated cluster islands) each island will have its own senior cluster member. However, when the islands meet again there could only be one senior cluster member so one of the senior cluster members will stop playing that role. When that happens the JVM no longer playing that role will receive the
ClusterEventListener.leftCluster()
andClusterEventListener.joinedCluster()
events.- Specified by:
markedAsSeniorClusterMember
in interfaceClusterEventListener
-
addLocalClientRoutesToCache
public void addLocalClientRoutesToCache()
-