提交 e701da7c 编写于 作者: K kohsuke

Added a discovery support by listening to UDP.

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@15122 71c3de6d-444a-0410-be80-ed276b4c234a
上级 8cc9cea3
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson;
import hudson.model.Hudson;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.DatagramChannel;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Monitors a UDP broadcast and respond with the location of the Hudson service.
*
* <p>
* Useful for auto-discovery of Hudson in the network.
*
* @author Kohsuke Kawaguchi
*/
public class UDPBroadcastThread extends Thread {
private final Hudson hudson;
public UDPBroadcastThread(Hudson hudson) {
super("Hudson UDP "+PORT+" monitoring thread");
this.hudson = hudson;
}
@Override
public void run() {
try {
DatagramChannel ch = DatagramChannel.open();
try {
ch.socket().bind(new InetSocketAddress(PORT));
ByteBuffer b = ByteBuffer.allocate(2048);
while(true) {
// the only thing that matters here is who sent it, not what was sent.
SocketAddress sender = ch.receive(b);
// prepare a response
TcpSlaveAgentListener tal = hudson.getTcpSlaveAgentListener();
StringBuilder buf = new StringBuilder("<hudson>");
tag(buf,"version",Hudson.VERSION);
tag(buf,"url",hudson.getRootUrl());
tag(buf,"slave-port",tal==null?null:tal.getPort());
buf.append("</hudson>");
b.clear();
b.put(buf.toString().getBytes("UTF-8"));
b.flip();
ch.send(b, sender);
}
} finally {
ch.close();
}
} catch (ClosedByInterruptException e) {
// shut down
} catch (IOException e) {
LOGGER.log(Level.WARNING, "UDP handling problem",e);
}
}
private void tag(StringBuilder buf, String tag, Object value) {
if(value==null) return;
buf.append('<').append(tag).append('>').append(value).append("</").append(tag).append('>');
}
public void shutdown() {
interrupt();
}
public static final int PORT = Integer.getInteger("hudson.udp",33848);
private static final Logger LOGGER = Logger.getLogger(UDPBroadcastThread.class.getName());
}
......@@ -39,6 +39,7 @@ import hudson.Util;
import static hudson.Util.fixEmpty;
import hudson.WebAppMain;
import hudson.XmlFile;
import hudson.UDPBroadcastThread;
import hudson.logging.LogRecorderManager;
import hudson.lifecycle.WindowsInstallerLink;
import hudson.lifecycle.Lifecycle;
......@@ -330,6 +331,8 @@ public final class Hudson extends AbstractModelObject implements ItemGroup<TopLe
public transient volatile TcpSlaveAgentListener tcpSlaveAgentListener;
private transient UDPBroadcastThread udpBroadcastThread;
/**
* List of registered {@link JobListener}s.
*/
......@@ -497,6 +500,9 @@ public final class Hudson extends AbstractModelObject implements ItemGroup<TopLe
else
tcpSlaveAgentListener = null;
udpBroadcastThread = new UDPBroadcastThread(this);
udpBroadcastThread.start();
updateComputerList();
getQueue().load();
......@@ -1804,6 +1810,7 @@ public final class Hudson extends AbstractModelObject implements ItemGroup<TopLe
c.kill();
pending.add(c.disconnect());
}
udpBroadcastThread.shutdown();
ExternalJob.reloadThread.interrupt();
Trigger.timer.cancel();
// TODO: how to wait for the completion of the last job?
......
package hudson;
import org.jvnet.hudson.test.HudsonTestCase;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParserFactory;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.io.StringReader;
/**
* @author Kohsuke Kawaguchi
*/
public class UDPBroadcastThreadTest extends HudsonTestCase {
public void test1() throws Exception {
DatagramSocket s = new DatagramSocket();
DatagramPacket p = new DatagramPacket(new byte[1024],1024);
p.setAddress(InetAddress.getLocalHost());
p.setPort(UDPBroadcastThread.PORT);
s.send(p);
s.setSoTimeout(5000); // to prevent test hang
s.receive(p);
String xml = new String(p.getData(), 0, p.getLength(), "UTF-8");
System.out.println(xml);
// make sure at least this XML parses
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.newSAXParser().parse(new InputSource(new StringReader(xml)),new DefaultHandler());
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册