Class OccupantManager

java.lang.Object
org.jivesoftware.openfire.muc.spi.OccupantManager
All Implemented Interfaces:
MUCEventListener

public class OccupantManager extends Object implements MUCEventListener
Maintains an in-memory inventory of what XMPP entity (user) is in what chatroom, across the entire XMPP cluster. Each instance of this class takes responsibility of maintaining the in-memory representation of occupants of rooms for exactly one instance of MultiUserChatService. Some data duplication exists between the data managed by this class, and the data that is managed by the collection of MUCRoom instances that are part of the same MUC service. The MUCRoom managed data is shared across the cluster using a clustered data structure (a clustered Cache). The content of such caches cannot survive certain events related to changes in the composition of the cluster (the local server joining or leaving the cluster). This introduces problems, as, for example, the occupants that are connected to the local server should see occupants connected to a cluster node that is now unavailable 'leave' the chatroom. This requires the local cluster node to retain knowledge, even after the clustered cache has been reset. This implementation therefore by design makes no use of such clustered caches to exchange data with other cluster nodes. Instead, this implementation relies on cluster tasks to share data between cluster nodes. To minimize data transfer and data duplication, the data managed by this implementation is kept to the bare minimum needed to perform post-cluster event maintenance. Apart from the responsibility of maintaining data for post-cluster event maintenance, this implementation adds some conveniences, that include:
  • A method (that operates on the maintained data) to determine what room names a particular user is in. As this implementation already maintains this data, obtaining it from this class is more convenient and more performant than obtaining it from the data that is maintained in the clustered data structure (as that is mapped 'by room')
  • A 'last activity' timestamp for users on the local node (to be used to detect idle users
Author:
Guus der Kinderen, guus.der.kinderen@gmail.com
See Also:
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static class 
    Representation of a user that is an occupant of a chatroom.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final SystemProperty<Boolean>
    Controls if blocking or non-blocking tasks are used when synchronizing MUC occupant data over an Openfire cluster.
  • Method Summary

    Modifier and Type
    Method
    Description
    boolean
    Checks whether the occupant exists.
    boolean
    Checks whether the occupant exists, optionally excluding a specific node from evaluation.
     
    Returns data that is maintained for occupants of the local cluster node.
     
     
    boolean
    isForThisService(org.xmpp.packet.JID jid)
    Verifies that a JID relates to the service for which this instance is operating, by comparing its domain part.
    lastActivityOnLocalNode(org.xmpp.packet.JID userJid)
    Returns the most recent activity for a particular user that is assumed to be connected to the local cluster node.
    Removes and returns all data that was maintained for cluster nodes other than the local node.
    Removes and returns all data that was maintained for a particular cluster node.
    void
    messageReceived(org.xmpp.packet.JID roomJID, org.xmpp.packet.JID user, String nickname, org.xmpp.packet.Message message)
    Event triggered when a room occupant sent a message to a room.
    void
    nicknameChanged(org.xmpp.packet.JID roomJID, org.xmpp.packet.JID userJID, String oldNickname, String newNickname)
    When an XMPP entity / user that is an occupant of a room changes its nickname, this event handler will ensure that the relevant data that is maintained in this instance of OccupantManager, as well as all instances for the same server on every other cluster node, is updated.
    int
    Counts all users that are in at least one room.
    void
    occupantJoined(org.xmpp.packet.JID roomJID, org.xmpp.packet.JID userJID, String nickname)
    When an XMPP entity / user is registered as a new occupant of a room, this event handler will ensure that this instance of OccupantManager, as well as all instances for the same server on every other cluster node, registers the relevant data that is needed to perform post-cluster event maintenance.
    void
    occupantLeft(org.xmpp.packet.JID roomJID, org.xmpp.packet.JID userJID, String nickname)
    When an XMPP entity / user is removed as an occupant of a room, this event handler will ensure that this instance of OccupantManager, as well as all instances for the same server on every other cluster node, updates the relevant data that it maintains to perform post-cluster event maintenance.
    void
    occupantNickKicked(org.xmpp.packet.JID roomJID, String nickname)
    When an XMPP entity / user is kicked out of a room because of nickname collision, this event handler will ensure that this instance of OccupantManager, as well as all instances for the same server on every other cluster node, updates the relevant data that it maintains to perform post-cluster event maintenance.
    occupantsForRoomByNode(String roomName, NodeID nodeID, boolean includeFederated)
     
    occupantsForRoomExceptForNode(String roomName, NodeID nodeID, boolean includeFederated)
     
    void
    privateMessageRecieved(org.xmpp.packet.JID toJID, org.xmpp.packet.JID fromJID, org.xmpp.packet.Message message)
    Event triggered when a room occupant sent a private message to another room user
    void
    Updates the data maintained by this instance to perform post-cluster event maintenance, based on the data from the clustered task.
    void
    Updates the data maintained by this instance to perform post-cluster event maintenance, based on the data from the clustered task.
    void
    Updates the data maintained by this instance to perform post-cluster event maintenance, based on the data from the clustered task.
    void
    Updates the data maintained by this instance to perform post-cluster event maintenance, based on the data from the clustered task.
    void
    Used by other nodes telling us about all of their occupants.
    void
    registerActivity(org.xmpp.packet.JID userJid)
    Registers activity for a particular user that is assumed to be connected to the local cluster node.
    registerOccupantJoinedLocally(org.xmpp.packet.JID roomJID, org.xmpp.packet.JID userJID, String nickname)
     
    void
    roomClearChatHistory(long roomID, org.xmpp.packet.JID roomJID)
    Event triggered when a clear chat history command was issued.
    void
    roomCreated(long roomID, org.xmpp.packet.JID roomJID)
    Event triggered when a new room was created.
    void
    roomDestroyed(long unused, org.xmpp.packet.JID roomJID)
    Event triggered when a room was destroyed.
    roomNamesForAddress(org.xmpp.packet.JID realJID)
    Returns the name of all the rooms that a particular XMPP entity (user) is currently an occupant of.
    void
    roomSubjectChanged(org.xmpp.packet.JID roomJID, org.xmpp.packet.JID user, String newSubject)
    Event triggered when the subject of a room is changed.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • PROPERTY_USE_NONBLOCKING_CLUSTERTASKS

      public static final SystemProperty<Boolean> PROPERTY_USE_NONBLOCKING_CLUSTERTASKS
      Controls if blocking or non-blocking tasks are used when synchronizing MUC occupant data over an Openfire cluster.
  • Method Details

    • isForThisService

      public boolean isForThisService(@Nonnull org.xmpp.packet.JID jid)
      Verifies that a JID relates to the service for which this instance is operating, by comparing its domain part.
      Parameters:
      jid - The JID to check
      Returns:
      True if the JID relates to the service, otherwise false.
    • occupantJoined

      public void occupantJoined(@Nonnull org.xmpp.packet.JID roomJID, @Nonnull org.xmpp.packet.JID userJID, @Nonnull String nickname)
      When an XMPP entity / user is registered as a new occupant of a room, this event handler will ensure that this instance of OccupantManager, as well as all instances for the same server on every other cluster node, registers the relevant data that is needed to perform post-cluster event maintenance.
      Specified by:
      occupantJoined in interface MUCEventListener
      Parameters:
      roomJID - the JID of the room where the occupant has joined.
      userJID - The 'real' JID (not room-at-service-slash-nickname) of the XMPP user that joined.
      nickname - nickname of the user in the room.
    • registerOccupantJoinedLocally

      @Nonnull public OccupantAddedTask registerOccupantJoinedLocally(@Nonnull org.xmpp.packet.JID roomJID, @Nonnull org.xmpp.packet.JID userJID, @Nonnull String nickname)
    • nicknameChanged

      public void nicknameChanged(@Nonnull org.xmpp.packet.JID roomJID, @Nonnull org.xmpp.packet.JID userJID, @Nonnull String oldNickname, @Nonnull String newNickname)
      When an XMPP entity / user that is an occupant of a room changes its nickname, this event handler will ensure that the relevant data that is maintained in this instance of OccupantManager, as well as all instances for the same server on every other cluster node, is updated.
      Specified by:
      nicknameChanged in interface MUCEventListener
      Parameters:
      roomJID - the JID of the room where the occupant has joined.
      userJID - The 'real' JID (not room-at-service-slash-nickname) of the XMPP user that joined.
      oldNickname - nickname of the user in the room prior to the change.
      newNickname - nickname of the user in the room after the change.
    • occupantLeft

      public void occupantLeft(org.xmpp.packet.JID roomJID, org.xmpp.packet.JID userJID, String nickname)
      When an XMPP entity / user is removed as an occupant of a room, this event handler will ensure that this instance of OccupantManager, as well as all instances for the same server on every other cluster node, updates the relevant data that it maintains to perform post-cluster event maintenance.
      Specified by:
      occupantLeft in interface MUCEventListener
      Parameters:
      roomJID - the JID of the room where the occupant has left.
      userJID - The 'real' JID (not room-at-service-slash-nickname) of the XMPP user that left.
      nickname - nickname that the user used in the room.
    • occupantNickKicked

      public void occupantNickKicked(org.xmpp.packet.JID roomJID, String nickname)
      When an XMPP entity / user is kicked out of a room because of nickname collision, this event handler will ensure that this instance of OccupantManager, as well as all instances for the same server on every other cluster node, updates the relevant data that it maintains to perform post-cluster event maintenance.
      Specified by:
      occupantNickKicked in interface MUCEventListener
      Parameters:
      roomJID - the JID of the room where the occupant is kicked out.
      nickname - nickname that the user used in the room.
    • process

      public void process(@Nonnull OccupantAddedTask task)
      Updates the data maintained by this instance to perform post-cluster event maintenance, based on the data from the clustered task.
      Parameters:
      task - Cluster task that informs of a new occupant
    • process

      public void process(@Nonnull OccupantUpdatedTask task)
      Updates the data maintained by this instance to perform post-cluster event maintenance, based on the data from the clustered task.
      Parameters:
      task - Cluster task that informs of an update for an existing occupant
    • process

      public void process(@Nonnull OccupantRemovedTask task)
      Updates the data maintained by this instance to perform post-cluster event maintenance, based on the data from the clustered task.
      Parameters:
      task - Cluster task that informs of a removed occupant
    • process

      public void process(@Nonnull OccupantKickedForNicknameTask task)
      Updates the data maintained by this instance to perform post-cluster event maintenance, based on the data from the clustered task.
      Parameters:
      task - Cluster task that informs of an occupant nickname that has been kicked out of a room
    • process

      public void process(@Nonnull SyncLocalOccupantsAndSendJoinPresenceTask task)
      Used by other nodes telling us about all of their occupants.
      Parameters:
      task - Cluster task that informs of occupants on a remote node.
    • roomNamesForAddress

      @Nonnull public Set<String> roomNamesForAddress(@Nonnull org.xmpp.packet.JID realJID)
      Returns the name of all the rooms that a particular XMPP entity (user) is currently an occupant of.
      Parameters:
      realJID - The XMPP address of a user
      Returns:
      All room names that have the user as an occupant.
    • getLocalOccupants

      @Nonnull public Set<OccupantManager.Occupant> getLocalOccupants()
      Returns data that is maintained for occupants of the local cluster node. The returned occupants include occupants that are local to the XMPP domain as well as federated users.
      Returns:
      all data maintained for the local cluster node.
    • registerActivity

      public void registerActivity(@Nonnull org.xmpp.packet.JID userJid)
      Registers activity for a particular user that is assumed to be connected to the local cluster node. This records a timestamp, that can be used to detect idle-ness.
      Parameters:
      userJid - The address of the user for which to record activity.
    • lastActivityOnLocalNode

      @Nullable public Instant lastActivityOnLocalNode(@Nonnull org.xmpp.packet.JID userJid)
      Returns the most recent activity for a particular user that is assumed to be connected to the local cluster node. This returns a timestamp, that can be used to detect idle-ness.
      Parameters:
      userJid - The address of the user for which to return a timestamp of last activity.
      Returns:
      A timestamp, or null when there currently is no occupant by that JID on the local node.
    • numberOfUniqueUsers

      public int numberOfUniqueUsers()
      Counts all users that are in at least one room.
      Returns:
      a user count
    • exists

      public boolean exists(@Nonnull OccupantManager.Occupant occupant, @Nullable NodeID exclude)
      Checks whether the occupant exists, optionally excluding a specific node from evaluation.
      Parameters:
      occupant - The subject of the existence check
      exclude - An optional node to exclude from the check
      Returns:
      True if the occupant was found, otherwise false.
    • exists

      public boolean exists(@Nonnull OccupantManager.Occupant occupant)
      Checks whether the occupant exists.
      Parameters:
      occupant - The subject of the existence check
      Returns:
      True if the occupant was found, otherwise false.
    • occupantsForRoomByNode

      @Nonnull public Set<OccupantManager.Occupant> occupantsForRoomByNode(@Nonnull String roomName, @Nonnull NodeID nodeID, boolean includeFederated)
    • occupantsForRoomExceptForNode

      @Nonnull public Set<OccupantManager.Occupant> occupantsForRoomExceptForNode(@Nonnull String roomName, @Nonnull NodeID nodeID, boolean includeFederated)
    • leftCluster

      @Nonnull public Set<OccupantManager.Occupant> leftCluster(@Nonnull NodeID nodeID)
      Removes and returns all data that was maintained for a particular cluster node. It is assumed that this method is used in reaction to that cluster node having left the cluster.
      Parameters:
      nodeID - Identifier of the cluster node that left.
      Returns:
      All data that this instance maintained for the cluster node.
    • leftCluster

      @Nullable public Set<OccupantManager.Occupant> leftCluster()
      Removes and returns all data that was maintained for cluster nodes other than the local node. It is assumed that this method is used in reaction to the local cluster node having left the cluster.
      Returns:
      All data that this instance maintained for all cluster nodes except the local one.
    • getLocalOccupantsByNode

      @Nonnull public Map<NodeID,Set<OccupantManager.Occupant>> getLocalOccupantsByNode()
    • getFederatedOccupants

      public Set<OccupantManager.Occupant> getFederatedOccupants()
    • getNodeByLocalOccupant

      @Nonnull public Map<OccupantManager.Occupant,NodeID> getNodeByLocalOccupant()
    • roomCreated

      public void roomCreated(long roomID, @Nonnull org.xmpp.packet.JID roomJID)
      Description copied from interface: MUCEventListener
      Event triggered when a new room was created.
      Specified by:
      roomCreated in interface MUCEventListener
      roomJID - JID of the room that was created.
    • roomDestroyed

      public void roomDestroyed(long unused, @Nonnull org.xmpp.packet.JID roomJID)
      Description copied from interface: MUCEventListener
      Event triggered when a room was destroyed.
      Specified by:
      roomDestroyed in interface MUCEventListener
      roomJID - JID of the room that was destroyed.
    • roomClearChatHistory

      public void roomClearChatHistory(long roomID, @Nonnull org.xmpp.packet.JID roomJID)
      Description copied from interface: MUCEventListener
      Event triggered when a clear chat history command was issued.
      Specified by:
      roomClearChatHistory in interface MUCEventListener
      roomJID - JID of the room to clear chat history.
    • messageReceived

      public void messageReceived(org.xmpp.packet.JID roomJID, org.xmpp.packet.JID user, String nickname, org.xmpp.packet.Message message)
      Description copied from interface: MUCEventListener
      Event triggered when a room occupant sent a message to a room.
      Specified by:
      messageReceived in interface MUCEventListener
      Parameters:
      roomJID - the JID of the room that received the message.
      user - the JID of the user that sent the message.
      nickname - nickname used by the user when sending the message.
      message - the message sent by the room occupant.
    • privateMessageRecieved

      public void privateMessageRecieved(org.xmpp.packet.JID toJID, org.xmpp.packet.JID fromJID, org.xmpp.packet.Message message)
      Description copied from interface: MUCEventListener
      Event triggered when a room occupant sent a private message to another room user
      Specified by:
      privateMessageRecieved in interface MUCEventListener
      Parameters:
      toJID - the JID of who the message is to.
      fromJID - the JID of who the message came from.
      message - the message sent to user.
    • roomSubjectChanged

      public void roomSubjectChanged(org.xmpp.packet.JID roomJID, org.xmpp.packet.JID user, String newSubject)
      Description copied from interface: MUCEventListener
      Event triggered when the subject of a room is changed.
      Specified by:
      roomSubjectChanged in interface MUCEventListener
      Parameters:
      roomJID - the JID of the room that had its subject changed.
      user - the JID of the user that changed the subject.
      newSubject - new room subject.