Commit ab4a1523 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Fixed directed presences for groupchats and one-2-one. JM-1273, JM-1274 and JM-1275

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@9932 b35dd754-fafc-0310-a699-88a17e54d16e
parent 34fd4775
...@@ -156,7 +156,7 @@ public class PresenceRouter extends BasicModule { ...@@ -156,7 +156,7 @@ public class PresenceRouter extends BasicModule {
// The user sent a directed presence to an entity // The user sent a directed presence to an entity
// Broadcast it to all connected resources // Broadcast it to all connected resources
for (JID jid : routingTable.getRoutes(recipientJID)) { for (JID jid : routingTable.getRoutes(recipientJID, senderJID)) {
// Register the sent directed presence // Register the sent directed presence
updateHandler.directedPresenceSent(packet, jid, recipientJID.toString()); updateHandler.directedPresenceSent(packet, jid, recipientJID.toString());
// Route the packet // Route the packet
......
...@@ -283,16 +283,22 @@ public interface RoutingTable { ...@@ -283,16 +283,22 @@ public interface RoutingTable {
* included in the answer in case the specified full JID exists or an empty collection * 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 * 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 * JIDs will be returned for each available resource associated to the bare JID. In
* any case, only JIDs of <tt>available</tt> client sessions are returned.<p> * any case, only JIDs of <tt>available</tt> 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 <tt>null</tt> then only
* available resources are considered.<p>
* *
* When asking for routes to components a single element will be returned in the answer * 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. * 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. * If no component was found then an empty collection will be returned.
* *
* @param route The address we want a route to. * @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. * @return list of routes associated to the specified route address.
*/ */
List<JID> getRoutes(JID route); List<JID> getRoutes(JID route, JID requester);
/** /**
* Returns true if a route of a client session has been successfully removed. When running * Returns true if a route of a client session has been successfully removed. When running
......
...@@ -551,7 +551,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener ...@@ -551,7 +551,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
Presence presence; Presence presence;
// Get list of sessions of the same user // Get list of sessions of the same user
JID searchJID = new JID(session.getAddress().getNode(), session.getAddress().getDomain(), null); JID searchJID = new JID(session.getAddress().getNode(), session.getAddress().getDomain(), null);
List<JID> addresses = routingTable.getRoutes(searchJID); List<JID> addresses = routingTable.getRoutes(searchJID, null);
for (JID address : addresses) { for (JID address : addresses) {
if (address.equals(session.getAddress())) { if (address.equals(session.getAddress())) {
continue; continue;
...@@ -575,7 +575,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener ...@@ -575,7 +575,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
public void broadcastPresenceToOtherResources(JID originatingResource, Presence presence) { public void broadcastPresenceToOtherResources(JID originatingResource, Presence presence) {
// Get list of sessions of the same user // Get list of sessions of the same user
JID searchJID = new JID(originatingResource.getNode(), originatingResource.getDomain(), null); JID searchJID = new JID(originatingResource.getNode(), originatingResource.getDomain(), null);
List<JID> addresses = routingTable.getRoutes(searchJID); List<JID> addresses = routingTable.getRoutes(searchJID, null);
for (JID address : addresses) { for (JID address : addresses) {
if (address.equals(originatingResource)) { if (address.equals(originatingResource)) {
continue; continue;
...@@ -621,7 +621,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener ...@@ -621,7 +621,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
// Check presence's priority of other available resources // Check presence's priority of other available resources
JID searchJID = new JID(session.getAddress().toBareJID()); JID searchJID = new JID(session.getAddress().toBareJID());
for (JID address : routingTable.getRoutes(searchJID)) { for (JID address : routingTable.getRoutes(searchJID, null)) {
if (address.equals(session.getAddress())) { if (address.equals(session.getAddress())) {
continue; continue;
} }
...@@ -812,7 +812,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener ...@@ -812,7 +812,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
public Collection<ClientSession> getSessions(String username) { public Collection<ClientSession> getSessions(String username) {
List<ClientSession> sessionList = new ArrayList<ClientSession>(); List<ClientSession> sessionList = new ArrayList<ClientSession>();
if (username != null) { if (username != null) {
List<JID> addresses = routingTable.getRoutes(new JID(username, serverName, null, true)); List<JID> addresses = routingTable.getRoutes(new JID(username, serverName, null, true), null);
for (JID address : addresses) { for (JID address : addresses) {
sessionList.add(routingTable.getClientRoute(address)); sessionList.add(routingTable.getClientRoute(address));
} }
...@@ -889,12 +889,12 @@ public class SessionManager extends BasicModule implements ClusterEventListener ...@@ -889,12 +889,12 @@ public class SessionManager extends BasicModule implements ClusterEventListener
* @return number of available sessions for a user. * @return number of available sessions for a user.
*/ */
public int getActiveSessionCount(String username) { public int getActiveSessionCount(String username) {
return routingTable.getRoutes(new JID(username, serverName, null, true)).size(); return routingTable.getRoutes(new JID(username, serverName, null, true), null).size();
} }
public int getSessionCount(String username) { public int getSessionCount(String username) {
// TODO Count ALL sessions not only available // TODO Count ALL sessions not only available
return routingTable.getRoutes(new JID(username, serverName, null, true)).size(); return routingTable.getRoutes(new JID(username, serverName, null, true), null).size();
} }
/** /**
...@@ -985,7 +985,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener ...@@ -985,7 +985,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
*/ */
public void userBroadcast(String username, Packet packet) throws PacketException { public void userBroadcast(String username, Packet packet) throws PacketException {
// TODO broadcast to ALL sessions of the user and not only available // TODO broadcast to ALL sessions of the user and not only available
for (JID address : routingTable.getRoutes(new JID(username, serverName, null))) { for (JID address : routingTable.getRoutes(new JID(username, serverName, null), null)) {
packet.setTo(address); packet.setTo(address);
routingTable.routePacket(address, packet, true); routingTable.routePacket(address, packet, true);
} }
......
...@@ -150,7 +150,7 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand ...@@ -150,7 +150,7 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand
// a module, the module will be able to handle the packet. If the handler is a // a module, the module will be able to handle the packet. If the handler is a
// Session the packet will be routed to the client. If a route cannot be found // Session the packet will be routed to the client. If a route cannot be found
// then the packet will be delivered based on its recipient and sender. // then the packet will be delivered based on its recipient and sender.
List<JID> jids = routingTable.getRoutes(recipientJID); List<JID> jids = routingTable.getRoutes(recipientJID, null);
if (!jids.isEmpty()) { if (!jids.isEmpty()) {
for (JID jid : jids) { for (JID jid : jids) {
Presence presenteToSend = presence.createCopy(); Presence presenteToSend = presence.createCopy();
......
...@@ -452,8 +452,11 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler ...@@ -452,8 +452,11 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler
} }
} }
public boolean hasDirectPresence(Session session, JID recipientJID) { public boolean hasDirectPresence(JID ownerJID, JID recipientJID) {
Collection<DirectedPresence> directedPresences = directedPresencesCache.get(session.getAddress().toString()); if (recipientJID == null) {
return false;
}
Collection<DirectedPresence> directedPresences = directedPresencesCache.get(ownerJID.toString());
if (directedPresences != null) { if (directedPresences != null) {
String recipient = recipientJID.toBareJID(); String recipient = recipientJID.toBareJID();
for (DirectedPresence directedPresence : directedPresences) { for (DirectedPresence directedPresence : directedPresences) {
......
...@@ -53,7 +53,7 @@ public class SocketPacketWriteHandler implements ChannelHandler { ...@@ -53,7 +53,7 @@ public class SocketPacketWriteHandler implements ChannelHandler {
} }
else { else {
// JID is of the form <user@domain> // JID is of the form <user@domain>
for (JID route : routingTable.getRoutes(recipient)) { for (JID route : routingTable.getRoutes(recipient, null)) {
routingTable.routePacket(route, packet, false); routingTable.routePacket(route, packet, false);
} }
} }
......
...@@ -582,7 +582,7 @@ public class Roster implements Cacheable, Externalizable { ...@@ -582,7 +582,7 @@ public class Roster implements Cacheable, Externalizable {
continue; continue;
} }
JID searchNode = new JID(item.getJid().getNode(), item.getJid().getDomain(), null, true); JID searchNode = new JID(item.getJid().getNode(), item.getJid().getDomain(), null, true);
for (JID jid : routingTable.getRoutes(searchNode)) { for (JID jid : routingTable.getRoutes(searchNode, null)) {
try { try {
routingTable.routePacket(jid, packet, false); routingTable.routePacket(jid, packet, false);
} }
...@@ -600,7 +600,7 @@ public class Roster implements Cacheable, Externalizable { ...@@ -600,7 +600,7 @@ public class Roster implements Cacheable, Externalizable {
// Outgoing presence notifications are blocked for this contact // Outgoing presence notifications are blocked for this contact
continue; continue;
} }
for (JID jid: routingTable.getRoutes(new JID(contact))) { for (JID jid: routingTable.getRoutes(new JID(contact), null)) {
try { try {
routingTable.routePacket(jid, packet, false); routingTable.routePacket(jid, packet, false);
} }
......
...@@ -32,9 +32,9 @@ import org.jivesoftware.openfire.user.UserNotFoundException; ...@@ -32,9 +32,9 @@ import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.lock.LockManager;
import org.jivesoftware.util.cache.Cache; import org.jivesoftware.util.cache.Cache;
import org.jivesoftware.util.cache.CacheFactory; import org.jivesoftware.util.cache.CacheFactory;
import org.jivesoftware.util.lock.LockManager;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError; import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence; import org.xmpp.packet.Presence;
...@@ -432,7 +432,7 @@ public class PresenceManagerImpl extends BasicModule implements PresenceManager ...@@ -432,7 +432,7 @@ public class PresenceManagerImpl extends BasicModule implements PresenceManager
if (userManager.isRegisteredUser(userJID.getNode())) { if (userManager.isRegisteredUser(userJID.getNode())) {
for (ClientSession session : sessionManager.getSessions(userJID.getNode())) { for (ClientSession session : sessionManager.getSessions(userJID.getNode())) {
// Do not send an unavailable presence if the user sent a direct available presence // Do not send an unavailable presence if the user sent a direct available presence
if (presenceUpdateHandler.hasDirectPresence(session, recipientJID)) { if (presenceUpdateHandler.hasDirectPresence(session.getAddress(), recipientJID)) {
continue; continue;
} }
Presence presencePacket = new Presence(); Presence presencePacket = new Presence();
......
...@@ -88,6 +88,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -88,6 +88,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
private IQRouter iqRouter; private IQRouter iqRouter;
private MessageRouter messageRouter; private MessageRouter messageRouter;
private PresenceRouter presenceRouter; private PresenceRouter presenceRouter;
private PresenceUpdateHandler presenceUpdateHandler;
public RoutingTableImpl() { public RoutingTableImpl() {
super("Routing table"); super("Routing table");
...@@ -200,7 +201,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -200,7 +201,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
clientRoute = anonymousUsersCache.get(jid.toString()); clientRoute = anonymousUsersCache.get(jid.toString());
} }
if (clientRoute != null) { if (clientRoute != null) {
if (!clientRoute.isAvailable() && routeOnlyAvailable(packet, fromServer)) { if (!clientRoute.isAvailable() && routeOnlyAvailable(packet, fromServer) &&
!presenceUpdateHandler.hasDirectPresence(packet.getTo(), packet.getFrom())) {
// Packet should only be sent to available sessions and the route is not available // Packet should only be sent to available sessions and the route is not available
routed = false; routed = false;
} }
...@@ -363,8 +365,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -363,8 +365,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
*/ */
private boolean routeToBareJID(JID recipientJID, Message packet) { private boolean routeToBareJID(JID recipientJID, Message packet) {
List<ClientSession> sessions = new ArrayList<ClientSession>(); List<ClientSession> sessions = new ArrayList<ClientSession>();
// Get existing AVAILABLE sessions of this user // Get existing AVAILABLE sessions of this user or AVAILABLE to the sender of the packet
for (JID address : getRoutes(recipientJID)) { for (JID address : getRoutes(recipientJID, packet.getFrom())) {
ClientSession session = getClientRoute(address); ClientSession session = getClientRoute(address);
if (session != null) { if (session != null) {
sessions.add(session); sessions.add(session);
...@@ -570,8 +572,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -570,8 +572,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
return componentsCache.containsKey(jid.getDomain()); return componentsCache.containsKey(jid.getDomain());
} }
public List<JID> getRoutes(JID route) { public List<JID> getRoutes(JID route, JID requester) {
// TODO Refactor API to be able to get c2s sessions available only/all
List<JID> jids = new ArrayList<JID>(); List<JID> jids = new ArrayList<JID>();
if (serverName.equals(route.getDomain())) { if (serverName.equals(route.getDomain())) {
// Address belongs to local user // Address belongs to local user
...@@ -581,7 +582,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -581,7 +582,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
if (clientRoute == null) { if (clientRoute == null) {
clientRoute = anonymousUsersCache.get(route.toString()); clientRoute = anonymousUsersCache.get(route.toString());
} }
if (clientRoute != null && clientRoute.isAvailable()) { if (clientRoute != null &&
(clientRoute.isAvailable() || presenceUpdateHandler.hasDirectPresence(route, requester))) {
jids.add(route); jids.add(route);
} }
} }
...@@ -595,7 +597,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -595,7 +597,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
if (clientRoute == null) { if (clientRoute == null) {
clientRoute = anonymousUsersCache.get(jid); clientRoute = anonymousUsersCache.get(jid);
} }
if (clientRoute != null && clientRoute.isAvailable()) { if (clientRoute != null && (clientRoute.isAvailable() ||
presenceUpdateHandler.hasDirectPresence(new JID(jid), requester))) {
jids.add(new JID(jid)); jids.add(new JID(jid));
} }
} }
...@@ -696,6 +699,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -696,6 +699,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
iqRouter = server.getIQRouter(); iqRouter = server.getIQRouter();
messageRouter = server.getMessageRouter(); messageRouter = server.getMessageRouter();
presenceRouter = server.getPresenceRouter(); presenceRouter = server.getPresenceRouter();
presenceUpdateHandler = server.getPresenceUpdateHandler();
// Listen to cluster events // Listen to cluster events
ClusterManager.addListener(this); ClusterManager.addListener(this);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment