Commit 507c70a1 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gaston

Changed way packets are being routed to internal components. Internal and...

Changed way packets are being routed to internal components. Internal and external components now have a route in the RoutingTable. LIVE-592


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@943 b35dd754-fafc-0310-a699-88a17e54d16e
parent a2ee8ade
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.xmpp.packet.Packet;
/** /**
* Interface for Components. * Interface for Components.
...@@ -19,12 +19,16 @@ import org.xmpp.packet.Packet; ...@@ -19,12 +19,16 @@ import org.xmpp.packet.Packet;
* @see ComponentManager * @see ComponentManager
* @author Derek DeMoro * @author Derek DeMoro
*/ */
public interface Component { public interface Component extends RoutableChannelHandler {
/** /**
* Processes an incoming packet addressed to this component. * Returns the service name of this component. The service name is usually the part before the
* dot before the server address in a JID. For example, given this JID jdoe@broadcast.localhost
* the service name would be broadcast.<p>
*
* This information is useful when adding or removing the component from the ComponentManager.
* *
* @param packet the packet. * @return the service name of this component.
*/ */
void processPacket(Packet packet); public String getServiceName();
} }
...@@ -11,12 +11,14 @@ ...@@ -11,12 +11,14 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import java.util.Map; import org.jivesoftware.messenger.auth.UnauthorizedException;
import java.util.concurrent.ConcurrentHashMap;
import org.xmpp.packet.Packet;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Presence; import org.xmpp.packet.Presence;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* Manages the registration and delegation of Components. The ComponentManager * Manages the registration and delegation of Components. The ComponentManager
* is responsible for managing registration and delegation of {@link Component Components}, * is responsible for managing registration and delegation of {@link Component Components},
...@@ -49,7 +51,9 @@ public class ComponentManager { ...@@ -49,7 +51,9 @@ public class ComponentManager {
/** /**
* Registers a <code>Component</code> with the server and maps * Registers a <code>Component</code> with the server and maps
* to particular jid. * to particular jid. A route for the new Component will be added to
* the <code>RoutingTable</code> based on the address of the component.
* Note: The address of the component will be a JID wih empties node and resource.
* *
* @param jid the jid to map to. * @param jid the jid to map to.
* @param component the <code>Component</code> to register. * @param component the <code>Component</code> to register.
...@@ -58,17 +62,27 @@ public class ComponentManager { ...@@ -58,17 +62,27 @@ public class ComponentManager {
jid = new JID(jid).toBareJID(); jid = new JID(jid).toBareJID();
components.put(jid, component); components.put(jid, component);
// Add the route to the new service provided by the component
XMPPServer.getInstance().getRoutingTable().addRoute(component.getAddress(), component);
// Check for potential interested users. // Check for potential interested users.
checkPresences(); checkPresences();
} }
/** /**
* Removes a <code>Component</code> from the server. * Removes a <code>Component</code> from the server. The route for the new Component
* will be removed from the <code>RoutingTable</code>.
* *
* @param jid the jid mapped to the particular component. * @param jid the jid mapped to the particular component.
*/ */
public void removeComponent(String jid) { public void removeComponent(String jid) {
components.remove(new JID(jid).toBareJID()); JID componentJID = new JID(jid);
components.remove(componentJID.toBareJID());
// Remove the route for the service provided by the component
if (XMPPServer.getInstance().getRoutingTable() != null) {
XMPPServer.getInstance().getRoutingTable().removeRoute(componentJID);
}
} }
/** /**
...@@ -127,10 +141,16 @@ public class ComponentManager { ...@@ -127,10 +141,16 @@ public class ComponentManager {
Presence presence = new Presence(); Presence presence = new Presence();
presence.setFrom(prober); presence.setFrom(prober);
presence.setTo(probee); presence.setTo(probee);
component.processPacket(presence); try {
component.process(presence);
// No reason to hold onto prober reference.
presenceMap.remove(prober);
}
catch (UnauthorizedException e) {
// Do nothing. This error should never occur
}
// No reason to hold onto prober reference.
presenceMap.remove(prober);
} }
} }
} }
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.xmpp.packet.IQ; import org.dom4j.Element;
import org.xmpp.packet.PacketError; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.JID;
import org.jivesoftware.messenger.container.BasicModule; import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.handler.IQHandler; import org.jivesoftware.messenger.handler.IQHandler;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.dom4j.Element; import org.jivesoftware.util.Log;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
...@@ -40,6 +40,7 @@ public class IQRouter extends BasicModule { ...@@ -40,6 +40,7 @@ public class IQRouter extends BasicModule {
private List<IQHandler> iqHandlers = new ArrayList<IQHandler>(); private List<IQHandler> iqHandlers = new ArrayList<IQHandler>();
private Map<String, IQHandler> namespace2Handlers = new ConcurrentHashMap<String, IQHandler>(); private Map<String, IQHandler> namespace2Handlers = new ConcurrentHashMap<String, IQHandler>();
private SessionManager sessionManager; private SessionManager sessionManager;
private ComponentManager componentManager;
/** /**
* Creates a packet router. * Creates a packet router.
...@@ -76,12 +77,7 @@ public class IQRouter extends BasicModule { ...@@ -76,12 +77,7 @@ public class IQRouter extends BasicModule {
else { else {
packet.setTo(sessionManager.getSession(packet.getFrom()).getAddress()); packet.setTo(sessionManager.getSession(packet.getFrom()).getAddress());
packet.setError(PacketError.Condition.not_authorized); packet.setError(PacketError.Condition.not_authorized);
try { sessionManager.getSession(packet.getFrom()).process(packet);
sessionManager.getSession(packet.getFrom()).process(packet);
}
catch (UnauthorizedException ue) {
Log.error(ue);
}
} }
} }
...@@ -128,8 +124,15 @@ public class IQRouter extends BasicModule { ...@@ -128,8 +124,15 @@ public class IQRouter extends BasicModule {
routingTable = server.getRoutingTable(); routingTable = server.getRoutingTable();
iqHandlers.addAll(server.getIQHandlers()); iqHandlers.addAll(server.getIQHandlers());
sessionManager = server.getSessionManager(); sessionManager = server.getSessionManager();
componentManager = ComponentManager.getInstance();
} }
/**
* A JID is considered local if:
* 1) is null or
* 2) has no domain or domain is empty or
* 3) has no resource or resource is empty
*/
private boolean isLocalServer(JID recipientJID) { private boolean isLocalServer(JID recipientJID) {
return recipientJID == null || recipientJID.getDomain() == null return recipientJID == null || recipientJID.getDomain() == null
|| "".equals(recipientJID.getDomain()) || recipientJID.getResource() == null || "".equals(recipientJID.getDomain()) || recipientJID.getResource() == null
...@@ -139,8 +142,17 @@ public class IQRouter extends BasicModule { ...@@ -139,8 +142,17 @@ public class IQRouter extends BasicModule {
private void handle(IQ packet) { private void handle(IQ packet) {
JID recipientJID = packet.getTo(); JID recipientJID = packet.getTo();
try { try {
if (isLocalServer(recipientJID)) { // Check for registered components
Component component = null;
if (recipientJID != null) {
component = componentManager.getComponent(packet.getTo().toBareJID());
}
if (component != null) {
// A component was found that can handle the Packet
component.process(packet);
}
else if (isLocalServer(recipientJID)) {
// Let the server handle the Packet
Element childElement = packet.getChildElement(); Element childElement = packet.getChildElement();
String namespace = null; String namespace = null;
if (childElement != null) { if (childElement != null) {
...@@ -158,7 +170,8 @@ public class IQRouter extends BasicModule { ...@@ -158,7 +170,8 @@ public class IQRouter extends BasicModule {
// Answer an error since the server can't handle the requested namespace // Answer an error since the server can't handle the requested namespace
reply.setError(PacketError.Condition.service_unavailable); reply.setError(PacketError.Condition.service_unavailable);
} }
else if (recipientJID.getNode() == null || "".equals(recipientJID.getNode())) { else if (recipientJID.getNode() == null ||
"".equals(recipientJID.getNode())) {
// Answer an error if JID is of the form <domain> // Answer an error if JID is of the form <domain>
reply.setError(PacketError.Condition.feature_not_implemented); reply.setError(PacketError.Condition.feature_not_implemented);
} }
......
...@@ -30,18 +30,11 @@ public class PacketRouter extends BasicModule { ...@@ -30,18 +30,11 @@ public class PacketRouter extends BasicModule {
private PresenceRouter presenceRouter; private PresenceRouter presenceRouter;
private MessageRouter messageRouter; private MessageRouter messageRouter;
/**
* Initialize ComponentManager to handle delegation of packets.
*/
private ComponentManager componentManager;
/** /**
* Constructs a packet router. * Constructs a packet router.
*/ */
public PacketRouter() { public PacketRouter() {
super("XMPP Packet Router"); super("XMPP Packet Router");
componentManager = ComponentManager.getInstance();
} }
/** /**
...@@ -52,13 +45,8 @@ public class PacketRouter extends BasicModule { ...@@ -52,13 +45,8 @@ public class PacketRouter extends BasicModule {
* any accesses to class resources. * any accesses to class resources.
* *
* @param packet The packet to route * @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) { public void route(Packet packet) {
if(hasRouted(packet)){
return;
}
if (packet instanceof Message) { if (packet instanceof Message) {
route((Message)packet); route((Message)packet);
} }
...@@ -74,34 +62,15 @@ public class PacketRouter extends BasicModule { ...@@ -74,34 +62,15 @@ public class PacketRouter extends BasicModule {
} }
public void route(IQ packet) { public void route(IQ packet) {
if (!hasRouted(packet)){ iqRouter.route(packet);
iqRouter.route(packet);
}
} }
public void route(Message packet) { public void route(Message packet) {
if (!hasRouted(packet)){ messageRouter.route(packet);
messageRouter.route(packet);
}
} }
public void route(Presence packet) { public void route(Presence packet) {
if (!hasRouted(packet)) { presenceRouter.route(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) { public void initialize(XMPPServer server) {
......
...@@ -90,7 +90,7 @@ public class PresenceRouter extends BasicModule { ...@@ -90,7 +90,7 @@ public class PresenceRouter extends BasicModule {
ChannelHandler handler = routingTable.getRoute(recipientJID); ChannelHandler handler = routingTable.getRoute(recipientJID);
handler.process(packet); handler.process(packet);
// Notify the PresenceUpdateHandler of the directed presence // Notify the PresenceUpdateHandler of the directed presence
updateHandler.directedPresenceSent(packet, handler); updateHandler.directedPresenceSent(packet, handler, recipientJID.toString());
} }
} }
......
...@@ -52,7 +52,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable { ...@@ -52,7 +52,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable {
routeLock.writeLock().lock(); routeLock.writeLock().lock();
try { try {
if (routes.isEmpty()) { if (routes.isEmpty() || destination instanceof Component) {
routes.put(node.getDomain(), destination); routes.put(node.getDomain(), destination);
} }
else { else {
......
...@@ -46,6 +46,7 @@ public class BroadcastPlugin implements Plugin, Component { ...@@ -46,6 +46,7 @@ public class BroadcastPlugin implements Plugin, Component {
private GroupManager groupManager; private GroupManager groupManager;
private List<JID> allowedUsers; private List<JID> allowedUsers;
private boolean groupMembersAllowed; private boolean groupMembersAllowed;
private JID serviceJID;
/** /**
* Constructs a new broadcast plugin. * Constructs a new broadcast plugin.
...@@ -55,6 +56,8 @@ public class BroadcastPlugin implements Plugin, Component { ...@@ -55,6 +56,8 @@ public class BroadcastPlugin implements Plugin, Component {
groupMembersAllowed = JiveGlobals.getBooleanProperty( groupMembersAllowed = JiveGlobals.getBooleanProperty(
"plugin.broadcast.groupMembersAllowed", true); "plugin.broadcast.groupMembersAllowed", true);
allowedUsers = stringToList(JiveGlobals.getProperty("plugin.broadcast.allowedUsers", "")); allowedUsers = stringToList(JiveGlobals.getProperty("plugin.broadcast.allowedUsers", ""));
serviceJID =
new JID(serviceName + "." + XMPPServer.getInstance().getServerInfo().getName());
} }
// Plugin Interface // Plugin Interface
...@@ -93,7 +96,7 @@ public class BroadcastPlugin implements Plugin, Component { ...@@ -93,7 +96,7 @@ public class BroadcastPlugin implements Plugin, Component {
// Component Interface // Component Interface
public void processPacket(Packet packet) { public void process(Packet packet) {
// Only respond to incoming messages. TODO: handle disco, presence, etc. // Only respond to incoming messages. TODO: handle disco, presence, etc.
if (packet instanceof Message) { if (packet instanceof Message) {
Message message = (Message)packet; Message message = (Message)packet;
...@@ -183,6 +186,10 @@ public class BroadcastPlugin implements Plugin, Component { ...@@ -183,6 +186,10 @@ public class BroadcastPlugin implements Plugin, Component {
return serviceName; return serviceName;
} }
public JID getAddress() {
return serviceJID;
}
/** /**
* Sets the service name of this component, which is "broadcast" by default. * Sets the service name of this component, which is "broadcast" by default.
* *
...@@ -200,6 +207,8 @@ public class BroadcastPlugin implements Plugin, Component { ...@@ -200,6 +207,8 @@ public class BroadcastPlugin implements Plugin, Component {
ComponentManager.getInstance().removeComponent(this.serviceName); ComponentManager.getInstance().removeComponent(this.serviceName);
ComponentManager.getInstance().addComponent(serviceName, this); ComponentManager.getInstance().addComponent(serviceName, this);
this.serviceName = serviceName; this.serviceName = serviceName;
serviceJID =
new JID(serviceName + "." + XMPPServer.getInstance().getServerInfo().getName());
} }
/** /**
......
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