package org.jboss.mx.remote.discovery.multicast;
import org.jboss.mx.remote.JMXRemotingObjectName;
import org.jboss.mx.remote.JMXUtil;
import org.jboss.mx.remote.connector.ConnectorFactory;
import org.jboss.mx.remote.connector.ConnectorMBean;
import org.jboss.mx.remote.connector.socket.SocketConnector;
import org.jboss.mx.remote.discovery.AbstractDetector;
import org.jboss.mx.remote.discovery.DetectionNotification;
import org.jboss.mx.remote.server.CascadingAgent;
import org.jboss.mx.util.SerializationHelper;
import org.jboss.mx.util.MBeanTyper;
import javax.management.*;
import java.net.*;
import java.util.*;
import java.io.IOException;
/**
* MulticastDetector is an implementation of MulticastDetectorMBean
* that uses multicast for detection
*
* @author <a href="mailto:telrod@e2technologies.net">Tom Elrod</a>
* @author <a href="mailto:jhaynie@vocalocity.net">Jeff Haynie</a>
*/
public class MulticastDetector extends AbstractDetector implements MulticastDetectorMBean
{
private static final String TYPE = "multicast";
public static final int DEFAULT_PORT = 2409;
public static final String DEFAULT_IP = "224.0.0.1";
private MulticastSocket socket;
private int port = DEFAULT_PORT;
private InetAddress group;
public MulticastDetector()
{
super();
this.type = TYPE;
setIP(DEFAULT_IP);
}
/**
* set the multicast port
*
* @param port
*/
public void setPort(int port)
{
int old = this.port;
this.port = port;
fireAttributeChange("detector.port.changed", "Port", String.class, new Integer(old), new Integer(this.port));
}
public MBeanNotificationInfo[] getNotificationInfo()
{
MBeanNotificationInfo sn[] = super.getNotificationInfo();
MBeanNotificationInfo ni[] = new MBeanNotificationInfo[1];
ni[0] = new MBeanNotificationInfo(new String[]{"detector.port.changed", "detector.ip.changed"}, AttributeChangeNotification.class.getName(), "attribute changed notification");
if (sn == null || sn.length == 0)
{
return ni;
}
else
{
// append super classes notification info to ours
MBeanNotificationInfo n[] = new MBeanNotificationInfo[1 + sn.length];
System.arraycopy(sn, 0, n, 0, sn.length);
n[sn.length] = ni[0];
return ni;
}
}
/**
* get the multicast port
*
* @return port number
*/
public int getPort()
{
return port;
}
/**
* set the IP address of the multicast group
*
* @param ip
*/
public void setIP(String ip)
{
String old = (this.group == null ? null : this.group.getHostAddress());
try
{
this.group = InetAddress.getByName(ip);
}
catch (Exception ex)
{
throw new IllegalArgumentException(ex.getMessage());
}
fireAttributeChange("detector.ip.changed", "IP", String.class, old, ip);
}
/**
* get the multicast group IP address
*
* @return ip address
*/
public String getIP()
{
return group.getHostAddress();
}
/**
* stop multicasting
*
* @throws Exception
*/
protected void stopService() throws Exception
{
super.stopService();
socket.leaveGroup(group);
socket.close();
socket = null;
}
/**
* start multicasting
*
* @throws Exception
*/
protected void startService() throws Exception
{
super.startService();
socket = new MulticastSocket(port);
socket.joinGroup(group);
}
/**
* multicast publish the detection msg
*
* @param msg
* @throws Exception
*/
protected void publish (DetectionNotification msg)
throws Exception
{
if (msg!=null && socket!=null)
{
byte buf[] = SerializationHelper.serialize(msg);
DatagramPacket p = new DatagramPacket(buf, buf.length, group, port);
//log.debug("packet->"+p);
socket.send(p);
}
}
/**
* receive multicast detection
*
* @return detection notification
* @throws Exception
*/
protected DetectionNotification receiveDetection ()
throws Exception
{
if (socket!=null)
{
byte buf[] = new byte[4000];
DatagramPacket p = new DatagramPacket(buf, 0, buf.length);
try
{
socket.receive(p);
}
catch (SocketException e)
{
if (e.getMessage().equals("socket closed"))
{
return null;
}
}
DetectionNotification msg = (DetectionNotification) SerializationHelper.deserialize(buf);
return msg;
}
return null;
}
}