Search in sources :

Example 1 with RemoteSessionLocator

use of org.jivesoftware.openfire.session.RemoteSessionLocator in project Openfire by igniterealtime.

the class ClusterListener method cleanupNode.

/**
     * Executes close logic for each session hosted in the remote node that is
     * no longer available. This logic is similar to the close listeners used by
     * the {@link SessionManager}.<p>
     *
     * If the node that went down performed its own clean up logic then the other
     * cluster nodes will have the correct state. That means that this method
     * will not find any sessions to remove.<p>
     *
     * If this operation is too big and we are still in a cluster then we can
     * distribute the work in the cluster to go faster.
     *
     * @param key the key that identifies the node that is no longer available.
     */
private void cleanupNode(NodeID key) {
    // TODO Fork in another process and even ask other nodes to process work
    RoutingTable routingTable = XMPPServer.getInstance().getRoutingTable();
    RemoteSessionLocator sessionLocator = XMPPServer.getInstance().getRemoteSessionLocator();
    SessionManager manager = XMPPServer.getInstance().getSessionManager();
    // TODO Consider removing each cached entry once processed instead of all at the end. Could be more error-prove.
    Set<String> registeredUsers = lookupJIDList(key, C2SCache.getName());
    if (!registeredUsers.isEmpty()) {
        for (String fullJID : new ArrayList<String>(registeredUsers)) {
            JID offlineJID = new JID(fullJID);
            manager.removeSession(null, offlineJID, false, true);
        }
    }
    Set<String> anonymousUsers = lookupJIDList(key, anonymousC2SCache.getName());
    if (!anonymousUsers.isEmpty()) {
        for (String fullJID : new ArrayList<String>(anonymousUsers)) {
            JID offlineJID = new JID(fullJID);
            manager.removeSession(null, offlineJID, true, true);
        }
    }
    // Remove outgoing server sessions hosted in node that left the cluster
    Set<String> remoteServers = lookupJIDList(key, S2SCache.getName());
    if (!remoteServers.isEmpty()) {
        for (String fullJID : new ArrayList<String>(remoteServers)) {
            JID serverJID = new JID(fullJID);
            routingTable.removeServerRoute(serverJID);
        }
    }
    Set<String> components = lookupJIDList(key, componentsCache.getName());
    if (!components.isEmpty()) {
        for (String address : new ArrayList<String>(components)) {
            Lock lock = CacheFactory.getLock(address, componentsCache);
            try {
                lock.lock();
                Set<NodeID> nodes = (Set<NodeID>) componentsCache.get(address);
                if (nodes != null) {
                    nodes.remove(key);
                    if (nodes.isEmpty()) {
                        componentsCache.remove(address);
                    } else {
                        componentsCache.put(address, nodes);
                    }
                }
            } finally {
                lock.unlock();
            }
        }
    }
    Set<String> componentSessions = lookupJIDList(key, componentSessionsCache.getName());
    if (!componentSessions.isEmpty()) {
        for (String domain : new ArrayList<String>(componentSessions)) {
            componentSessionsCache.remove(domain);
        // Registered subdomains of external component will be removed
        // by the clean up of the component cache
        }
    }
    Set<String> multiplexers = lookupJIDList(key, multiplexerSessionsCache.getName());
    if (!multiplexers.isEmpty()) {
        for (String fullJID : new ArrayList<String>(multiplexers)) {
            multiplexerSessionsCache.remove(fullJID);
        // c2s connections connected to node that went down will be cleaned up
        // by the c2s logic above. If the CM went down and the node is up then
        // connections will be cleaned up as usual
        }
    }
    Set<String> incomingSessions = lookupJIDList(key, incomingServerSessionsCache.getName());
    if (!incomingSessions.isEmpty()) {
        for (String streamIDValue : new ArrayList<>(incomingSessions)) {
            StreamID streamID = BasicStreamIDFactory.createStreamID(streamIDValue);
            IncomingServerSession session = sessionLocator.getIncomingServerSession(key.toByteArray(), streamID);
            // Remove all the hostnames that were registered for this server session
            for (String hostname : session.getValidatedDomains()) {
                manager.unregisterIncomingServerSession(hostname, session);
            }
        }
    }
    nodeSessions.remove(key);
// TODO Make sure that routing table has no entry referring to node that is gone
}
Also used : JID(org.xmpp.packet.JID) IncomingServerSession(org.jivesoftware.openfire.session.IncomingServerSession) Lock(java.util.concurrent.locks.Lock) RemoteSessionLocator(org.jivesoftware.openfire.session.RemoteSessionLocator) NodeID(org.jivesoftware.openfire.cluster.NodeID)

