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,
}
}
}
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;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketExtension;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
......@@ -148,8 +147,18 @@ public class PEPService implements PubSubService {
*/
private Timer timer = new Timer("PEP service maintenance");
/**
* Date format to use for time stamps in delayed event notifications.
*/
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 {
fastDateFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("UTC"));
}
......@@ -332,16 +341,21 @@ public class PEPService implements PubSubService {
// 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
// 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)) {
for (ClientSession clientSession : SessionManager.getInstance().getSessions(recipientJID.getNode())) {
recipientFullJIDs.add(clientSession.getAddress());
}
}
// TODO: Try to get presence info even if not local...
/*else {
recipientFullJIDs.add(recipientJID);
}*/
else {
// Since recipientJID is not local, try to get presence info from cached known remote
// presences.
for (JID remotePresence : knownRemotePresences) {
if (recipientJID.toBareJID().equals(remotePresence.toBareJID())) {
recipientFullJIDs.add(remotePresence);
}
}
}
if (recipientFullJIDs.isEmpty()) {
router.route(message);
......@@ -548,4 +562,12 @@ public class PEPService implements PubSubService {
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