Commit dbb673f3 authored by Armando Jagucki's avatar Armando Jagucki Committed by ajagucki

PEP: Devised a means to cache presences sent to the service from entities on...

PEP: Devised a means to cache presences sent to the service from entities on remote servers. This fixes bugs found in tests with server2server routes.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/branches/pep@8911 b35dd754-fafc-0310-a699-88a17e54d16e
parent ba591cb6
...@@ -604,6 +604,37 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider, ...@@ -604,6 +604,37 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
} }
} }
} }
else if (incoming && processed && packet instanceof Presence) {
// Cache newly-available presence resources for remote users (since the PresenceEventDispatcher
// methods are not called for remote presence events).
JID jidFrom = packet.getFrom();
if (!XMPPServer.getInstance().isLocal(jidFrom) && packet.getTo() != null) {
if (Log.isDebugEnabled()) {
Log.debug("PEP: received presence from: " + packet.getFrom() + " to: " + packet.getTo());
}
for (PEPService service : pepServices.values()) {
if (service.getAddress().toString().equals(packet.getTo().toString())) {
Presence.Type type = ((Presence) packet).getType();
if (type != null && type == Presence.Type.unavailable) {
if (service.removeRemotePresence(jidFrom)) {
if (Log.isDebugEnabled()) {
Log.debug("PEP: removed " + jidFrom + " from " + service.getAddress() + "'s knownRemotePresences");
}
}
}
else if (jidFrom.getResource() != null && service.addRemotePresence(jidFrom)) {
if (Log.isDebugEnabled()) {
Log.debug("PEP: added " + jidFrom + " to " + service.getAddress() + "'s knownRemotePresences");
}
// Send last published item for newly-available remote resource.
availableSession((ClientSession) session, (Presence) packet);
}
}
}
}
}
} }
/** /**
......
...@@ -43,7 +43,6 @@ import org.xmpp.packet.Message; ...@@ -43,7 +43,6 @@ import org.xmpp.packet.Message;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketExtension; import org.xmpp.packet.PacketExtension;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
...@@ -148,8 +147,18 @@ public class PEPService implements PubSubService { ...@@ -148,8 +147,18 @@ public class PEPService implements PubSubService {
*/ */
private Timer timer = new Timer("PEP service maintenance"); private Timer timer = new Timer("PEP service maintenance");
/**
* Date format to use for time stamps in delayed event notifications.
*/
private static final FastDateFormat fastDateFormat; private static final FastDateFormat fastDateFormat;
/**
* A cache of all known full JIDs that have sent presences from a remote server.
* This set is convenient for sending notifications to the full JID of remote users
* that have sent available presences to the PEP service.
*/
private HashSet<JID> knownRemotePresences = new HashSet<JID>();
static { static {
fastDateFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("UTC")); fastDateFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("UTC"));
} }
...@@ -332,16 +341,21 @@ public class PEPService implements PubSubService { ...@@ -332,16 +341,21 @@ public class PEPService implements PubSubService {
// If the recipient subscribed with a bare JID and this PEPService can retrieve // If the recipient subscribed with a bare JID and this PEPService can retrieve
// presence information for the recipient, collect all of their full JIDs and // presence information for the recipient, collect all of their full JIDs and
// send the notification to each below. // send the notification to each below.
Collection<JID> recipientFullJIDs = new ArrayList<JID>(); HashSet<JID> recipientFullJIDs = new HashSet<JID>();
if (recipientJID.getResource() == null && XMPPServer.getInstance().isLocal(recipientJID)) { if (recipientJID.getResource() == null && XMPPServer.getInstance().isLocal(recipientJID)) {
for (ClientSession clientSession : SessionManager.getInstance().getSessions(recipientJID.getNode())) { for (ClientSession clientSession : SessionManager.getInstance().getSessions(recipientJID.getNode())) {
recipientFullJIDs.add(clientSession.getAddress()); recipientFullJIDs.add(clientSession.getAddress());
} }
} }
// TODO: Try to get presence info even if not local... else {
/*else { // Since recipientJID is not local, try to get presence info from cached known remote
recipientFullJIDs.add(recipientJID); // presences.
}*/ for (JID remotePresence : knownRemotePresences) {
if (recipientJID.toBareJID().equals(remotePresence.toBareJID())) {
recipientFullJIDs.add(remotePresence);
}
}
}
if (recipientFullJIDs.isEmpty()) { if (recipientFullJIDs.isEmpty()) {
router.route(message); router.route(message);
...@@ -548,4 +562,12 @@ public class PEPService implements PubSubService { ...@@ -548,4 +562,12 @@ public class PEPService implements PubSubService {
return false; return false;
} }
public boolean addRemotePresence(JID jidFrom) {
return knownRemotePresences.add(jidFrom);
}
public boolean removeRemotePresence(JID jidFrom) {
return knownRemotePresences.remove(jidFrom);
}
} }
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