Example 2 with RemoteSessionLocator

use of org.jivesoftware.openfire.session.RemoteSessionLocator in project Openfire by igniterealtime.

the class SessionManager method getConnectionMultiplexerSessions.

/**
     * Returns all sessions originated from connection managers.
     *
     * @return all sessions originated from connection managers.
     */
public List<ConnectionMultiplexerSession> getConnectionMultiplexerSessions() {
    List<ConnectionMultiplexerSession> sessions = new ArrayList<>();
    // Add sessions of CMs connected to this JVM
    sessions.addAll(localSessionManager.getConnnectionManagerSessions().values());
    // Add sessions of CMs connected to other cluster nodes
    RemoteSessionLocator locator = server.getRemoteSessionLocator();
    if (locator != null) {
        for (Map.Entry<String, byte[]> entry : multiplexerSessionsCache.entrySet()) {
            if (!server.getNodeID().equals(entry.getValue())) {
                sessions.add(locator.getConnectionMultiplexerSession(entry.getValue(), new JID(entry.getKey())));
            }
        }
    }
    return sessions;
}
Also used : LocalConnectionMultiplexerSession(org.jivesoftware.openfire.session.LocalConnectionMultiplexerSession) ConnectionMultiplexerSession(org.jivesoftware.openfire.session.ConnectionMultiplexerSession) RemoteSessionLocator(org.jivesoftware.openfire.session.RemoteSessionLocator) JID(org.xmpp.packet.JID) ArrayList(java.util.ArrayList) Map(java.util.Map)

Example 3 with RemoteSessionLocator

use of org.jivesoftware.openfire.session.RemoteSessionLocator in project Openfire by igniterealtime.

the class ClusterListener method cleanupNode.

/**
     * Executes close logic for each session hosted in the remote node that is
     * no longer available. This logic is similar to the close listeners used by
     * the {@link SessionManager}.<p>
     *
     * If the node that went down performed its own clean up logic then the other
     * cluster nodes will have the correct state. That means that this method
     * will not find any sessions to remove.<p>
     *
     * If this operation is too big and we are still in a cluster then we can
     * distribute the work in the cluster to go faster.
     *
     * @param key the key that identifies the node that is no longer available.
     */
