You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2019/08/11 22:05:32 UTC

[camel] 01/01: CAMEL-13853: Fixed AvailablePortFinder for WSL

This is an automated email from the ASF dual-hosted git repository.

janbednar pushed a commit to branch CAMEL-13853
in repository https://gitbox.apache.org/repos/asf/camel.git

commit c7f36cd646054868340f530c1e82d0710e8315ee
Author: Jan Bednář <ma...@janbednar.eu>
AuthorDate: Sun Aug 11 20:05:28 2019 +0200

    CAMEL-13853: Fixed AvailablePortFinder for WSL
---
 .../org/apache/camel/test/AvailablePortFinder.java | 57 +++++++++++++---------
 .../apache/camel/test/AvailablePortFinderTest.java | 26 +++++++++-
 .../camel/management/util/AvailablePortFinder.java | 57 +++++++++++++---------
 3 files changed, 95 insertions(+), 45 deletions(-)

diff --git a/components/camel-test/src/main/java/org/apache/camel/test/AvailablePortFinder.java b/components/camel-test/src/main/java/org/apache/camel/test/AvailablePortFinder.java
index 310af44..1b83b1b 100644
--- a/components/camel-test/src/main/java/org/apache/camel/test/AvailablePortFinder.java
+++ b/components/camel-test/src/main/java/org/apache/camel/test/AvailablePortFinder.java
@@ -18,6 +18,8 @@ package org.apache.camel.test;
 
 import java.io.IOException;
 import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.util.NoSuchElementException;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -61,19 +63,26 @@ public final class AvailablePortFinder {
     private AvailablePortFinder() {
         // Do nothing
     }
-    
+
     static {
         int port = MIN_PORT_NUMBER;
         ServerSocket ss = null;
 
         while (ss == null) {
             try {
-                ss = new ServerSocket(port);
+                ss = new ServerSocket();
+                ss.setReuseAddress(false);
+                ss.bind(new InetSocketAddress(InetAddress.getLocalHost(), port), 0);
             } catch (Exception e) {
+                close(ss);
                 ss = null;
                 port += 200;
+                if (port >= MAX_PORT_NUMBER) {
+                    throw new IllegalStateException("Cannot find port", e);
+                }
             }
-        } 
+        }
+
         LOCK = ss;
         Runtime.getRuntime().addShutdownHook(new Thread() {
             public void run() {
@@ -137,31 +146,35 @@ public final class AvailablePortFinder {
             throw new IllegalArgumentException("Invalid start currentMinPort: " + port);
         }
 
-        ServerSocket ss = null;
-        DatagramSocket ds = null;
         try {
-            ss = new ServerSocket(port);
-            ss.setReuseAddress(true);
-            ds = new DatagramSocket(port);
-            ds.setReuseAddress(true);
-            return true;
-        } catch (IOException e) {
-            // Do nothing
-        } finally {
-            if (ds != null) {
-                ds.close();
+            ServerSocket ss = null;
+            InetAddress addr = InetAddress.getLocalHost();
+            try {
+                ss = new ServerSocket();
+                ss.setReuseAddress(false);
+                ss.bind(new InetSocketAddress(addr, port), 0);
+            } finally {
+                close(ss);
             }
 
-            if (ss != null) {
-                try {
-                    ss.close();
-                } catch (IOException e) {
-                    /* should not be thrown */
-                }
+            try (DatagramSocket ds = new DatagramSocket(null)) {
+                ds.setReuseAddress(false);
+                ds.bind(new InetSocketAddress(addr, port));
             }
+            return true;
+        } catch (IOException ignored) {
         }
 
         return false;
     }
 
-}
+    private static void close(ServerSocket ss) {
+        if (ss != null) {
+            try {
+                ss.close();
+            } catch (IOException e) {
+                /* should not be thrown */
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/components/camel-test/src/test/java/org/apache/camel/test/AvailablePortFinderTest.java b/components/camel-test/src/test/java/org/apache/camel/test/AvailablePortFinderTest.java
index 3e2a236..4d25ea3 100644
--- a/components/camel-test/src/test/java/org/apache/camel/test/AvailablePortFinderTest.java
+++ b/components/camel-test/src/test/java/org/apache/camel/test/AvailablePortFinderTest.java
@@ -16,6 +16,10 @@
  */
 package org.apache.camel.test;
 
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.MulticastSocket;
 import java.net.ServerSocket;
 
 import org.junit.Assert;
@@ -40,7 +44,7 @@ public class AvailablePortFinderTest {
 
 
     @Test
-    public void testNotAvailablePort() throws Exception {
+    public void testNotAvailableTcpPort() throws Exception {
         int p1 = AvailablePortFinder.getNextAvailable(11000);
         ServerSocket socket = new ServerSocket(p1);
         int p2 = AvailablePortFinder.getNextAvailable(p1);
@@ -48,6 +52,26 @@ public class AvailablePortFinderTest {
         socket.close();
     }
 
+    @Test
+    public void testNotAvailableUdpPort() throws Exception {
+        int p1 = AvailablePortFinder.getNextAvailable(11000);
+        DatagramSocket socket = new DatagramSocket(p1);
+        int p2 = AvailablePortFinder.getNextAvailable(p1);
+        Assert.assertFalse("Port " + p1 + " Port2 " + p2, p1 == p2);
+        socket.close();
+    }
+
+    @Test
+    public void testNotAvailableMulticastPort() throws Exception {
+        int p1 = AvailablePortFinder.getNextAvailable(11000);
+        MulticastSocket socket = new MulticastSocket(null);
+        socket.setReuseAddress(false); // true is default for MulticastSocket, we wan to fail if port is occupied
+        socket.bind(new InetSocketAddress(InetAddress.getLocalHost(), p1));
+        int p2 = AvailablePortFinder.getNextAvailable(p1);
+        Assert.assertFalse("Port " + p1 + " Port2 " + p2, p1 == p2);
+        socket.close();
+    }
+
     @Test (expected = IllegalArgumentException.class)
     public void getMinOutOfRangePort() throws Exception {
         AvailablePortFinder.getNextAvailable(AvailablePortFinder.MIN_PORT_NUMBER - 1);
diff --git a/core/camel-management-impl/src/test/java/org/apache/camel/management/util/AvailablePortFinder.java b/core/camel-management-impl/src/test/java/org/apache/camel/management/util/AvailablePortFinder.java
index 04a14b2..09691ed 100644
--- a/core/camel-management-impl/src/test/java/org/apache/camel/management/util/AvailablePortFinder.java
+++ b/core/camel-management-impl/src/test/java/org/apache/camel/management/util/AvailablePortFinder.java
@@ -18,6 +18,8 @@ package org.apache.camel.management.util;
 
 import java.io.IOException;
 import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.util.NoSuchElementException;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -61,19 +63,26 @@ public final class AvailablePortFinder {
     private AvailablePortFinder() {
         // Do nothing
     }
-    
+
     static {
         int port = MIN_PORT_NUMBER;
         ServerSocket ss = null;
 
         while (ss == null) {
             try {
-                ss = new ServerSocket(port);
+                ss = new ServerSocket();
+                ss.setReuseAddress(false);
+                ss.bind(new InetSocketAddress(InetAddress.getLocalHost(), port), 0);
             } catch (Exception e) {
+                close(ss);
                 ss = null;
                 port += 200;
+                if (port >= MAX_PORT_NUMBER) {
+                    throw new IllegalStateException("Cannot find port", e);
+                }
             }
-        } 
+        }
+
         LOCK = ss;
         Runtime.getRuntime().addShutdownHook(new Thread() {
             public void run() {
@@ -137,31 +146,35 @@ public final class AvailablePortFinder {
             throw new IllegalArgumentException("Invalid start currentMinPort: " + port);
         }
 
-        ServerSocket ss = null;
-        DatagramSocket ds = null;
         try {
-            ss = new ServerSocket(port);
-            ss.setReuseAddress(true);
-            ds = new DatagramSocket(port);
-            ds.setReuseAddress(true);
-            return true;
-        } catch (IOException e) {
-            // Do nothing
-        } finally {
-            if (ds != null) {
-                ds.close();
+            ServerSocket ss = null;
+            InetAddress addr = InetAddress.getLocalHost();
+            try {
+                ss = new ServerSocket();
+                ss.setReuseAddress(false);
+                ss.bind(new InetSocketAddress(addr, port), 0);
+            } finally {
+                close(ss);
             }
 
-            if (ss != null) {
-                try {
-                    ss.close();
-                } catch (IOException e) {
-                    /* should not be thrown */
-                }
+            try (DatagramSocket ds = new DatagramSocket(null)) {
+                ds.setReuseAddress(false);
+                ds.bind(new InetSocketAddress(addr, port));
             }
+            return true;
+        } catch (IOException ignored) {
         }
 
         return false;
     }
 
-}
+    private static void close(ServerSocket ss) {
+        if (ss != null) {
+            try {
+                ss.close();
+            } catch (IOException e) {
+                /* should not be thrown */
+            }
+        }
+    }
+}
\ No newline at end of file