rendered paste bodypackage org.codehaus.plexus.discovery.mdns;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.log4j.Logger;
import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.discovery.DiscoverableResource;
import org.codehaus.plexus.discovery.ResourceDiscoverer;
import org.codehaus.plexus.discovery.ResourcePublisher;
import org.codehaus.plexus.util.StringUtils;
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
public class MDNSResourceDiscovererTestEx extends PlexusTestCase {
private class BackThread extends Thread {
private final Set resourceSet;
private final Set foundResourceSet;
final ResourceDiscoverer objResourceDiscoverer = resourceDiscoverer;
private AtomicBoolean doneFlag;
private BackThread(Set resourceSet, Set foundResourceSet,
AtomicBoolean doneFlag) {
this.resourceSet = resourceSet;
this.foundResourceSet = foundResourceSet;
this.doneFlag = doneFlag;
}
public void run() {
while (!doneFlag.get()) {
int resourceCount = 0;
Iterator itResources = objResourceDiscoverer.findResources();
while (itResources.hasNext()) {
String name = ((DiscoverableResource) itResources.next())
.getName();
synchronized (this) {
if (!foundResourceSet.contains(name)) {
assertTrue(
"resourceSet should contain name (name=\""
+ name + "\")", resourceSet
.contains(name));
resourceSet.remove(name);
if (LOGGER.isInfoEnabled())
LOGGER.info("consuming(name=\"" + name + "\")");
foundResourceSet.add(name);
resourceCount++;
}
}
}
Thread.yield();
}
}
}
/**
* Logger
*/
private static final Logger LOGGER = Logger
.getLogger(MDNSResourceDiscovererTestEx.class);
/**
* Resource Publisher
*/
private ResourcePublisher resourcePublisher;
/**
* Resource Discoverer
*/
private ResourceDiscoverer resourceDiscoverer;
/**
* Overrides customizeContext, adding the found interface address to the
* context, in order to get them bound
*/
protected void customizeContext(Context context) throws Exception {
InetAddress[] ifAddresses = null;
Map addrMap = new TreeMap();
addrMap.put(Inet4Address.class.getName(), new ArrayList());
addrMap.put(Inet6Address.class.getName(), new ArrayList());
loop: for (Enumeration enmInterfaces = NetworkInterface
.getNetworkInterfaces(); enmInterfaces.hasMoreElements();) {
NetworkInterface curIf = ((NetworkInterface) enmInterfaces
.nextElement());
for (Enumeration inetAddresses = curIf.getInetAddresses(); inetAddresses
.hasMoreElements();) {
InetAddress ifAddress = (InetAddress) inetAddresses
.nextElement();
/**
* Does this interface address suit? If don't, skip the loop
*/
if (!(ifAddress.isLinkLocalAddress() || ifAddress
.isSiteLocalAddress())
|| ifAddress.isLoopbackAddress())
continue;
/**
* Retrieves all the related ip address lists for this
* InetAddress class then loop across them
*/
List ifAddrList = ((List) addrMap.get(ifAddress.getClass()
.getName()));
for (Iterator iterNetIf = ifAddrList.iterator(); iterNetIf
.hasNext();) {
/**
* Retrieve the previous added address
*
* Tests if their MSBs (1 byte, Inet4Address, 2 bytes
* Inet6Address) match. Skip if don't. Otherwise, assign to
* interfaces and stop looping
*/
InetAddress prevIfAddress = (InetAddress) iterNetIf.next();
{
boolean shouldSkip = (ifAddress.getAddress()[0] != prevIfAddress
.getAddress()[0]);
if (ifAddress instanceof Inet6Address)
shouldSkip = (ifAddress.getAddress()[1] != prevIfAddress
.getAddress()[1]);
if (shouldSkip)
continue;
}
ifAddresses = new InetAddress[] { prevIfAddress, ifAddress };
break loop;
}
/**
* Add this ifAddress to the interface address list for this
* address class
*/
ifAddrList.add(ifAddress);
}
}
/**
* Ultimate Sanity Check
*/
assertNotNull(ifAddresses);
assertNotSame(ifAddresses[0], ifAddresses[1]);
context.put("interface.a", ifAddresses[0].getHostAddress());
context.put("interface.b", ifAddresses[1].getHostAddress());
}
protected void setUp() throws Exception {
super.setUp();
this.resourcePublisher = (ResourcePublisher) lookup(ResourcePublisher.ROLE);
this.resourceDiscoverer = (ResourceDiscoverer) lookup(ResourceDiscoverer.ROLE);
}
/**
* Concurrent publishing/consumption of resources
*
* @throws Exception
*/
public void testMultipleResourceExchange() throws Exception {
final Set resourceSet = Collections.synchronizedSet(new TreeSet());
final Set foundResourceSet = new TreeSet();
AtomicBoolean doneFlag = new AtomicBoolean(false);
Thread backCollector = new BackThread(resourceSet, foundResourceSet,
doneFlag);
backCollector.start();
int resourceCount = 0;
Random rng = new Random(0);
for (int i = 0; i < 16; i++) {
DiscoverableResource discoverableResource = new DiscoverableResource();
discoverableResource.setId("test-server-" + i);
discoverableResource.setName("Test Server "
+ i
+ " ["
+ StringUtils.leftPad(Integer.toHexString(rng.nextInt())
.toUpperCase(), 8, "0") + "]");
discoverableResource.setUrl(new URL("http://localhost:" + i
+ "/path?a=b&c+d=e&f=Hello%2C%20World%21&g&h="));
discoverableResource.setType("_http.tcp.local.");
synchronized (backCollector) {
this.resourcePublisher.registerResource(discoverableResource);
if (LOGGER.isInfoEnabled())
LOGGER.info("producing(name=\""
+ discoverableResource.getName() + "\")");
resourceSet.add(discoverableResource.getName());
}
Thread.yield();
assertTrue("BackCollector should be running", backCollector
.isAlive());
resourceCount++;
}
{
long timeouts = 500L * resourceCount + System.currentTimeMillis();
do {
if (foundResourceSet.size() == resourceCount) {
doneFlag.set(true);
break;
} else {
Thread.yield();
}
} while (System.currentTimeMillis() < timeouts);
}
assertTrue("resourceSet should be empty", resourceSet.isEmpty());
assertFalse("foundResourceSet should not be empty", foundResourceSet
.isEmpty());
assertEquals("resourceCount should equals foundResourceSet size",
Integer.valueOf(foundResourceSet.size()), Integer
.valueOf(resourceCount));
/**
* Reset to defaults. Restart
*/
resourceSet.addAll(foundResourceSet);
foundResourceSet.clear();
this.container.release(this.resourceDiscoverer);
doneFlag.set(false);
this.resourceDiscoverer = (ResourceDiscoverer) lookup(ResourceDiscoverer.ROLE);
backCollector = new BackThread(resourceSet, foundResourceSet, doneFlag);
backCollector.start();
{
long timeouts = 5000L * resourceCount + System.currentTimeMillis();
do {
if (foundResourceSet.size() == resourceCount) {
doneFlag.set(true);
break;
} else {
Thread.yield();
}
Thread.sleep(500);
} while (System.currentTimeMillis() < timeouts);
}
assertFalse("backCollector should not be running", backCollector.isAlive());
assertTrue("resourceSet should be empty", resourceSet.isEmpty());
assertFalse("foundResourceSet should not be empty", foundResourceSet
.isEmpty());
assertEquals("resourceCount should equals foundResourceSet size",
Integer.valueOf(foundResourceSet.size()), Integer
.valueOf(resourceCount));
}
}