Commit 7750f416 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

1) My little small refactoring.

2) Reroute failed packet to full JID to bare JID. JM-1075

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@8406 b35dd754-fafc-0310-a699-88a17e54d16e
parent 35bb6b57
...@@ -16,11 +16,14 @@ import org.jivesoftware.openfire.interceptor.InterceptorManager; ...@@ -16,11 +16,14 @@ import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.interceptor.PacketRejectedException; import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.session.ClientSession; import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.session.Session; import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log; import org.xmpp.packet.JID;
import org.xmpp.packet.*; import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
import java.util.*; import java.util.StringTokenizer;
/** /**
* <p>Route message packets throughout the server.</p> * <p>Route message packets throughout the server.</p>
...@@ -37,6 +40,7 @@ public class MessageRouter extends BasicModule { ...@@ -37,6 +40,7 @@ public class MessageRouter extends BasicModule {
private RoutingTable routingTable; private RoutingTable routingTable;
private SessionManager sessionManager; private SessionManager sessionManager;
private MulticastRouter multicastRouter; private MulticastRouter multicastRouter;
private UserManager userManager;
private String serverName; private String serverName;
...@@ -68,14 +72,11 @@ public class MessageRouter extends BasicModule { ...@@ -68,14 +72,11 @@ public class MessageRouter extends BasicModule {
try { try {
// Invoke the interceptors before we process the read packet // Invoke the interceptors before we process the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true, false); InterceptorManager.getInstance().invokeInterceptors(packet, session, true, false);
if (session == null if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) {
|| session.getStatus() == Session.STATUS_AUTHENTICATED)
{
JID recipientJID = packet.getTo(); JID recipientJID = packet.getTo();
// Check if the message was sent to the server hostname // Check if the message was sent to the server hostname
if (recipientJID != null && recipientJID.getNode() == null && if (recipientJID != null && recipientJID.getNode() == null && recipientJID.getResource() == null &&
recipientJID.getResource() == null &&
serverName.equals(recipientJID.getDomain())) { serverName.equals(recipientJID.getDomain())) {
if (packet.getElement().element("addresses") != null) { if (packet.getElement().element("addresses") != null) {
// Message includes multicast processing instructions. Ask the multicastRouter // Message includes multicast processing instructions. Ask the multicastRouter
...@@ -91,25 +92,12 @@ public class MessageRouter extends BasicModule { ...@@ -91,25 +92,12 @@ public class MessageRouter extends BasicModule {
} }
try { try {
// Check if message was sent to a bare JID of a local user // Deliver stanza to requested route
if (recipientJID != null && recipientJID.getResource() == null && routingTable.routePacket(recipientJID, packet);
serverName.equals(recipientJID.getDomain())) {
routeToBareJID(recipientJID, packet);
}
else {
// Deliver stanza to requested route
routingTable.routePacket(recipientJID, packet);
}
} }
catch (Exception e) { catch (Exception e) {
try { routingFailed(recipientJID, packet);
messageStrategy.storeOffline(packet);
}
catch (Exception e1) {
Log.error(e1);
}
} }
} }
else { else {
packet.setTo(session.getAddress()); packet.setTo(session.getAddress());
...@@ -135,100 +123,6 @@ public class MessageRouter extends BasicModule { ...@@ -135,100 +123,6 @@ public class MessageRouter extends BasicModule {
} }
} }
/**
* Deliver the message sent to the bare JID of a local user to the best connected resource. If the
* target user is not online then messages will be stored offline according to the offline strategy.
* However, if the user is connected from only one resource then the message will be delivered to
* that resource. In the case that the user is connected from many resources the logic will be the
* following:
* <ol>
* <li>Select resources with highest priority</li>
* <li>Select resources with highest show value (chat, available, away, xa, dnd)</li>
* <li>Select resource with most recent activity</li>
* </ol>
*
* Admins can override the above logic and just send the message to all connected resources
* with highest priority by setting the system property <tt>route.all-resources</tt> to
* <tt>true</tt>.
*
* @param recipientJID the bare JID of the target local user.
* @param packet the message to send.
*/
private void routeToBareJID(JID recipientJID, Message packet) {
List<ClientSession> sessions = sessionManager.getHighestPrioritySessions(recipientJID.getNode());
if (sessions.isEmpty()) {
// No session is available so store offline
messageStrategy.storeOffline(packet);
}
else if (sessions.size() == 1) {
// Found only one session so deliver message
sessions.get(0).process(packet);
}
else {
// Many sessions have the highest priority (be smart now) :)
if (!JiveGlobals.getBooleanProperty("route.all-resources", false)) {
// Sort sessions by show value (e.g. away, xa)
Collections.sort(sessions, new Comparator<ClientSession>() {
public int compare(ClientSession o1, ClientSession o2) {
int thisVal = getShowValue(o1);
int anotherVal = getShowValue(o2);
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}
/**
* Priorities are: chat, available, away, xa, dnd.
*/
private int getShowValue(ClientSession session) {
Presence.Show show = session.getPresence().getShow();
if (show == Presence.Show.chat) {
return 1;
}
else if (show == null) {
return 2;
}
else if (show == Presence.Show.away) {
return 3;
}
else if (show == Presence.Show.xa) {
return 4;
}
else {
return 5;
}
}
});
// Get same sessions with same max show value
List<ClientSession> targets = new ArrayList<ClientSession>();
Presence.Show showFilter = sessions.get(0).getPresence().getShow();
for (ClientSession session : sessions) {
if (session.getPresence().getShow() == showFilter) {
targets.add(session);
}
else {
break;
}
}
// Get session with most recent activity (and highest show value)
Collections.sort(targets, new Comparator<ClientSession>() {
public int compare(ClientSession o1, ClientSession o2) {
return o1.getLastActiveDate().compareTo(o2.getLastActiveDate());
}
});
// Deliver stanza to session with highest priority, highest show value and most recent activity
targets.get(0).process(packet);
}
else {
// Deliver stanza to all connected resources with highest priority
for (ClientSession session : sessions) {
session.process(packet);
}
}
}
}
/** /**
* Forwards the received message to the list of users defined in the property * Forwards the received message to the list of users defined in the property
* <b>xmpp.forward.admins</b>. The property may include bare JIDs or just usernames separated * <b>xmpp.forward.admins</b>. The property may include bare JIDs or just usernames separated
...@@ -274,15 +168,24 @@ public class MessageRouter extends BasicModule { ...@@ -274,15 +168,24 @@ public class MessageRouter extends BasicModule {
routingTable = server.getRoutingTable(); routingTable = server.getRoutingTable();
sessionManager = server.getSessionManager(); sessionManager = server.getSessionManager();
multicastRouter = server.getMulticastRouter(); multicastRouter = server.getMulticastRouter();
userManager = server.getUserManager();
serverName = server.getServerInfo().getName(); serverName = server.getServerInfo().getName();
} }
/** /**
* Notification message indicating that a packet has failed to be routed to the receipient. * Notification message indicating that a packet has failed to be routed to the receipient.
* *
* @param receipient address of the entity that failed to receive the packet.
* @param packet Message packet that failed to be sent to the receipient. * @param packet Message packet that failed to be sent to the receipient.
*/ */
public void routingFailed(Packet packet) { public void routingFailed(JID receipient, Packet packet) {
messageStrategy.storeOffline((Message) packet); // If message was sent to an unavailable full JID of a user then retry using the bare JID
if (serverName.equals(receipient.getDomain()) && receipient.getResource() != null &&
userManager.isRegisteredUser(receipient.getNode())) {
routingTable.routePacket(new JID(receipient.toBareJID()), packet);
} else {
// Just store the message offline
messageStrategy.storeOffline((Message) packet);
}
} }
} }
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