public class RoutingTableImpl extends BasicModule implements RoutingTable, ClusterEventListener
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.
Modifier and Type | Field and Description |
---|---|
static String |
ANONYMOUS_C2S_CACHE_NAME |
static String |
C2S_CACHE_NAME |
static String |
C2S_SESSION_NAME |
static String |
COMPONENT_CACHE_NAME |
static String |
S2S_CACHE_NAME |
Constructor and Description |
---|
RoutingTableImpl() |
Modifier and Type | Method and Description |
---|---|
boolean |
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 |
addServerRoute(DomainPair address,
LocalOutgoingServerSession destination)
Adds a route to the routing table for the specified outoing server session.
|
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.
|
ClientSession |
getClientRoute(org.xmpp.packet.JID jid)
Returns the client session associated to the specified XMPP address or null
if none was found.
|
Collection<ClientSession> |
getClientsRoutes(boolean onlyLocal)
Returns collection of client sessions authenticated with the server.
|
Collection<String> |
getComponentsDomains()
Returns domains of components hosted by the server.
|
RemotePacketRouter |
getRemotePacketRouter()
Returns the
RemotePacketRouter to use for deliverying packets to entities hosted
in remote nodes of the cluster or null 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.
|
Collection<String> |
getServerHostnames()
Returns a collection with the hostnames of the remote servers that currently may receive
packets sent from this server.
|
OutgoingServerSession |
getServerRoute(DomainPair jids)
Returns the outgoing server session associated to the specified XMPP address or null
if none was found.
|
Collection<DomainPair> |
getServerRoutes() |
int |
getServerSessionsCount()
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)
Returns true if an anonymous user with the specified full JID is currently logged.
|
boolean |
isLocalRoute(org.xmpp.packet.JID jid)
Returns true if the specified address belongs to a route that is hosted by this JVM.
|
void |
joinedCluster()
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 |
leftCluster()
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 |
markedAsSeniorClusterMember()
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 outoing server has been successfully removed.
|
void |
routePacket(org.xmpp.packet.JID jid,
org.xmpp.packet.Packet packet,
boolean fromServer)
Routes a packet to the specified address.
|
void |
setRemotePacketRouter(RemotePacketRouter remotePacketRouter)
Sets the
RemotePacketRouter to use for deliverying packets to entities hosted
in remote nodes of the cluster. |
void |
start()
Starts the basic module.
|
void |
stop()
Stops the basic module.
|
destroy, getName
public static final String C2S_CACHE_NAME
public static final String ANONYMOUS_C2S_CACHE_NAME
public static final String S2S_CACHE_NAME
public static final String COMPONENT_CACHE_NAME
public static final String C2S_SESSION_NAME
public void addServerRoute(DomainPair address, LocalOutgoingServerSession destination)
RoutingTable
addServerRoute
in interface RoutingTable
address
- the address associated to the route.destination
- the outgoing server session.public void addComponentRoute(org.xmpp.packet.JID route, RoutableChannelHandler destination)
RoutingTable
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.
addComponentRoute
in interface RoutingTable
route
- the address associated to the route.destination
- the component.public boolean addClientRoute(org.xmpp.packet.JID route, LocalClientSession destination)
RoutingTable
addClientRoute
in interface RoutingTable
route
- the address associated to the route.destination
- the client session.public void broadcastPacket(org.xmpp.packet.Message packet, boolean onlyLocal)
RoutingTable
broadcastPacket
in interface RoutingTable
packet
- the message to broadcast.onlyLocal
- true if only client sessions connecte to the local JVM will get the message.public void routePacket(org.xmpp.packet.JID jid, org.xmpp.packet.Packet packet, boolean fromServer) throws PacketException
RoutingTable
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
and
Presences
are only sent to available client sessions whilst
IQs
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.
routePacket
in interface RoutingTable
jid
- the recipient of the packet to route.packet
- the packet to route.fromServer
- true if the packet was created by the server. This packets should
always be deliveredPacketException
- thrown if the packet is malformed (results in the sender's
session being shutdown).public ClientSession getClientRoute(org.xmpp.packet.JID jid)
RoutingTable
getClientRoute
in interface RoutingTable
jid
- the address of the session.public Collection<ClientSession> getClientsRoutes(boolean onlyLocal)
RoutingTable
getClientsRoutes
in interface RoutingTable
onlyLocal
- true if only client sessions connected to this JVM must be considered.public OutgoingServerSession getServerRoute(DomainPair jids)
RoutingTable
getServerRoute
in interface RoutingTable
public Collection<String> getServerHostnames()
RoutingTable
getServerHostnames
in interface RoutingTable
public Collection<DomainPair> getServerRoutes()
getServerRoutes
in interface RoutingTable
public int getServerSessionsCount()
RoutingTable
getServerSessionsCount
in interface RoutingTable
public Collection<String> getComponentsDomains()
RoutingTable
getComponentsDomains
in interface RoutingTable
public boolean hasClientRoute(org.xmpp.packet.JID jid)
RoutingTable
hasClientRoute
in interface RoutingTable
jid
- the full JID of the user.public boolean isAnonymousRoute(org.xmpp.packet.JID jid)
RoutingTable
isAnonymousRoute
in interface RoutingTable
jid
- the full JID of the anonymous user.public boolean isLocalRoute(org.xmpp.packet.JID jid)
RoutingTable
XMPPServer.isLocal(org.xmpp.packet.JID)
to figure out if the address
belongs to tge domain hosted by this server.isLocalRoute
in interface RoutingTable
jid
- the address of the route.public boolean hasServerRoute(DomainPair pair)
RoutingTable
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.
hasServerRoute
in interface RoutingTable
pair
- DomainPair that specifies the local/remote server address.public boolean hasComponentRoute(org.xmpp.packet.JID jid)
RoutingTable
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.
hasComponentRoute
in interface RoutingTable
jid
- JID that specifies the component address.public List<org.xmpp.packet.JID> getRoutes(org.xmpp.packet.JID route, org.xmpp.packet.JID requester)
RoutingTable
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 is null 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.
getRoutes
in interface RoutingTable
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.public boolean removeClientRoute(org.xmpp.packet.JID route)
RoutingTable
removeClientRoute
in interface RoutingTable
route
- the route to remove.public boolean removeServerRoute(DomainPair route)
RoutingTable
removeServerRoute
in interface RoutingTable
route
- the route to remove.public boolean removeComponentRoute(org.xmpp.packet.JID route)
RoutingTable
removeComponentRoute
in interface RoutingTable
route
- the route to remove.public void setRemotePacketRouter(RemotePacketRouter remotePacketRouter)
RoutingTable
RemotePacketRouter
to use for deliverying packets to entities hosted
in remote nodes of the cluster.setRemotePacketRouter
in interface RoutingTable
remotePacketRouter
- the RemotePacketRouter to use for deliverying packets to entities hosted
in remote nodes of the cluster.public RemotePacketRouter getRemotePacketRouter()
RoutingTable
RemotePacketRouter
to use for deliverying packets to entities hosted
in remote nodes of the cluster or null if none was set.getRemotePacketRouter
in interface RoutingTable
public void initialize(XMPPServer server)
BasicModule
Initializes the basic module.
Inheriting classes that choose to override this method MUST call this initialize() method before accessing BasicModule resources.
initialize
in interface Module
initialize
in class BasicModule
server
- the server hosting this module.public void start() throws IllegalStateException
BasicModule
Starts the basic module.
Inheriting classes that choose to override this method MUST call this start() method before accessing BasicModule resources.
start
in interface Module
start
in class BasicModule
IllegalStateException
- If start is called before initialize
successfully returnspublic void stop()
BasicModule
Stops the basic module.
Inheriting classes that choose to override this method MUST call this stop() method before accessing BasicModule resources.
stop
in interface Module
stop
in class BasicModule
public void joinedCluster()
ClusterEventListener
XMPPServer.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.
joinedCluster
in interface ClusterEventListener
public void joinedCluster(byte[] nodeID)
ClusterEventListener
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.
joinedCluster
in interface ClusterEventListener
nodeID
- ID of the node that joined the cluster.public void leftCluster()
ClusterEventListener
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 and joined 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.
leftCluster
in interface ClusterEventListener
public void leftCluster(byte[] nodeID)
ClusterEventListener
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 and joined 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.
leftCluster
in interface ClusterEventListener
nodeID
- ID of the node that is left the cluster.public void markedAsSeniorClusterMember()
ClusterEventListener
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()
and ClusterEventListener.joinedCluster()
events.
markedAsSeniorClusterMember
in interface ClusterEventListener
Copyright © 2003-2008 Jive Software.