Search in sources :

Example 1 with PresenceUpdateHandler

use of org.jivesoftware.openfire.handler.PresenceUpdateHandler in project Openfire by igniterealtime.

the class RoutingTableImpl method joinedCluster.

@Override
public void joinedCluster() {
    // The local node joined a cluster.
    // 
    // Upon joining a cluster, clustered caches are reset to their clustered equivalent (by the swap from the local
    // cache implementation to the clustered cache implementation that's done in the implementation of
    // org.jivesoftware.util.cache.CacheFactory.joinedCluster). This means that they now hold data that's
    // available on all other cluster nodes. Data that's available on the local node needs to be added again.
    restoreCacheContent();
    Log.debug("Add the entry listeners to the corresponding caches.");
    // Register a cache entry event listeners that will collect data for entries added by all other cluster nodes,
    // which is intended to be used (only) in the event of a cluster split.
    final ClusteredCacheEntryListener<String, ClientRoute> userCacheEntryListener = new ReverseLookupUpdatingCacheEntryListener<>(routeOwnersByClusterNode);
    final ClusteredCacheEntryListener<DomainPair, NodeID> serversCacheEntryListener = new ReverseLookupUpdatingCacheEntryListener<>(s2sDomainPairsByClusterNode);
    final ClusteredCacheEntryListener<String, HashSet<NodeID>> componentsCacheEntryListener = new ReverseLookupComputingCacheEntryListener<>(componentsByClusterNode, nodeIDS -> nodeIDS.stream().filter(n -> !n.equals(XMPPServer.getInstance().getNodeID())).collect(Collectors.toSet()));
    // Note that, when #joinedCluster() fired, the cache will _always_ have been replaced, meaning that it won't
    // have old event listeners. When #leaveCluster() fires, the cache will be destroyed. This takes away the need
    // to explicitly deregister the listener in that case.
    // Ensure that event listeners have been registered with the caches, before starting to simulate 'entryAdded' events,
    // to prevent the possibility of having entries that are missed by the simulation because of bad timing.
    usersCache.addClusteredCacheEntryListener(userCacheEntryListener, false, false);
    anonymousUsersCache.addClusteredCacheEntryListener(userCacheEntryListener, false, false);
    serversCache.addClusteredCacheEntryListener(serversCacheEntryListener, false, false);
    componentsCache.addClusteredCacheEntryListener(componentsCacheEntryListener, true, true);
    // This is not necessary for the usersSessions cache, because its content is being managed while the content
    // of users cache and anonymous users cache is being managed.
    Log.debug("Simulate 'entryAdded' for all data that already exists elsewhere in the cluster.");
    Stream.concat(usersCache.entrySet().stream(), anonymousUsersCache.entrySet().stream()).filter(entry -> !entry.getValue().getNodeID().equals(XMPPServer.getInstance().getNodeID())).forEach(entry -> userCacheEntryListener.entryAdded(entry.getKey(), entry.getValue(), entry.getValue().getNodeID()));
    serversCache.entrySet().stream().filter(entry -> !entry.getValue().equals(XMPPServer.getInstance().getNodeID())).forEach(entry -> serversCacheEntryListener.entryAdded(entry.getKey(), entry.getValue(), entry.getValue()));
    componentsCache.entrySet().forEach(entry -> {
        entry.getValue().forEach(nodeIdForComponent -> {
            // Iterate over all node ids on which the component is known
            if (!nodeIdForComponent.equals(XMPPServer.getInstance().getNodeID())) {
                // Here we pretend that the component has been added by the node id on which it is reported to
                // be available. This might not have been the case, but it is probably accurate. An alternative
                // approach is not easily available.
                componentsCacheEntryListener.entryAdded(entry.getKey(), entry.getValue(), nodeIdForComponent);
            }
        });
    });
    // Broadcast presence of local sessions to remote sessions when subscribed to presence.
    // Probe presences of remote sessions when subscribed to presence of local session.
    // Send pending subscription requests to local sessions from remote sessions.
    // Deliver offline messages sent to local sessions that were unavailable in other nodes.
    // Send available presences of local sessions to other resources of the same user.
    PresenceUpdateHandler presenceUpdateHandler = XMPPServer.getInstance().getPresenceUpdateHandler();
    for (LocalClientSession session : localRoutingTable.getClientRoutes()) {
        // Simulate that the local session has just become available
        session.setInitialized(false);
        // Simulate that current session presence has just been received
        presenceUpdateHandler.process(session.getPresence());
    }
// TODO OF-2067: the above also (re)generates events on the local node, where these events had already occurred. Ideally, that should not happen.
// TODO OF-2066: shouldn't a similar action be done on the other nodes, so that the node that just joined gets informed about all sessions living on other cluster nodes?
}
Also used : Presence(org.xmpp.packet.Presence) LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession) Forwarded(org.jivesoftware.openfire.forward.Forwarded) ClientSession(org.jivesoftware.openfire.session.ClientSession) Received(org.jivesoftware.openfire.carbons.Received) BasicModule(org.jivesoftware.openfire.container.BasicModule) CacheFactory(org.jivesoftware.util.cache.CacheFactory) ClusteredCacheEntryListener(org.jivesoftware.openfire.cluster.ClusteredCacheEntryListener) LoggerFactory(org.slf4j.LoggerFactory) JiveGlobals(org.jivesoftware.util.JiveGlobals) MessageRouter(org.jivesoftware.openfire.MessageRouter) ReverseLookupUpdatingCacheEntryListener(org.jivesoftware.util.cache.ReverseLookupUpdatingCacheEntryListener) PresenceUpdateHandler(org.jivesoftware.openfire.handler.PresenceUpdateHandler) Message(org.xmpp.packet.Message) OutgoingServerSession(org.jivesoftware.openfire.session.OutgoingServerSession) CacheUtil(org.jivesoftware.util.cache.CacheUtil) RemoteServerManager(org.jivesoftware.openfire.server.RemoteServerManager) Cache(org.jivesoftware.util.cache.Cache) RoutingTable(org.jivesoftware.openfire.RoutingTable) PresenceRouter(org.jivesoftware.openfire.PresenceRouter) ClusterManager(org.jivesoftware.openfire.cluster.ClusterManager) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Collectors(java.util.stream.Collectors) Stream(java.util.stream.Stream) ConnectionSettings(org.jivesoftware.openfire.session.ConnectionSettings) RemoteSessionLocator(org.jivesoftware.openfire.session.RemoteSessionLocator) java.util(java.util) PacketException(org.jivesoftware.openfire.PacketException) Multimap(com.google.common.collect.Multimap) ReverseLookupComputingCacheEntryListener(org.jivesoftware.util.cache.ReverseLookupComputingCacheEntryListener) JID(org.xmpp.packet.JID) Function(java.util.function.Function) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) ConcurrentMap(java.util.concurrent.ConcurrentMap) NodeID(org.jivesoftware.openfire.cluster.NodeID) XMPPServer(org.jivesoftware.openfire.XMPPServer) RoutableChannelHandler(org.jivesoftware.openfire.RoutableChannelHandler) RemotePacketRouter(org.jivesoftware.openfire.RemotePacketRouter) ClusterEventListener(org.jivesoftware.openfire.cluster.ClusterEventListener) DomainPair(org.jivesoftware.openfire.session.DomainPair) LocalOutgoingServerSession(org.jivesoftware.openfire.session.LocalOutgoingServerSession) Logger(org.slf4j.Logger) ConsistencyChecks(org.jivesoftware.util.cache.ConsistencyChecks) ExternalComponentManager(org.jivesoftware.openfire.component.ExternalComponentManager) AtomicLong(java.util.concurrent.atomic.AtomicLong) Lock(java.util.concurrent.locks.Lock) Packet(org.xmpp.packet.Packet) OutgoingSessionPromise(org.jivesoftware.openfire.server.OutgoingSessionPromise) Element(org.dom4j.Element) QName(org.dom4j.QName) IQRouter(org.jivesoftware.openfire.IQRouter) IQ(org.xmpp.packet.IQ) ReverseLookupUpdatingCacheEntryListener(org.jivesoftware.util.cache.ReverseLookupUpdatingCacheEntryListener) PresenceUpdateHandler(org.jivesoftware.openfire.handler.PresenceUpdateHandler) LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession) DomainPair(org.jivesoftware.openfire.session.DomainPair) NodeID(org.jivesoftware.openfire.cluster.NodeID) ReverseLookupComputingCacheEntryListener(org.jivesoftware.util.cache.ReverseLookupComputingCacheEntryListener)

Aggregations

Multimap (com.google.common.collect.Multimap)1 java.util (java.util)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 Lock (java.util.concurrent.locks.Lock)1 Function (java.util.function.Function)1 Collectors (java.util.stream.Collectors)1 Stream (java.util.stream.Stream)1 Element (org.dom4j.Element)1 QName (org.dom4j.QName)1 IQRouter (org.jivesoftware.openfire.IQRouter)1 MessageRouter (org.jivesoftware.openfire.MessageRouter)1 PacketException (org.jivesoftware.openfire.PacketException)1 PresenceRouter (org.jivesoftware.openfire.PresenceRouter)1 RemotePacketRouter (org.jivesoftware.openfire.RemotePacketRouter)1 RoutableChannelHandler (org.jivesoftware.openfire.RoutableChannelHandler)1 RoutingTable (org.jivesoftware.openfire.RoutingTable)1 XMPPServer (org.jivesoftware.openfire.XMPPServer)1 UnauthorizedException (org.jivesoftware.openfire.auth.UnauthorizedException)1