/* * Copyright (C) 2004-2008 Jive Software, 2017-2025 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.openfire; import org.jivesoftware.openfire.session.*; import org.xmpp.packet.JID; import org.xmpp.packet.Message; import org.xmpp.packet.Packet; import java.util.Collection; import java.util.List; /** *
Maintains server-wide knowledge of routes to any node.
*Routes are only concerned with node addresses. Destinations are * packet handlers (typically of the three following types):
*In almost all cases, the caller should not be concerned with what * handler is associated with a given node. Simply obtain the packet handler * and deliver the packet to the node, leaving the details up to the handler.
*Routes are matched using the stringprep rules given in the XMPP specification. * Wildcard routes for a particular name or resource is indicated by a null. E.g. * routing to any address at server.com should set the name to null, the host to * 'server.com' and the resource to null. A route to the best resource for user@server.com * should indicate that route with a null resource component of the XMPPAddress. Session * managers should add a route for both the generic user@server.com as well as * user@server.com/resource routes (knowing that one is an alias for the other * is the responsibility of the session or session manager).
*In order to accommodate broadcasts, you can also do partial matches by querying * all 'child' nodes of a particular node. The routing table contains a forest of * node trees. The node tree is arranged in the following hierarchy:
*Note: it is important that any component or action affecting routes * update the routing table immediately.
* * @author Iain Shigeoka */ public 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. * * @param route the address associated to the route. * @param destination the outgoing server session. */ void addServerRoute(DomainPair route, LocalOutgoingServerSession destination); /** * Adds a route to the routing table for the specified internal or external component.* * When running inside of a cluster this message {@code 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. * * @param route the address associated to the route. * @param destination the component. */ void addComponentRoute(JID route, RoutableChannelHandler destination); /** * 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 message {@code must} be sent * from the cluster node that is actually holding the client session. * * @param route the address (a full JID) associated to the route. * @param destination the client session. */ void addClientRoute(JID route, LocalClientSession destination); /** * 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, {@link org.xmpp.packet.Message Messages} and * {@link org.xmpp.packet.Presence Presences} are only sent to available client sessions whilst * {@link org.xmpp.packet.IQ 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.
* * @param jid the recipient of the packet to route. * @param packet the packet to route. * @throws PacketException thrown if the packet is malformed (results in the sender's * session being shutdown). */ void routePacket(JID jid, Packet packet) throws PacketException; /** * 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???? * * @param jid the full JID of the user. * @return true if a registered user or anonymous user with the specified full JID is * currently logged. */ boolean hasClientRoute(JID jid); /** * 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. Use * {@link XMPPServer#isLocal(org.xmpp.packet.JID)} to figure out if the address * belongs to tge domain hosted by this server. * * @param jid the address of the route. * @return true if the specified address belongs to a route that is hosted by this JVM. */ boolean isLocalRoute(JID jid); /** * 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. * * @param pair DomainPair that specifies the local/remote server address. * @return true if an outgoing server session exists to the specified remote server. */ boolean hasServerRoute(DomainPair pair); /** * 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.
*
* @param jid JID that specifies the component address.
* @return true if an internal or external component is hosting the specified address.
*/
boolean hasComponentRoute(JID jid);
/**
* Returns the client session associated to the specified XMPP address or {@code null}
* 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.
*
* @param jid the address of the session.
* @return the client session associated to the specified XMPP address or null if none was found.
*/
ClientSession getClientRoute(JID jid);
/**
* 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.
*
* @param onlyLocal true if only client sessions connected to this JVM must be considered.
* @return collection of client sessions authenticated with the server.
*/
Collection
*
* 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 {@code 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 {@code 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.
*
* @param route The address we want a route to.
* @param requester The address of the entity requesting the routes or null if we don't
* care about directed presences.
* @return list of routes associated to the specified route address.
*/
List