Commit 48676c7c authored by Christian Schudt's avatar Christian Schudt

OF-818 Message routing to bare JID can route to negative priority resources

This commit fixes the regression, that was introduced with the addition of Message Carbons.
Message Carbons are delivered to all non-negative sessions.
If there's no Message Carbons-enabled session, it will be delivered to the highest priority session only.
parent d7af3afc
...@@ -525,29 +525,36 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -525,29 +525,36 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
} }
} }
if (sessions.isEmpty()) { // Get the sessions with non-negative priority for message carbons processing.
List<ClientSession> nonNegativePrioritySessions = getNonNegativeSessions(sessions, 0);
// Get the highest priority sessions for normal processing.
List<ClientSession> highestPrioritySessions = getHighestPrioritySessions(nonNegativePrioritySessions);
// Check for message carbons enabled sessions and send the message to them.
for (ClientSession session : nonNegativePrioritySessions) {
// Deliver to each session, if is message carbons enabled.
if (shouldCarbonCopyToResource(session, packet, isPrivate)) {
session.process(packet);
}
}
if (highestPrioritySessions.isEmpty()) {
// No session is available so store offline // No session is available so store offline
Log.debug("Unable to route packet. No session is available so store offline. {} ", packet.toXML()); Log.debug("Unable to route packet. No session is available so store offline. {} ", packet.toXML());
return false; return false;
} }
else if (sessions.size() == 1) { else if (highestPrioritySessions.size() == 1) {
// Found only one session so deliver message // Found only one session so deliver message (if it hasn't already been processed because it has message carbons enabled)
sessions.get(0).process(packet); if (!shouldCarbonCopyToResource(highestPrioritySessions.get(0), packet, isPrivate)) {
highestPrioritySessions.get(0).process(packet);
}
} }
else { else {
// Check for message carbons enabled sessions and sent message to them.
for (ClientSession session : sessions) {
// Deliver to each session.
if (shouldSentToResource(session, packet, isPrivate)) {
session.process(packet);
}
}
// Many sessions have the highest priority (be smart now) :) // Many sessions have the highest priority (be smart now) :)
if (!JiveGlobals.getBooleanProperty("route.all-resources", false)) { if (!JiveGlobals.getBooleanProperty("route.all-resources", false)) {
// Sort sessions by show value (e.g. away, xa) // Sort sessions by show value (e.g. away, xa)
Collections.sort(sessions, new Comparator<ClientSession>() { Collections.sort(highestPrioritySessions, new Comparator<ClientSession>() {
public int compare(ClientSession o1, ClientSession o2) { public int compare(ClientSession o1, ClientSession o2) {
int thisVal = getShowValue(o1); int thisVal = getShowValue(o1);
...@@ -580,8 +587,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -580,8 +587,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
// Get same sessions with same max show value // Get same sessions with same max show value
List<ClientSession> targets = new ArrayList<ClientSession>(); List<ClientSession> targets = new ArrayList<ClientSession>();
Presence.Show showFilter = sessions.get(0).getPresence().getShow(); Presence.Show showFilter = highestPrioritySessions.get(0).getPresence().getShow();
for (ClientSession session : sessions) { for (ClientSession session : highestPrioritySessions) {
if (session.getPresence().getShow() == showFilter) { if (session.getPresence().getShow() == showFilter) {
targets.add(session); targets.add(session);
} }
...@@ -599,17 +606,15 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -599,17 +606,15 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
// Make sure, we don't send the packet again, if it has already been sent by message carbons. // Make sure, we don't send the packet again, if it has already been sent by message carbons.
ClientSession session = targets.get(0); ClientSession session = targets.get(0);
if (!shouldSentToResource(session, packet, isPrivate)) { if (!shouldCarbonCopyToResource(session, packet, isPrivate)) {
// Deliver stanza to session with highest priority, highest show value and most recent activity // Deliver stanza to session with highest priority, highest show value and most recent activity
session.process(packet); session.process(packet);
} }
} }
else { else {
// Deliver stanza to all connected resources with highest priority for (ClientSession session : highestPrioritySessions) {
sessions = getHighestPrioritySessions(sessions);
for (ClientSession session : sessions) {
// Make sure, we don't send the packet again, if it has already been sent by message carbons. // Make sure, we don't send the packet again, if it has already been sent by message carbons.
if (!shouldSentToResource(session, packet, isPrivate)) { if (!shouldCarbonCopyToResource(session, packet, isPrivate)) {
session.process(packet); session.process(packet);
} }
} }
...@@ -618,7 +623,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -618,7 +623,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
return true; return true;
} }
private boolean shouldSentToResource(ClientSession session, Message message, boolean isPrivate) { private boolean shouldCarbonCopyToResource(ClientSession session, Message message, boolean isPrivate) {
return !isPrivate && session.isMessageCarbonsEnabled() && message.getType() == Message.Type.chat; return !isPrivate && session.isMessageCarbonsEnabled() && message.getType() == Message.Type.chat;
} }
...@@ -638,14 +643,25 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -638,14 +643,25 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
highest = priority; highest = priority;
} }
} }
// Answer an empty collection if all have negative priority // Get sessions that have the highest priority
if (highest == Integer.MIN_VALUE) { return getNonNegativeSessions(sessions, highest);
}
/**
* Gets the non-negative session from a minimal priority.
*
* @param sessions The sessions.
* @param min The minimal priority.
* @return The filtered sessions.
*/
private List<ClientSession> getNonNegativeSessions(List<ClientSession> sessions, int min) {
if (min < 0) {
return Collections.emptyList(); return Collections.emptyList();
} }
// Get sessions that have the highest priority // Get sessions with priority >= min
List<ClientSession> answer = new ArrayList<ClientSession>(sessions.size()); List<ClientSession> answer = new ArrayList<ClientSession>(sessions.size());
for (ClientSession session : sessions) { for (ClientSession session : sessions) {
if (session.getPresence().getPriority() == highest) { if (session.getPresence().getPriority() >= min) {
answer.add(session); answer.add(session);
} }
} }
......
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