Author: pferraro
Date: 2008-10-30 00:14:36 -0400 (Thu, 30 Oct 2008)
New Revision: 2029
Added:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/MulticastSocketFactory.java
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/MulticastSocketFactoryImpl.java
trunk/mod_cluster/src/test/java/org/jboss/modcluster/advertise/MulticastSocketFactoryImplTestCase.java
Removed:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/OSResolver.java
Modified:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerFactoryImpl.java
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerImpl.java
trunk/mod_cluster/src/test/java/org/jboss/modcluster/advertise/AdvertiseListenerImplTestCase.java
Log:
Isolated inline OSResolver usage in AdvertiseListenerImpl into a MulticastSocketFactory
Added:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/MulticastSocketFactory.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/MulticastSocketFactory.java
(rev 0)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/MulticastSocketFactory.java 2008-10-30
04:14:36 UTC (rev 2029)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.modcluster.advertise;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+
+/**
+ * Factory for creating multicast sockets.
+ *
+ * @author Paul Ferraro
+ */
+public interface MulticastSocketFactory
+{
+ MulticastSocket createMulticastSocket(InetAddress address, int port) throws
IOException;
+}
Modified:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerFactoryImpl.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerFactoryImpl.java 2008-10-29
23:07:15 UTC (rev 2028)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerFactoryImpl.java 2008-10-30
04:14:36 UTC (rev 2029)
@@ -32,13 +32,12 @@
*/
public class AdvertiseListenerFactoryImpl implements AdvertiseListenerFactory
{
-
/**
* @{inheritDoc}
* @see
org.jboss.modcluster.advertise.AdvertiseListenerFactory#createListener(org.jboss.modcluster.mcmp.MCMPHandler)
*/
public AdvertiseListener createListener(MCMPHandler handler, MCMPHandlerConfiguration
config)
{
- return new AdvertiseListenerImpl(handler, config);
+ return new AdvertiseListenerImpl(handler, config, new
MulticastSocketFactoryImpl());
}
}
Modified:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerImpl.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerImpl.java 2008-10-29
23:07:15 UTC (rev 2028)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerImpl.java 2008-10-30
04:14:36 UTC (rev 2029)
@@ -21,16 +21,12 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
*/
-
package org.jboss.modcluster.advertise.impl;
import java.io.IOException;
import java.net.DatagramPacket;
-import java.net.Inet4Address;
import java.net.InetAddress;
-import java.net.InetSocketAddress;
import java.net.MulticastSocket;
-import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -49,6 +45,7 @@
import org.jboss.logging.Logger;
import org.jboss.modcluster.Constants;
import org.jboss.modcluster.advertise.AdvertiseListener;
+import org.jboss.modcluster.advertise.MulticastSocketFactory;
import org.jboss.modcluster.config.MCMPHandlerConfiguration;
import org.jboss.modcluster.mcmp.MCMPHandler;
@@ -72,7 +69,8 @@
private int advertisePort = DEFAULT_PORT;
private InetAddress groupAddress = null;
- MulticastSocket ms;
+ private MulticastSocketFactory socketFactory;
+ MulticastSocket socket;
private boolean initialized = false;
volatile boolean listening = true;
@@ -87,8 +85,6 @@
final Map<String, AdvertisedServer> servers = new HashMap<String,
AdvertisedServer>();
final MCMPHandler commHandler;
- private final OSResolver osResolver;
-
private Thread workerThread;
/** The string manager for this package. */
@@ -112,30 +108,18 @@
}
md.update(b);
}
-
- /**
- * Create AdvertiseListener instance
- * @param eventHandler The event handler that will be used for
- * status and new server notifications.
- * @param config our configuration
- */
- public AdvertiseListenerImpl(MCMPHandler commHandler, MCMPHandlerConfiguration
config)
- {
- this(commHandler, config, new OSResolver());
- }
/**
- * Constructor meant for use by test cases; allows injection of a non-standard
OSResolver.
+ * Constructors a new AdvertiseListenerImpl
*
- * @param eventHandler The event handler that will be used for
- * status and new server notifications.
+ * @param eventHandler The event handler that will be used for status and new server
notifications.
* @param config our configuration
- * @param resolver the OSResolver
+ * @param socketFactory a multicast socket factory
*/
- public AdvertiseListenerImpl(MCMPHandler commHandler, MCMPHandlerConfiguration config,
OSResolver resolver)
+ public AdvertiseListenerImpl(MCMPHandler commHandler, MCMPHandlerConfiguration config,
MulticastSocketFactory socketFactory)
{
this.commHandler = commHandler;
- this.osResolver = resolver == null ? new OSResolver() : resolver;
+ this.socketFactory = socketFactory;
try
{
@@ -248,19 +232,10 @@
{
if (!this.initialized)
{
- // On Linux, we avoid cross-talk problem by binding the MulticastSocket
- // to the multicast address. See
https://jira.jboss.org/jira/browse/JGRP-777
- if(osResolver.isLinux())
- {
- this.ms = createMulticastSocket(this.groupAddress, this.advertisePort);
- }
- else
- {
- this.ms = new MulticastSocket(this.advertisePort);
- }
+ this.socket = this.socketFactory.createMulticastSocket(this.groupAddress,
this.advertisePort);
- this.ms.setTimeToLive(16);
- this.ms.joinGroup(this.groupAddress);
+ this.socket.setTimeToLive(16);
+ this.socket.joinGroup(this.groupAddress);
this.initialized = true;
}
@@ -273,9 +248,9 @@
try
{
// Restrict to localhost.
- this.ms.setTimeToLive(0);
+ this.socket.setTimeToLive(0);
DatagramPacket dp = new DatagramPacket(this.secure, this.secure.length,
this.groupAddress, this.advertisePort);
- this.ms.send(dp);
+ this.socket.send(dp);
}
catch (IOException e)
{
@@ -365,10 +340,10 @@
if (this.initialized)
{
- this.ms.leaveGroup(this.groupAddress);
- this.ms.close();
+ this.socket.leaveGroup(this.groupAddress);
+ this.socket.close();
this.initialized = false;
- this.ms = null;
+ this.socket = null;
}
}
@@ -421,42 +396,7 @@
return true;
}
-
-
-
- private MulticastSocket createMulticastSocket(InetAddress mcast_addr, int port) throws
IOException
- {
- if (mcast_addr != null && !mcast_addr.isMulticastAddress())
- {
- log.warn("mcast_addr (" + mcast_addr + ") is not a multicast
address, will be ignored");
- return new MulticastSocket(port);
- }
- SocketAddress saddr = new InetSocketAddress(mcast_addr, port);
- MulticastSocket retval = null;
-
- try
- {
- retval = new MulticastSocket(saddr);
- }
- catch (IOException ex)
- {
- StringBuilder sb = new StringBuilder();
- String type = mcast_addr != null ? mcast_addr instanceof Inet4Address ?
"IPv4" : "IPv6" : "n/a";
- sb.append("could not bind to " + mcast_addr + " (" + type +
" address)");
- sb.append("; make sure your mcast_addr is of the same type as the IP stack
(IPv4 or IPv6).");
- sb.append("\nWill ignore mcast_addr, but this may lead to cross talking
"
- + "(see
http://www.jboss.com/wiki/Edit.jsp?page=CrossTalking for
details). ");
- sb.append("\nException was: " + ex);
- log.warn(sb);
- }
- if (retval == null)
- {
- retval = new MulticastSocket(port);
- }
- return retval;
- }
-
// ------------------------------------ AdvertiseListenerWorker Inner Class
class AdvertiseListenerWorker implements Runnable
{
@@ -487,7 +427,7 @@
try
{
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
- AdvertiseListenerImpl.this.ms.receive(dp);
+ AdvertiseListenerImpl.this.socket.receive(dp);
if (!AdvertiseListenerImpl.this.running.get())
{
break;
Added:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/MulticastSocketFactoryImpl.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/MulticastSocketFactoryImpl.java
(rev 0)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/MulticastSocketFactoryImpl.java 2008-10-30
04:14:36 UTC (rev 2029)
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.modcluster.advertise.impl;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.MulticastSocket;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.jboss.logging.Logger;
+import org.jboss.modcluster.advertise.MulticastSocketFactory;
+
+/**
+ * On Linux, we attempt to avoid cross-talk problem by binding the MulticastSocket
+ * to the multicast address, if possible.
+ * See {@linkplain
https://jira.jboss.org/jira/browse/JGRP-777}
+ *
+ * @author Paul Ferraro
+ */
+public class MulticastSocketFactoryImpl implements MulticastSocketFactory
+{
+ final Logger log = Logger.getLogger(this.getClass());
+
+ private final boolean linux;
+
+ public MulticastSocketFactoryImpl()
+ {
+ String value = this.getSystemProperty("os.name");
+
+ this.linux = (value != null) &&
value.toLowerCase().startsWith("linux");
+ }
+
+ private String getSystemProperty(final String key)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ return System.getProperty(key);
+ }
+
+ PrivilegedAction<String> action = new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ try
+ {
+ return System.getProperty(key);
+ }
+ catch (SecurityException e)
+ {
+ MulticastSocketFactoryImpl.this.log.warn(e.getMessage(), e);
+
+ return null;
+ }
+ }
+ };
+
+ return AccessController.doPrivileged(action);
+ }
+
+ /**
+ * @{inheritDoc}
+ * @see
org.jboss.modcluster.advertise.MulticastSocketFactory#createMulticastSocket(java.net.InetAddress,
int)
+ */
+ public MulticastSocket createMulticastSocket(InetAddress address, int port) throws
IOException
+ {
+ if ((address == null) || !this.linux) return new MulticastSocket(port);
+
+ if (!address.isMulticastAddress())
+ {
+ this.log.warn(address + " is not a multicast address, will be
ignored");
+
+ return new MulticastSocket(port);
+ }
+
+ try
+ {
+ return new MulticastSocket(new InetSocketAddress(address, port));
+ }
+ catch (IOException e)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("could not bind to
").append(address.getHostAddress()).append(" (");
+ builder.append((address instanceof Inet4Address) ? "IPv4" :
"IPv6").append(" address)");
+ builder.append("; make sure your mcast_addr is of the same type as the IP
stack (IPv4 or IPv6).");
+ builder.append("\nWill ignore mcast_addr, but this may lead to cross
talking ");
+ builder.append("(see
http://www.jboss.org/community/docs/DOC-9469 for
details). ");
+
+ this.log.warn(builder.toString(), e);
+
+ return new MulticastSocket(port);
+ }
+ }
+}
Deleted:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/OSResolver.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/OSResolver.java 2008-10-29
23:07:15 UTC (rev 2028)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/OSResolver.java 2008-10-30
04:14:36 UTC (rev 2029)
@@ -1,81 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-
-package org.jboss.modcluster.advertise.impl;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * Provides information about the underlying operating system.
- * <p>
- * This class basically provides a hook to allow tests to pretend the Linux
- * OS is not Linux, for testing the JBNATIVE-68 fix. This default implementation
- * does not pretend Linux isn't Linux, but subclasses can.
- * </p>
- *
- * @author Brian Stansberry
- */
-public class OSResolver
-{
- /**
- * Is the underlying operation system Linux?
- *
- * @return
- */
- public boolean isLinux()
- {
- return checkForPresence("os.name", "linux");
- }
-
- private boolean checkForPresence(final String key, String value)
- {
- try
- {
- String tmp= null;
- if (System.getSecurityManager() == null)
- {
- tmp = System.getProperty(key);
- }
- else
- {
- // Use a different local var to limit scope of @SuppressWarnings
- @SuppressWarnings("unchecked")
- String prop = (String) AccessController.doPrivileged(new PrivilegedAction()
- {
- public Object run()
- {
- return System.getProperty(key);
- }
-
- });
- tmp = prop;
- }
-
- return tmp != null && tmp.trim().toLowerCase().startsWith(value);
- }
- catch (Throwable t)
- {
- return false;
- }
- }
-}
Modified:
trunk/mod_cluster/src/test/java/org/jboss/modcluster/advertise/AdvertiseListenerImplTestCase.java
===================================================================
---
trunk/mod_cluster/src/test/java/org/jboss/modcluster/advertise/AdvertiseListenerImplTestCase.java 2008-10-29
23:07:15 UTC (rev 2028)
+++
trunk/mod_cluster/src/test/java/org/jboss/modcluster/advertise/AdvertiseListenerImplTestCase.java 2008-10-30
04:14:36 UTC (rev 2029)
@@ -31,9 +31,11 @@
import java.util.Date;
import java.util.Locale;
+import junit.framework.Assert;
+
+import org.easymock.Capture;
import org.easymock.EasyMock;
import org.jboss.modcluster.advertise.impl.AdvertiseListenerImpl;
-import org.jboss.modcluster.advertise.impl.OSResolver;
import org.jboss.modcluster.config.MCMPHandlerConfiguration;
import org.jboss.modcluster.mcmp.MCMPHandler;
import org.junit.After;
@@ -44,6 +46,7 @@
*
* @author Brian Stansberry
*/
+@SuppressWarnings("boxing")
public class AdvertiseListenerImplTestCase
{
private static final String ADVERTISE_GROUP = "224.0.1.106";
@@ -55,6 +58,7 @@
private MCMPHandler mcmpHandler = EasyMock.createStrictMock(MCMPHandler.class);
private MCMPHandlerConfiguration mcmpConfig =
EasyMock.createMock(MCMPHandlerConfiguration.class);
+ private MulticastSocketFactory socketFactory =
EasyMock.createMock(MulticastSocketFactory.class);
private MulticastSocket mcastSocket;
private AdvertiseListenerImpl testee;
@@ -62,47 +66,44 @@
@After
public void tearDown()
{
- if (mcastSocket != null)
- mcastSocket.close();
- if (testee != null)
- testee.stop();
+ if (this.mcastSocket != null)
+ {
+ this.mcastSocket.close();
+ }
+
+ if (this.testee != null)
+ {
+ this.testee.stop();
+ }
}
@Test
public void testBasicOperation() throws IOException
{
- basicOperationTest(false);
- }
-
- @Test
- public void testBasicOperationWithLinux() throws IOException
- {
- basicOperationTest(true);
- }
-
- private void basicOperationTest(boolean linux) throws IOException
- {
- ConfigurableOSResolver resolver = new ConfigurableOSResolver(linux);
-
EasyMock.expect(this.mcmpConfig.getAdvertiseGroupAddress()).andReturn(ADVERTISE_GROUP);
- EasyMock.expect(this.mcmpConfig.getAdvertisePort()).andReturn(23365);
+ EasyMock.expect(this.mcmpConfig.getAdvertisePort()).andReturn(ADVERTISE_PORT);
EasyMock.expect(this.mcmpConfig.getAdvertiseSecurityKey()).andReturn(null);
EasyMock.replay(this.mcmpConfig);
- this.testee = new AdvertiseListenerImpl(this.mcmpHandler, this.mcmpConfig,
resolver);
+ this.testee = new AdvertiseListenerImpl(this.mcmpHandler, this.mcmpConfig,
this.socketFactory);
+
+ EasyMock.verify(this.mcmpConfig);
+ EasyMock.reset(this.mcmpConfig);
+
+ Capture<InetAddress> capturedAddress = new Capture<InetAddress>();
+
+
EasyMock.expect(this.socketFactory.createMulticastSocket(EasyMock.capture(capturedAddress),
EasyMock.eq(ADVERTISE_PORT))).andReturn(new MulticastSocket(ADVERTISE_PORT));
+
+ EasyMock.replay(this.socketFactory);
+
this.testee.start();
+
+ EasyMock.verify(this.socketFactory);
- try
- {
- Thread.sleep(20);
- }
- catch (InterruptedException e)
- {
- Thread.interrupted();
- }
+ Assert.assertEquals(ADVERTISE_GROUP, capturedAddress.getValue().getHostAddress());
- EasyMock.verify(this.mcmpConfig);
+ EasyMock.reset(this.socketFactory);
this.mcastSocket = new MulticastSocket(ADVERTISE_PORT);
InetAddress mcastGroup = InetAddress.getByName(ADVERTISE_GROUP);
@@ -124,47 +125,22 @@
byte[] buf = data.toString().getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, mcastGroup,
ADVERTISE_PORT);
- this.mcmpHandler.addProxy(SERVER_ADDRESS);
+ this.mcmpHandler.addProxy(SERVER_ADDRESS);
+
EasyMock.replay(this.mcmpHandler);
this.mcastSocket.send(packet);
try
{
- Thread.sleep(20);
+ // Give time for advertise worker to process message
+ Thread.sleep(100);
}
catch (InterruptedException e)
{
- Thread.interrupted();
+ Thread.currentThread().interrupt();
}
EasyMock.verify(this.mcmpHandler);
}
-
- private static class ConfigurableOSResolver extends OSResolver
- {
- private boolean allowLinux;
-
- public ConfigurableOSResolver(boolean allowLinux)
- {
- this.allowLinux = allowLinux;
- }
-
- public boolean isAllowLinux()
- {
- return allowLinux;
- }
-
- public void setAllowLinux(boolean allowLinux)
- {
- this.allowLinux = allowLinux;
- }
-
- @Override
- public boolean isLinux()
- {
- return allowLinux && super.isLinux();
- }
-
- }
}
Added:
trunk/mod_cluster/src/test/java/org/jboss/modcluster/advertise/MulticastSocketFactoryImplTestCase.java
===================================================================
---
trunk/mod_cluster/src/test/java/org/jboss/modcluster/advertise/MulticastSocketFactoryImplTestCase.java
(rev 0)
+++
trunk/mod_cluster/src/test/java/org/jboss/modcluster/advertise/MulticastSocketFactoryImplTestCase.java 2008-10-30
04:14:36 UTC (rev 2029)
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.jboss.modcluster.advertise;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.util.Arrays;
+
+import org.jboss.modcluster.advertise.impl.AdvertiseListenerImpl;
+import org.jboss.modcluster.advertise.impl.MulticastSocketFactoryImpl;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests of {@link AdvertiseListenerImpl}.
+ *
+ * @author Brian Stansberry
+ */
+public class MulticastSocketFactoryImplTestCase
+{
+ private static final String ADVERTISE_GROUP = "224.0.1.106";
+ private static final int ADVERTISE_PORT = 23365;
+
+ @Test
+ public void createMulticastSocketNotLinux() throws IOException
+ {
+ String os = System.getProperty("os.name");
+
+ boolean linux = os.trim().toLowerCase().startsWith("linux");
+
+ try
+ {
+ if (linux)
+ {
+ System.setProperty("os.name", "OtherOS");
+ }
+
+ this.createMulticastSocketAsLinux();
+ }
+ finally
+ {
+ if (linux)
+ {
+ System.setProperty("os.name", os);
+ }
+ }
+ }
+
+ @Test
+ public void createMulticastSocketAsLinux() throws IOException
+ {
+ InetAddress groupAddress = InetAddress.getByName(ADVERTISE_GROUP);
+
+ MulticastSocketFactory socketFactory = new MulticastSocketFactoryImpl();
+ MulticastSocket factorySocket = socketFactory.createMulticastSocket(groupAddress,
ADVERTISE_PORT);
+
+ try
+ {
+ factorySocket.joinGroup(groupAddress);
+
+ testMulticastSocket(factorySocket, groupAddress);
+
+ factorySocket.leaveGroup(groupAddress);
+ }
+ finally
+ {
+ factorySocket.close();
+ }
+ }
+
+ public void testMulticastSocket(MulticastSocket factorySocket, InetAddress
groupAddress) throws IOException
+ {
+ MulticastSocket socket = new MulticastSocket(ADVERTISE_PORT);
+
+ try
+ {
+ socket.joinGroup(groupAddress);
+
+ String data = "1234567890";
+
+ byte[] buffer = data.getBytes();
+ DatagramPacket packet = new DatagramPacket(buffer, buffer.length, groupAddress,
ADVERTISE_PORT);
+
+ socket.send(packet);
+
+ try
+ {
+ Thread.sleep(20);
+ }
+ catch (InterruptedException e)
+ {
+ Thread.interrupted();
+ }
+
+ Arrays.fill(buffer, (byte) 0);
+
+ packet = new DatagramPacket(buffer, buffer.length);
+
+ factorySocket.receive(packet);
+
+ Assert.assertArrayEquals(buffer, data.getBytes());
+
+ socket.leaveGroup(groupAddress);
+ }
+ finally
+ {
+ socket.close();
+ }
+ }
+}