private void cleanupNode(NodeID key) {
    // TODO Fork in another process and even ask other nodes to process work
    RoutingTable routingTable = XMPPServer.getInstance().getRoutingTable();
    RemoteSessionLocator sessionLocator = XMPPServer.getInstance().getRemoteSessionLocator();
    SessionManager manager = XMPPServer.getInstance().getSessionManager();
    // TODO Consider removing each cached entry once processed instead of all at the end. Could be more error-prove.
    Set<String> registeredUsers = lookupJIDList(key, C2SCache.getName());
    if (!registeredUsers.isEmpty()) {
        for (String fullJID : new ArrayList<String>(registeredUsers)) {
            JID offlineJID = new JID(fullJID);
            manager.removeSession(null, offlineJID, false, true);
        }
    }
    Set<String> anonymousUsers = lookupJIDList(key, anonymousC2SCache.getName());
    if (!anonymousUsers.isEmpty()) {
        for (String fullJID : new ArrayList<String>(anonymousUsers)) {
            JID offlineJID = new JID(fullJID);
            manager.removeSession(null, offlineJID, true, true);
        }
    }
    // Remove outgoing server sessions hosted in node that left the cluster
    Set<String> remoteServers = lookupJIDList(key, S2SCache.getName());
    if (!remoteServers.isEmpty()) {
        for (String fullJID : new ArrayList<String>(remoteServers)) {
            JID serverJID = new JID(fullJID);
            routingTable.removeServerRoute(serverJID);
        }
    }
    Set<String> components = lookupJIDList(key, componentsCache.getName());
    if (!components.isEmpty()) {
        for (String address : new ArrayList<String>(components)) {
            Lock lock = CacheFactory.getLock(address, componentsCache);
            try {
                lock.lock();
                Set<NodeID> nodes = (Set<NodeID>) componentsCache.get(address);
                if (nodes != null) {
                    nodes.remove(key);
                    if (nodes.isEmpty()) {
                        componentsCache.remove(address);
                    } else {
                        componentsCache.put(address, nodes);
                    }
                }
            } finally {
                lock.unlock();
            }
        }
    }
    Set<String> sessionInfo = lookupJIDList(key, sessionInfoCache.getName());
    if (!sessionInfo.isEmpty()) {
        for (String session : new ArrayList<String>(sessionInfo)) {
            sessionInfoCache.remove(session);
        // Registered sessions will be removed
        // by the clean up of the session info cache
        }
    }
    Set<String> componentSessions = lookupJIDList(key, componentSessionsCache.getName());
    if (!componentSessions.isEmpty()) {
        for (String domain : new ArrayList<String>(componentSessions)) {
            componentSessionsCache.remove(domain);
        // Registered subdomains of external component will be removed
        // by the clean up of the component cache
        }
    }
    Set<String> multiplexers = lookupJIDList(key, multiplexerSessionsCache.getName());
    if (!multiplexers.isEmpty()) {
        for (String fullJID : new ArrayList<String>(multiplexers)) {
            multiplexerSessionsCache.remove(fullJID);
        // c2s connections connected to node that went down will be cleaned up
        // by the c2s logic above. If the CM went down and the node is up then
        // connections will be cleaned up as usual
        }
    }
    Set<String> incomingSessions = lookupJIDList(key, incomingServerSessionsCache.getName());
    if (!incomingSessions.isEmpty()) {
        for (String streamIDValue : new ArrayList<>(incomingSessions)) {
            StreamID streamID = BasicStreamIDFactory.createStreamID(streamIDValue);
            IncomingServerSession session = sessionLocator.getIncomingServerSession(key.toByteArray(), streamID);
            // Remove all the hostnames that were registered for this server session
            for (String hostname : session.getValidatedDomains()) {
                manager.unregisterIncomingServerSession(hostname, session);
            }
        }
    }
    nodeSessions.remove(key);
// TODO Make sure that routing table has no entry referring to node that is gone
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) JID(org.xmpp.packet.JID) IncomingServerSession(org.jivesoftware.openfire.session.IncomingServerSession) ArrayList(java.util.ArrayList) Lock(java.util.concurrent.locks.Lock) RemoteSessionLocator(org.jivesoftware.openfire.session.RemoteSessionLocator) NodeID(org.jivesoftware.openfire.cluster.NodeID)

Aggregations

RemoteSessionLocator (org.jivesoftware.openfire.session.RemoteSessionLocator)3 JID (org.xmpp.packet.JID)3 ArrayList (java.util.ArrayList)2 Lock (java.util.concurrent.locks.Lock)2 NodeID (org.jivesoftware.openfire.cluster.NodeID)2 IncomingServerSession (org.jivesoftware.openfire.session.IncomingServerSession)2 HashSet (java.util.HashSet)1 Map (java.util.Map)1 Set (java.util.Set)1 ConnectionMultiplexerSession (org.jivesoftware.openfire.session.ConnectionMultiplexerSession)1 LocalConnectionMultiplexerSession (org.jivesoftware.openfire.session.LocalConnectionMultiplexerSession)1