Author: andygumbrecht
Date: Wed Aug 1 13:05:27 2012
New Revision: 1367974
URL: http://svn.apache.org/viewvc?rev=1367974&view=rev
Log:
Improve MultiPulse sort order, filtering (Teredo address) and also include
host/DNS name
Flush spec in ProtocolMetaData - Resolved a TCP tunneling issue on an old box
(Read was blocking until timeout).
Modified:
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/MulticastPulseClient.java
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ProtocolMetaData.java
openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/MulticastPulseAgent.java
openejb/trunk/openejb/server/openejb-multicast/src/test/java/org/apache/openejb/server/discovery/MulticastPulseAgentTest.java
Modified:
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/MulticastPulseClient.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/MulticastPulseClient.java?rev=1367974&r1=1367973&r2=1367974&view=diff
==============================================================================
---
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/MulticastPulseClient.java
(original)
+++
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/MulticastPulseClient.java
Wed Aug 1 13:05:27 2012
@@ -1,9 +1,32 @@
package org.apache.openejb.client;
+import sun.net.util.IPAddressUtil;
+
import java.io.IOException;
-import java.net.*;
+import java.net.DatagramPacket;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.MulticastSocket;
+import java.net.NetworkInterface;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
import java.nio.charset.Charset;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.TreeSet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -146,32 +169,47 @@ public class MulticastPulseClient extend
final Set<URI> set = new TreeSet<URI>(new Comparator<URI>() {
@Override
- public int compare(URI u1, URI u2) {
+ public int compare(URI uri1, URI uri2) {
//Ignore server hostname
- final String serverHost = u1.getScheme();
- u1 = URI.create(u1.getSchemeSpecificPart());
- u2 = URI.create(u2.getSchemeSpecificPart());
+ URI u1 = URI.create(uri1.getSchemeSpecificPart());
+ URI u2 = URI.create(uri2.getSchemeSpecificPart());
//Ignore scheme (ejb,ejbs,etc.)
u1 = URI.create(u1.getSchemeSpecificPart());
u2 = URI.create(u2.getSchemeSpecificPart());
- if (u1.getHost().equals(serverHost)) {
- //If the service host is the same as the server host
- //then keep it at the top of the list
- return -1;
- }
-
//Compare URI hosts
- int i = u1.getHost().compareTo(u2.getHost());
-
+ int i = compare(u1.getHost(), u2.getHost());
if (i == 0) {
- i = u1.compareTo(u2);
+ i = uri1.compareTo(uri2);
}
return i;
}
+
+ private int compare(final String h1, final String h2) {
+
+ //Sort by hostname, IPv4, IPv6
+
+ try {
+ if (IPAddressUtil.isIPv4LiteralAddress(h1)) {
+ if (IPAddressUtil.isIPv6LiteralAddress(h2.replace("[",
"").replace("]", ""))) {
+ return -1;
+ }
+ } else if
(IPAddressUtil.isIPv6LiteralAddress(h1.replace("[", "").replace("]", ""))) {
+ if (IPAddressUtil.isIPv4LiteralAddress(h2)) {
+ return 1;
+ }
+ } else if (0 != h1.compareTo(h2)) {
+ return -1;
+ }
+ } catch (Throwable e) {
+ //Ignore
+ }
+
+ return h1.compareTo(h2);
+ }
});
final ReentrantLock setLock = new ReentrantLock();
@@ -256,11 +294,15 @@ public class MulticastPulseClient extend
try {
if (svc.contains("0.0.0.0")) {
for (final String h :
hosts) {
-
set.add(URI.create(svc.replace("0.0.0.0", ipFormat(h))));
+ if (!h.replace("[",
"").startsWith("2001:0:")) { //Filter Teredo
+
set.add(URI.create(svc.replace("0.0.0.0", ipFormat(h))));
+ }
}
} else if
(svc.contains("[::]")) {
for (final String h :
hosts) {
-
set.add(URI.create(svc.replace("[::]", ipFormat(h))));
+ if (!h.replace("[",
"").startsWith("2001:0:")) { //Filter Teredo
+
set.add(URI.create(svc.replace("[::]", ipFormat(h))));
+ }
}
} else {
//Just add as is
@@ -343,7 +385,7 @@ public class MulticastPulseClient extend
setLock.lock();
try {
- return new HashSet<URI>(set);
+ return new TreeSet<URI>(set);
} finally {
setLock.unlock();
}
@@ -380,7 +422,7 @@ public class MulticastPulseClient extend
private static String ipFormat(final String h) throws UnknownHostException
{
- final InetAddress ia = Inet6Address.getByName(h);
+ final InetAddress ia = InetAddress.getByName(h);
if (ia instanceof Inet6Address) {
return "[" + ia.getHostAddress() + "]";
} else {
Modified:
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ProtocolMetaData.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ProtocolMetaData.java?rev=1367974&r1=1367973&r2=1367974&view=diff
==============================================================================
---
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ProtocolMetaData.java
(original)
+++
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/ProtocolMetaData.java
Wed Aug 1 13:05:27 2012
@@ -33,6 +33,7 @@ import java.io.EOFException;
*
* @version $Revision$ $Date$
*/
+@SuppressWarnings("UnusedDeclaration")
public class ProtocolMetaData {
private static final String OEJB = "OEJP";
@@ -43,14 +44,14 @@ public class ProtocolMetaData {
public ProtocolMetaData() {
}
- public ProtocolMetaData(String version) {
+ public ProtocolMetaData(final String version) {
init(OEJB+"/"+version);
}
- private void init(String spec) {
+ private void init(final String spec) {
assert spec.matches("^OEJP/[0-9]\\.[0-9]$"): "Protocol version spec
must follow format [ \"OEJB\" \"/\" 1*DIGIT \".\" 1*DIGIT ]";
- char[] chars = new char[8];
+ final char[] chars = new char[8];
spec.getChars(0, chars.length, chars, 0);
this.id = new String(chars, 0, 4);
@@ -78,12 +79,13 @@ public class ProtocolMetaData {
return id+"/"+major+"."+minor;
}
- public void writeExternal(OutputStream out) throws IOException {
+ public void writeExternal(final OutputStream out) throws IOException {
out.write(getSpec().getBytes("UTF-8"));
+ out.flush();
}
- public void readExternal(InputStream in) throws IOException {
- byte[] spec = new byte[8];
+ public void readExternal(final InputStream in) throws IOException {
+ final byte[] spec = new byte[8];
for (int i = 0; i < spec.length; i++) {
spec[i] = (byte) in.read();
if (spec[i] == -1){
Modified:
openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/MulticastPulseAgent.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/MulticastPulseAgent.java?rev=1367974&r1=1367973&r2=1367974&view=diff
==============================================================================
---
openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/MulticastPulseAgent.java
(original)
+++
openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/MulticastPulseAgent.java
Wed Aug 1 13:05:27 2012
@@ -9,17 +9,29 @@ import org.apache.openejb.server.Service
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.OptionsLog;
+import sun.net.util.IPAddressUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.net.*;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.MulticastSocket;
+import java.net.NetworkInterface;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
+import java.util.TreeSet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -466,7 +478,32 @@ public class MulticastPulseAgent impleme
private static String getHosts() {
- final Set<String> hosts = new HashSet<String>();
+ final Set<String> hosts = new TreeSet<String>(new Comparator<String>()
{
+
+ @Override
+ public int compare(final String h1, final String h2) {
+
+ //Sort by hostname, IPv4, IPv6
+
+ try {
+ if (IPAddressUtil.isIPv4LiteralAddress(h1)) {
+ if (IPAddressUtil.isIPv6LiteralAddress(h2.replace("[",
"").replace("]", ""))) {
+ return -1;
+ }
+ } else if
(IPAddressUtil.isIPv6LiteralAddress(h1.replace("[", "").replace("]", ""))) {
+ if (IPAddressUtil.isIPv4LiteralAddress(h2)) {
+ return 1;
+ }
+ } else if (0 != h1.compareTo(h2)) {
+ return -1;
+ }
+ } catch (Throwable e) {
+ //Ignore
+ }
+
+ return h1.compareTo(h2);
+ }
+ });
try {
final InetAddress localhost = InetAddress.getLocalHost();
@@ -479,7 +516,11 @@ public class MulticastPulseAgent impleme
continue;
}
- hosts.add(ip.getHostAddress());
+ final String ha = ip.getHostAddress();
+ if (!ha.replace("[", "").startsWith("2001:0:")) { //Filter
Teredo
+ hosts.add(ha);
+ hosts.add(ip.getCanonicalHostName());
+ }
}
} catch (UnknownHostException e) {
log.warning("Failed to list machine hosts", e);
Modified:
openejb/trunk/openejb/server/openejb-multicast/src/test/java/org/apache/openejb/server/discovery/MulticastPulseAgentTest.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-multicast/src/test/java/org/apache/openejb/server/discovery/MulticastPulseAgentTest.java?rev=1367974&r1=1367973&r2=1367974&view=diff
==============================================================================
---
openejb/trunk/openejb/server/openejb-multicast/src/test/java/org/apache/openejb/server/discovery/MulticastPulseAgentTest.java
(original)
+++
openejb/trunk/openejb/server/openejb-multicast/src/test/java/org/apache/openejb/server/discovery/MulticastPulseAgentTest.java
Wed Aug 1 13:05:27 2012
@@ -20,6 +20,7 @@ import org.apache.openejb.server.Discove
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
+import sun.net.util.IPAddressUtil;
import java.net.DatagramPacket;
import java.net.Inet6Address;
@@ -89,6 +90,13 @@ public class MulticastPulseAgentTest {
executor.shutdownNow();
}
+ /**
+ * Most of this code is identical to
org.apache.openejb.client.MulticastPulseClient#discoverURIs
+ * <p/>
+ * The MulticastPulseClient class is not shared or available here so the
test has to emulate it.
+ *
+ * @throws Exception On error
+ */
@Test
public void test() throws Exception {
@@ -120,32 +128,47 @@ public class MulticastPulseAgentTest {
final Set<URI> set = new TreeSet<URI>(new Comparator<URI>() {
@Override
- public int compare(URI u1, URI u2) {
+ public int compare(URI uri1, URI uri2) {
//Ignore server hostname
- final String serverHost = u1.getScheme();
- u1 = URI.create(u1.getSchemeSpecificPart());
- u2 = URI.create(u2.getSchemeSpecificPart());
+ URI u1 = URI.create(uri1.getSchemeSpecificPart());
+ URI u2 = URI.create(uri2.getSchemeSpecificPart());
//Ignore scheme (ejb,ejbs,etc.)
u1 = URI.create(u1.getSchemeSpecificPart());
u2 = URI.create(u2.getSchemeSpecificPart());
- if (u1.getHost().equals(serverHost)) {
- //If the service host is the same as the server host
- //then keep it at the top of the list
- return -1;
- }
-
//Compare URI hosts
- int i = u1.getHost().compareTo(u2.getHost());
-
+ int i = compare(u1.getHost(), u2.getHost());
if (i == 0) {
- i = u1.compareTo(u2);
+ i = uri1.compareTo(uri2);
}
return i;
}
+
+ private int compare(final String h1, final String h2) {
+
+ //Sort by hostname, IPv4, IPv6
+
+ try {
+ if (IPAddressUtil.isIPv4LiteralAddress(h1)) {
+ if (IPAddressUtil.isIPv6LiteralAddress(h2.replace("[",
"").replace("]", ""))) {
+ return -1;
+ }
+ } else if
(IPAddressUtil.isIPv6LiteralAddress(h1.replace("[", "").replace("]", ""))) {
+ if (IPAddressUtil.isIPv4LiteralAddress(h2)) {
+ return 1;
+ }
+ } else if (0 != h1.compareTo(h2)) {
+ return -1;
+ }
+ } catch (Throwable e) {
+ //Ignore
+ }
+
+ return h1.compareTo(h2);
+ }
});
final ReentrantLock setLock = new ReentrantLock();
@@ -241,11 +264,15 @@ public class MulticastPulseAgentTest {
try {
if (svc.contains("0.0.0.0")) {
for (final String h :
hosts) {
-
set.add(URI.create(svc.replace("0.0.0.0", ipFormat(h))));
+ if (!h.replace("[",
"").startsWith("2001:0:")) { //Filter Teredo
+
set.add(URI.create(svc.replace("0.0.0.0", ipFormat(h))));
+ }
}
} else if
(svc.contains("[::]")) {
for (final String h :
hosts) {
-
set.add(URI.create(svc.replace("[::]", ipFormat(h))));
+ if (!h.replace("[",
"").startsWith("2001:0:")) { //Filter Teredo
+
set.add(URI.create(svc.replace("[::]", ipFormat(h))));
+ }
}
} else {
//Just add as is
@@ -269,6 +296,7 @@ public class MulticastPulseAgentTest {
}
System.out.println("Exit MulticastPulse client thread on:
" + name);
+ System.out.flush();
}
}));
}
@@ -340,9 +368,21 @@ public class MulticastPulseAgentTest {
}
System.out.println();
+ System.out.flush();
+
+ final ArrayList<String> list = new ArrayList<String>();
+
+ final TreeSet<URI> uris = new TreeSet<URI>(set);
+ for (final URI uri : uris) {
+ final String astr = uri.toASCIIString();
+ System.out.println("MultiPulse discovered: " + astr);
+
+ if (list.contains(astr)) {
+ System.out.println("Duplicate uri: " + uri);
+ }
- for (final URI uri : set) {
- System.out.println("MultiPulse discovered: " +
uri.toASCIIString());
+ org.junit.Assert.assertTrue(!list.contains(astr));
+ list.add(astr);
}
System.out.println("Multipulse complete");
@@ -353,7 +393,7 @@ public class MulticastPulseAgentTest {
private String ipFormat(final String h) throws UnknownHostException {
- final InetAddress ia = Inet6Address.getByName(h);
+ final InetAddress ia = InetAddress.getByName(h);
if (ia instanceof Inet6Address) {
return "[" + ia.getHostAddress() + "]";
} else {