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 {


Reply via email to