Commit d93645fd authored by Thiago Camargo's avatar Thiago Camargo Committed by thiago

[OF-408] - Jingle Nodes API version Upgrade and Tracker Feature Support

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@11947 b35dd754-fafc-0310-a699-88a17e54d16e
parent c55e07de
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
package org.jinglenodes; package org.jinglenodes;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.DocumentHelper;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -27,75 +28,112 @@ import org.xmpp.component.AbstractComponent; ...@@ -27,75 +28,112 @@ import org.xmpp.component.AbstractComponent;
import org.xmpp.jnodes.RelayChannel; import org.xmpp.jnodes.RelayChannel;
import org.xmpp.jnodes.nio.LocalIPResolver; import org.xmpp.jnodes.nio.LocalIPResolver;
import org.xmpp.jnodes.smack.JingleChannelIQ; import org.xmpp.jnodes.smack.JingleChannelIQ;
import org.xmpp.jnodes.smack.JingleTrackerIQ;
import org.xmpp.jnodes.smack.TrackerEntry;
import org.xmpp.packet.IQ; import org.xmpp.packet.IQ;
import org.xmpp.packet.PacketError; import org.xmpp.packet.PacketError;
import java.util.List;
import java.util.ArrayList;
class JingleNodesComponent extends AbstractComponent { class JingleNodesComponent extends AbstractComponent {
private static final Logger Log = LoggerFactory.getLogger(JingleNodesComponent.class); private static final Logger Log = LoggerFactory.getLogger(JingleNodesComponent.class);
private static final String UDP = "udp"; private static final String UDP = "udp";
private static final String PROTOCOL = "protocol"; private static final String PROTOCOL = "protocol";
private static final String HOST = "host"; private static final String HOST = "host";
private static final String LOCAL_PORT = "localport"; private static final String LOCAL_PORT = "localport";
private static final String REMOTE_PORT = "remoteport"; private static final String REMOTE_PORT = "remoteport";
private final JingleNodesPlugin plugin; private final JingleNodesPlugin plugin;
public JingleNodesComponent(final JingleNodesPlugin plugin) { public JingleNodesComponent(final JingleNodesPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
} }
public String getName() { public String getName() {
return "JingleRelayNode"; return "JingleRelayNode";
} }
public String getDescription() { public String getDescription() {
return "Jingle Relay Service"; return "Jingle Relay Service";
} }
@Override @Override
protected String[] discoInfoFeatureNamespaces() { protected String[] discoInfoFeatureNamespaces() {
return new String[] { JingleChannelIQ.NAMESPACE }; return new String[]{JingleChannelIQ.NAMESPACE, JingleTrackerIQ.NAMESPACE};
} }
@Override @Override
protected String discoInfoIdentityCategoryType() { protected String discoInfoIdentityCategoryType() {
return "relay"; return "relay";
} }
@Override @Override
protected IQ handleIQGet(IQ iq) throws Exception { protected IQ handleIQGet(IQ iq) throws Exception {
final IQ reply = IQ.createResultIQ(iq); final IQ reply = IQ.createResultIQ(iq);
final Element element = iq.getChildElement(); final Element element = iq.getChildElement();
final String namespace = element.getNamespaceURI(); final String namespace = element.getNamespaceURI();
if (JingleChannelIQ.NAME.equals(element.getName()) && JingleChannelIQ.NAMESPACE.equals(namespace) if (JingleChannelIQ.NAME.equals(element.getName()) && JingleChannelIQ.NAMESPACE.equals(namespace)
&& UDP.equals(element.attributeValue(PROTOCOL))) { && UDP.equals(element.attributeValue(PROTOCOL))) {
final Element childElement = iq.getChildElement().createCopy(); final Element childElement = iq.getChildElement().createCopy();
final RelayChannel channel = plugin.createRelayChannel(); final RelayChannel channel = plugin.createRelayChannel();
if (channel != null) { if (channel != null) {
childElement.addAttribute(HOST, LocalIPResolver.getLocalIP()); childElement.addAttribute(HOST, LocalIPResolver.getLocalIP());
childElement.addAttribute(LOCAL_PORT, Integer.toString(channel.getPortA())); childElement.addAttribute(LOCAL_PORT, Integer.toString(channel.getPortA()));
childElement.addAttribute(REMOTE_PORT, Integer.toString(channel.getPortB())); childElement.addAttribute(REMOTE_PORT, Integer.toString(channel.getPortB()));
reply.setChildElement(childElement); reply.setChildElement(childElement);
Log.debug("Created relay channel {}:{}, {}:{}, {}:{}", new Object[] { HOST, Log.debug("Created relay channel {}:{}, {}:{}, {}:{}", new Object[]{HOST,
LocalIPResolver.getLocalIP(), LOCAL_PORT, Integer.toString(channel.getPortA()), REMOTE_PORT, LocalIPResolver.getLocalIP(), LOCAL_PORT, Integer.toString(channel.getPortA()), REMOTE_PORT,
Integer.toString(channel.getPortB()) }); Integer.toString(channel.getPortB())});
} else { } else {
reply.setError(PacketError.Condition.internal_server_error); reply.setError(PacketError.Condition.internal_server_error);
} }
return reply; return reply;
} } else if (JingleTrackerIQ.NAME.equals(element.getName()) && JingleTrackerIQ.NAMESPACE.equals(namespace)) {
return null; // feature not implemented. final List<TrackerEntry> entries = new ArrayList<TrackerEntry>();
} entries.add(new TrackerEntry(TrackerEntry.Type.relay, TrackerEntry.Policy._roster, plugin.getServiceName() + "." + getDomain(), UDP));
@Override final String elements = getChildElementXML(entries);
public String getDomain() {
return XMPPServer.getInstance().getServerInfo().getXMPPDomain(); final Element e = DocumentHelper.parseText(elements).getRootElement();
}
reply.setChildElement(e);
return reply;
}
return null; // feature not implemented.
}
public String getChildElementXML(final List<TrackerEntry> entries) {
final StringBuilder str = new StringBuilder();
str.append("<").append(JingleTrackerIQ.NAME).append(" xmlns='").append(JingleTrackerIQ.NAMESPACE).append("'>");
for (final TrackerEntry entry : entries) {
str.append("<").append(entry.getType().toString());
str.append(" policy='").append(entry.getPolicy().toString()).append("'");
str.append(" address='").append(entry.getJid()).append("'");
str.append(" protocol='").append(entry.getProtocol()).append("'");
if (entry.isVerified()) {
str.append(" verified='").append(entry.isVerified()).append("'");
}
str.append("/>");
}
str.append("</").append(JingleTrackerIQ.NAME).append(">");
return str.toString();
}
@Override
public String getDomain() {
return XMPPServer.getInstance().getServerInfo().getXMPPDomain();
}
} }
...@@ -47,7 +47,7 @@ public class JingleNodesPlugin implements Plugin { ...@@ -47,7 +47,7 @@ public class JingleNodesPlugin implements Plugin {
private final String serviceName = "relay"; private final String serviceName = "relay";
public void initializePlugin(PluginManager manager, File pluginDirectory) { public void initializePlugin(PluginManager manager, File pluginDirectory) {
componentManager = ComponentManagerFactory.getComponentManager(); componentManager = ComponentManagerFactory.getComponentManager();
JingleNodesComponent component = new JingleNodesComponent(this); JingleNodesComponent component = new JingleNodesComponent(this);
try { try {
...@@ -102,6 +102,10 @@ public class JingleNodesPlugin implements Plugin { ...@@ -102,6 +102,10 @@ public class JingleNodesPlugin implements Plugin {
c.close(); c.close();
} }
public String getServiceName() {
return serviceName;
}
public void destroyPlugin() { public void destroyPlugin() {
try { try {
componentManager.removeComponent(serviceName); componentManager.removeComponent(serviceName);
......
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