Commit 919511cd authored by Matt Tucker's avatar Matt Tucker Committed by matt

Refactored router classes (JM-138).


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@921 b35dd754-fafc-0310-a699-88a17e54d16e
parent 91204e59
......@@ -12,6 +12,11 @@
package org.jivesoftware.messenger;
import org.xmpp.packet.Message;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.container.BasicModule;
/**
* <p>Route message packets throughout the server.</p>
......@@ -22,7 +27,19 @@ import org.xmpp.packet.Message;
*
* @author Iain Shigeoka
*/
public interface MessageRouter {
public class MessageRouter extends BasicModule {
private OfflineMessageStrategy messageStrategy;
private RoutingTable routingTable;
private SessionManager sessionManager;
/**
* Constructs a message router.
*/
public MessageRouter() {
super("XMPP Message Router");
}
/**
* <p>Performs the actual packet routing.</p>
* <p>You routing is considered 'quick' and implementations may not take
......@@ -36,5 +53,46 @@ public interface MessageRouter {
* @param packet The packet to route
* @throws NullPointerException If the packet is null
*/
public void route(Message packet);
public void route(Message packet) {
if (packet == null) {
throw new NullPointerException();
}
Session session = sessionManager.getSession(packet.getFrom());
if (session == null
|| session.getStatus() == Session.STATUS_AUTHENTICATED)
{
JID recipientJID = packet.getTo();
try {
routingTable.getBestRoute(recipientJID).process(packet);
}
catch (Exception e) {
try {
messageStrategy.storeOffline(packet);
}
catch (Exception e1) {
Log.error(e1);
}
}
}
else {
packet.setTo(session.getAddress());
packet.setFrom((JID)null);
packet.setError(PacketError.Condition.not_authorized);
try {
session.process(packet);
}
catch (UnauthorizedException ue) {
Log.error(ue);
}
}
}
public void initialize(XMPPServer server) {
super.initialize(server);
messageStrategy = server.getOfflineMessageStrategy();
routingTable = server.getRoutingTable();
sessionManager = server.getSessionManager();
}
}
......@@ -12,6 +12,10 @@
package org.jivesoftware.messenger;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Message;
import org.xmpp.packet.Presence;
import org.xmpp.packet.IQ;
import org.jivesoftware.messenger.container.BasicModule;
/**
* <p>An uber router that can handle any packet type.</p>
......@@ -20,17 +24,90 @@ import org.xmpp.packet.Packet;
*
* @author Iain Shigeoka
*/
public interface PacketRouter extends MessageRouter, PresenceRouter {
public class PacketRouter extends BasicModule {
private IQRouter iqRouter;
private PresenceRouter presenceRouter;
private MessageRouter messageRouter;
/**
* Initialize ComponentManager to handle delegation of packets.
*/
private ComponentManager componentManager;
/**
* Constructs a packet router.
*/
public PacketRouter() {
super("XMPP Packet Router");
componentManager = ComponentManager.getInstance();
}
/**
* <p>Routes the given packet based on packet recipient and sender.</p>
* Routes the given packet based on packet recipient and sender. The
* router defers actual routing decisions to other classes.
* <h2>Warning</h2>
* <p>Be careful to enforce concurrency DbC of concurrent by synchronizing
* any accesses to class resources.</p>
* Be careful to enforce concurrency DbC of concurrent by synchronizing
* any accesses to class resources.
*
* @param packet The packet to route
* @throws NullPointerException If the packet is null
* @throws IllegalArgumentException If the packet is not one of the three XMPP packet types
* @throws NullPointerException If the packet is null or the packet could not be routed
*/
public void route(Packet packet) throws IllegalArgumentException, NullPointerException;
}
public void route(Packet packet) {
if(hasRouted(packet)){
return;
}
if (packet instanceof Message) {
route((Message)packet);
}
else if (packet instanceof Presence) {
route((Presence)packet);
}
else if (packet instanceof IQ) {
route((IQ)packet);
}
else {
throw new IllegalArgumentException();
}
}
public void route(IQ packet) {
if (!hasRouted(packet)){
iqRouter.route(packet);
}
}
public void route(Message packet) {
if (!hasRouted(packet)){
messageRouter.route(packet);
}
}
public void route(Presence packet) {
if (!hasRouted(packet)) {
presenceRouter.route(packet);
}
}
public boolean hasRouted(Packet packet){
if (packet.getTo() == null) {
return false;
}
// Check for registered components
Component component = componentManager.getComponent(packet.getTo().toBareJID());
if (component != null) {
component.processPacket(packet);
return true;
}
return false;
}
public void initialize(XMPPServer server) {
super.initialize(server);
iqRouter = server.getIQRouter();
messageRouter = server.getMessageRouter();
presenceRouter = server.getPresenceRouter();
}
}
\ No newline at end of file
......@@ -12,6 +12,14 @@
package org.jivesoftware.messenger;
import org.xmpp.packet.Presence;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import org.jivesoftware.messenger.handler.PresenceUpdateHandler;
import org.jivesoftware.messenger.handler.PresenceSubscribeHandler;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.LocaleUtils;
/**
* <p>Route presence packets throughout the server.</p>
......@@ -22,19 +30,108 @@ import org.xmpp.packet.Presence;
*
* @author Iain Shigeoka
*/
public interface PresenceRouter {
public class PresenceRouter extends BasicModule {
private RoutingTable routingTable;
private PresenceUpdateHandler updateHandler;
private PresenceSubscribeHandler subscribeHandler;
private SessionManager sessionManager;
/**
* Constructs a presence router.
*/
public PresenceRouter() {
super("XMPP Presence Router");
}
/**
* <p>Performs the actual packet routing.</p>
* <p>You routing is considered 'quick' and implementations may not take
* excessive amounts of time to complete the routing. If routing will take
* a long amount of time, the actual routing should be done in another thread
* so this method returns quickly.</p>
* <h2>Warning</h2>
* <p>Be careful to enforce concurrency DbC of concurrent by synchronizing
* any accesses to class resources.</p>
* Routes presence packets.
*
* @param packet The packet to route
* @throws NullPointerException If the packet is null
* @param packet the packet to route.
* @throws NullPointerException if the packet is null.
*/
public void route(Presence packet);
public void route(Presence packet) {
if (packet == null) {
throw new NullPointerException();
}
Session session = sessionManager.getSession(packet.getFrom());
if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) {
handle(packet);
}
else {
packet.setTo(session.getAddress());
packet.setFrom((JID)null);
packet.setError(PacketError.Condition.not_authorized);
try {
session.process(packet);
}
catch (UnauthorizedException ue) {
Log.error(ue);
}
}
}
private void handle(Presence packet) {
JID recipientJID = packet.getTo();
try {
Presence.Type type = packet.getType();
// Presence updates (null is 'available')
if (type == null || Presence.Type.unavailable == type) {
// check for local server target
if (recipientJID == null
|| recipientJID.getDomain() == null
|| "".equals(recipientJID.getDomain())
|| (recipientJID.getNode() == null && recipientJID.getResource() == null)) {
updateHandler.process(packet);
}
else {
// The user sent a directed presence to an entity
ChannelHandler handler = routingTable.getRoute(recipientJID);
handler.process(packet);
// Notify the PresenceUpdateHandler of the directed presence
updateHandler.directedPresenceSent(packet, handler);
}
}
else if (Presence.Type.subscribe == type // presence subscriptions
|| Presence.Type.unsubscribe == type
|| Presence.Type.subscribed == type
|| Presence.Type.unsubscribed == type)
{
subscribeHandler.process(packet);
}
else {
// It's an unknown or ERROR type, just deliver it because there's nothing else to do with it
routingTable.getRoute(recipientJID).process(packet);
}
}
catch (NoSuchRouteException e) {
// Do nothing, presence to unreachable routes are dropped
}
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error.routing"), e);
try {
Session session = sessionManager.getSession(packet.getFrom());
if (session != null) {
Connection conn = session.getConnection();
if (conn != null) {
conn.close();
}
}
}
catch (UnauthorizedException e1) {
// do nothing
}
}
}
public void initialize(XMPPServer server) {
super.initialize(server);
routingTable = server.getRoutingTable();
updateHandler = server.getPresenceUpdateHandler();
subscribeHandler = server.getPresenceSubscribeHandler();
sessionManager = server.getSessionManager();
}
}
......@@ -233,10 +233,10 @@ public class XMPPServer {
loadModule(ConnectionManagerImpl.class.getName());
loadModule(PresenceManagerImpl.class.getName());
loadModule(SessionManager.class.getName());
loadModule(PacketRouterImpl.class.getName());
loadModule(PacketRouter.class.getName());
loadModule(IQRouter.class.getName());
loadModule(MessageRouterImpl.class.getName());
loadModule(PresenceRouterImpl.class.getName());
loadModule(MessageRouter.class.getName());
loadModule(PresenceRouter.class.getName());
loadModule(PacketTransporterImpl.class.getName());
loadModule(PacketDelivererImpl.class.getName());
loadModule(TransportHandler.class.getName());
......@@ -681,7 +681,7 @@ public class XMPPServer {
* @return the <code>PacketRouter</code> registered with this server.
*/
public PacketRouter getPacketRouter() {
return (PacketRouter) modules.get(PacketRouterImpl.class);
return (PacketRouter) modules.get(PacketRouter.class);
}
/**
......@@ -773,7 +773,7 @@ public class XMPPServer {
* @return the <code>MessageRouter</code> registered with this server.
*/
public MessageRouter getMessageRouter() {
return (MessageRouter) modules.get(MessageRouterImpl.class);
return (MessageRouter) modules.get(MessageRouter.class);
}
/**
......@@ -784,7 +784,7 @@ public class XMPPServer {
* @return the <code>PresenceRouter</code> registered with this server.
*/
public PresenceRouter getPresenceRouter() {
return (PresenceRouter) modules.get(PresenceRouterImpl.class);
return (PresenceRouter) modules.get(PresenceRouter.class);
}
/**
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.spi;
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.util.Log;
import org.xmpp.packet.Message;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
/**
* Generic message routing base class.
*
* @author Iain Shigeoka
*/
public class MessageRouterImpl extends BasicModule implements MessageRouter {
private OfflineMessageStrategy messageStrategy;
private RoutingTable routingTable;
private SessionManager sessionManager;
/**
* <p>Create a packet router.</p>
*/
public MessageRouterImpl() {
super("XMPP Message Router");
}
public void route(Message packet) {
if (packet == null) {
throw new NullPointerException();
}
Session session = sessionManager.getSession(packet.getFrom());
if (session == null
|| session.getStatus() == Session.STATUS_AUTHENTICATED)
{
JID recipientJID = packet.getTo();
try {
routingTable.getBestRoute(recipientJID).process(packet);
}
catch (Exception e) {
try {
messageStrategy.storeOffline(packet);
}
catch (Exception e1) {
Log.error(e1);
}
}
}
else {
packet.setTo(session.getAddress());
packet.setFrom((JID)null);
packet.setError(PacketError.Condition.not_authorized);
try {
session.process(packet);
}
catch (UnauthorizedException ue) {
Log.error(ue);
}
}
}
public void initialize(XMPPServer server) {
super.initialize(server);
messageStrategy = server.getOfflineMessageStrategy();
routingTable = server.getRoutingTable();
sessionManager = server.getSessionManager();
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.spi;
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.*;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Message;
import org.xmpp.packet.Presence;
import org.xmpp.packet.IQ;
/**
* Generic packet routing base class.
*
* @author Iain Shigeoka
*/
public class PacketRouterImpl extends BasicModule implements PacketRouter {
private IQRouter iqRouter;
private PresenceRouter presenceRouter;
private MessageRouter messageRouter;
/**
* Initialize ComponentManager to handle delegation of packets.
*/
private ComponentManager componentManager;
/**
* Create a packet router.
*/
public PacketRouterImpl() {
super("XMPP Packet Router");
componentManager = ComponentManager.getInstance();
}
/**
* Routes the given packet based on packet recipient and sender. The
* router defers actual routing decisions to other classes.
* <h2>Warning</h2>
* Be careful to enforce concurrency DbC of concurrent by synchronizing
* any accesses to class resources.
*
* @param packet The packet to route
* @throws NullPointerException If the packet is null or the packet could not be routed
*/
public void route(Packet packet) {
if(hasRouted(packet)){
return;
}
if (packet instanceof Message) {
route((Message)packet);
}
else if (packet instanceof Presence) {
route((Presence)packet);
}
else if (packet instanceof IQ) {
route((IQ)packet);
}
else {
throw new IllegalArgumentException();
}
}
public void route(IQ packet) {
if(!hasRouted(packet)){
iqRouter.route(packet);
}
}
public void route(Message packet) {
if(!hasRouted(packet)){
messageRouter.route(packet);
}
}
public void route(Presence packet) {
if (!hasRouted(packet)) {
presenceRouter.route(packet);
}
}
public boolean hasRouted(Packet packet){
if (packet.getTo() == null) {
return false;
}
// Check for registered components
Component component = componentManager.getComponent(packet.getTo().toBareJID());
if (component != null) {
component.processPacket(packet);
return true;
}
return false;
}
public void initialize(XMPPServer server) {
super.initialize(server);
iqRouter = server.getIQRouter();
messageRouter = server.getMessageRouter();
presenceRouter = server.getPresenceRouter();
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.spi;
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.handler.PresenceSubscribeHandler;
import org.jivesoftware.messenger.handler.PresenceUpdateHandler;
import org.xmpp.packet.Presence;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
/**
* Generic presence routing base class.
*
* @author Iain Shigeoka
*/
public class PresenceRouterImpl extends BasicModule implements PresenceRouter {
private RoutingTable routingTable;
private PresenceUpdateHandler updateHandler;
private PresenceSubscribeHandler subscribeHandler;
private SessionManager sessionManager;
/**
* Create a packet router.
*/
public PresenceRouterImpl() {
super("XMPP Presence Router");
}
public void route(Presence packet) {
if (packet == null) {
throw new NullPointerException();
}
Session session = sessionManager.getSession(packet.getFrom());
if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) {
handle(packet);
}
else {
packet.setTo(session.getAddress());
packet.setFrom((JID)null);
packet.setError(PacketError.Condition.not_authorized);
try {
session.process(packet);
}
catch (UnauthorizedException ue) {
Log.error(ue);
}
}
}
private void handle(Presence packet) {
JID recipientJID = packet.getTo();
try {
Presence.Type type = packet.getType();
// Presence updates (null is 'available')
if (type == null || Presence.Type.unavailable == type) {
// check for local server target
if (recipientJID == null
|| recipientJID.getDomain() == null
|| "".equals(recipientJID.getDomain())
|| (recipientJID.getNode() == null && recipientJID.getResource() == null)) {
updateHandler.process(packet);
}
else {
// The user sent a directed presence to an entity
ChannelHandler handler = routingTable.getRoute(recipientJID);
handler.process(packet);
// Notify the PresenceUpdateHandler of the directed presence
updateHandler.directedPresenceSent(packet, handler);
}
}
else if (Presence.Type.subscribe == type // presence subscriptions
|| Presence.Type.unsubscribe == type
|| Presence.Type.subscribed == type
|| Presence.Type.unsubscribed == type)
{
subscribeHandler.process(packet);
}
else {
// It's an unknown or ERROR type, just deliver it because there's nothing else to do with it
routingTable.getRoute(recipientJID).process(packet);
}
}
catch (NoSuchRouteException e) {
// Do nothing, presence to unreachable routes are dropped
}
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error.routing"), e);
try {
Session session = sessionManager.getSession(packet.getFrom());
if (session != null) {
Connection conn = session.getConnection();
if (conn != null) {
conn.close();
}
}
}
catch (UnauthorizedException e1) {
// do nothing
}
}
}
public void initialize(XMPPServer server) {
super.initialize(server);
routingTable = server.getRoutingTable();
updateHandler = server.getPresenceUpdateHandler();
subscribeHandler = server.getPresenceSubscribeHandler();
sessionManager = server.getSessionManager();
}
}
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