inet = intface.getInetAddresses();
-// if (!inet.hasMoreElements())
+// if (!inet.hasMoreElements())
// continue;
// String address = inet.nextElement().getHostAddress();
// return address;
// }
return null;
}
-
+
public static void waitListening(AbstractInternetProtocolReceivingChannelAdapter adapter) throws Exception {
int n = 0;
while (!adapter.isListening()) {
@@ -383,9 +349,7 @@ public class SocketTestUtils {
throw new Exception("Gateway failed to listen");
}
}
-
- }
-
+ }
}
diff --git a/spring-integration-test/src/main/java/org/springframework/integration/test/util/SocketUtils.java b/spring-integration-test/src/main/java/org/springframework/integration/test/util/SocketUtils.java
new file mode 100644
index 0000000000..e54f27cbc4
--- /dev/null
+++ b/spring-integration-test/src/main/java/org/springframework/integration/test/util/SocketUtils.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.integration.test.util;
+
+import java.net.DatagramSocket;
+import java.net.ServerSocket;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.net.ServerSocketFactory;
+
+import org.springframework.util.Assert;
+
+/**
+ *
+ * Contains several socket-specific utility methods. For example, you may have
+ * test cases that require an open port. Rather than hard-coding the relevant port,
+ * it will be better to use methods from this utility class to automatically select
+ * an open port, therefore improving the portability of your test-cases across
+ * systems.
+ *
+ * @author Gunnar Hillert
+ * @since 2.2
+ *
+ */
+public final class SocketUtils {
+
+ public static final int DEFAULT_PORT_RANGE_MIN = 10000;
+ public static final int DEFAULT_PORT_RANGE_MAX = 60000;
+
+ /**
+ * The constructor is intentionally public. In several test cases you may have
+ * the need to use the methods of this class multiple times from within your
+ * Spring Application Context XML file using SpEL. Of course you can do:
+ *
+ *
+ * {@code
+ * ...port="#{T(org.springframework.integration.test.util.SocketUtils).findAvailableServerSocket(12000)}"
+ * }
+ *
+ *
+ * But unfortunately, you would need to repeat the package for each usage.
+ * This will be acceptable for single use, but if you need to invoke the
+ * methods numerous time, you may instead want to do this:
+ *
+ *
+ * {@code
+ *
+ *
+ * ...port="#{tcpIpUtils.findAvailableServerSocket(12000)}"
+ * }
+ *
+ *
+ */
+ public SocketUtils() { }
+
+ /**
+ * Determines a free available server socket (port) using the 'seed' value as
+ * the starting port. The utility methods will probe for 200 sockets but will
+ * return as soon an open port is found.
+ *
+ * @param seed The starting port, which must not be negative.
+ * @return An available port number
+ *
+ * @throws IllegalStateException when no open port was found.
+ */
+ public static int findAvailableServerSocket(int seed) {
+ final List openPorts = findAvailableServerSockets(seed, 1);
+ return openPorts.get(0);
+ }
+
+ /**
+ * Determines a free available server socket (port) using the 'seed' value as
+ * the starting port. The utility methods will probe for 200 sockets but will
+ * return as soon an open port is found.
+ *
+ * @param seed The starting port, which must not be negative.
+ * @param numberOfRequestedPorts How many open ports shall be retrieved?
+ * @return A list containing the requested number of open ports
+ *
+ * @throws IllegalStateException when no open port was found.
+ */
+ public static List findAvailableServerSockets(int seed, int numberOfRequestedPorts) {
+
+ Assert.isTrue(seed >= 0, "'seed' must not be negative");
+ Assert.isTrue(numberOfRequestedPorts > 0, "'numberOfRequestedPorts' must not be negative");
+
+ final List openPorts = new ArrayList(numberOfRequestedPorts);
+
+ for (int i = seed; i < seed+200; i++) {
+ try {
+ ServerSocket sock = ServerSocketFactory.getDefault().createServerSocket(i);
+ sock.close();
+ openPorts.add(i);
+
+ if (openPorts.size() == numberOfRequestedPorts) {
+ return openPorts;
+ }
+
+ } catch (Exception e) { }
+ }
+
+ throw new IllegalStateException(String.format("Cannot find a free server socket (%s requested)", numberOfRequestedPorts));
+ }
+
+ /**
+ * Determines a free available server socket (port) using an automatically
+ * chosen start seed port.
+ *
+ * @return An available port number
+ *
+ * @throws IllegalStateException when no open port was found.
+ */
+ public static int findAvailableServerSocket() {
+ int seed = getRandomSeedPort();
+ return findAvailableServerSocket(seed);
+ }
+
+ /**
+ * Determines a free available Udp socket (port) using the 'seed' value as
+ * the starting port. The utility methods will probe for 200 sockets but will
+ * return as soon an open port is found.
+ *
+ * @param seed The starting port, which must not be negative.
+ * @return An available port number
+ *
+ * @throws IllegalStateException when no open port was found.
+ *
+ */
+ public static int findAvailableUdpSocket(int seed) {
+ final List openPorts = findAvailableUdpSockets(seed, 1);
+ return openPorts.get(0);
+ }
+
+ /**
+ * Determines free available udp socket(s) (port) using the 'seed' value as
+ * the starting port. The utility methods will probe for 200 sockets but will
+ * return as soon an open port is found.
+ *
+ * @param seed The starting port, which must not be negative.
+ * @param numberOfRequestedPorts How many open ports shall be retrieved?
+ * @return A list containing the requested number of open ports
+ *
+ * @throws IllegalStateException when no open port was found.
+ */
+ public static List findAvailableUdpSockets(int seed, int numberOfRequestedPorts) {
+
+ Assert.isTrue(seed >= 0, "'seed' must not be negative");
+ Assert.isTrue(numberOfRequestedPorts > 0, "'numberOfRequestedPorts' must not be negative");
+
+ final List openPorts = new ArrayList(numberOfRequestedPorts);
+
+ for (int i = seed; i < seed+200; i++) {
+ try {
+ DatagramSocket sock = new DatagramSocket(i);
+ sock.close();
+ Thread.sleep(100);
+
+ openPorts.add(i);
+
+ if (openPorts.size() == numberOfRequestedPorts) {
+ return openPorts;
+ }
+
+ } catch (Exception e) { }
+ }
+
+ throw new IllegalStateException(String.format("Cannot find a free server socket (%s requested)", numberOfRequestedPorts));
+
+ }
+
+ /**
+ * Determines a free available Udp socket using an automatically
+ * chosen start seed port.
+ *
+ * @return An available port number
+ *
+ * @throws IllegalStateException when no open port was found.
+ */
+ public static int findAvailableUdpSocket() {
+ int seed = getRandomSeedPort();
+ return findAvailableUdpSocket(seed);
+ }
+
+ /**
+ * Determines a random seed port number within the port range
+ * {@value #DEFAULT_PORT_RANGE_MIN} and {@value #DEFAULT_PORT_RANGE_MAX}.
+ *
+ * @return A number with the the specified range
+ */
+ public static int getRandomSeedPort() {
+
+ final Random random = new Random();
+
+ int randomNumber = random.nextInt(DEFAULT_PORT_RANGE_MAX - DEFAULT_PORT_RANGE_MIN + 1) + DEFAULT_PORT_RANGE_MIN;
+
+ return randomNumber;
+ }
+
+}
diff --git a/spring-integration-test/src/test/java/org/springframework/integration/test/util/SocketUtilsTests.java b/spring-integration-test/src/test/java/org/springframework/integration/test/util/SocketUtilsTests.java
new file mode 100644
index 0000000000..508354ac18
--- /dev/null
+++ b/spring-integration-test/src/test/java/org/springframework/integration/test/util/SocketUtilsTests.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.integration.test.util;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+/**
+ * @author Gunnar Hillert
+ */
+public class SocketUtilsTests {
+
+ @Test
+ public void testFindAvailableServerSocketWithNegativeSeedPort() {
+
+ try {
+ SocketUtils.findAvailableServerSocket(-500);
+ }
+ catch (IllegalArgumentException e) {
+ Assert.assertEquals("'seed' must not be negative", e.getMessage());
+ return;
+
+ }
+
+ Assert.fail("Expected an IllegalArgumentException to be thrown.");
+ }
+
+ @Test
+ public void testFindAvailableUdpSocketWithNegativeSeedPort() {
+
+ try {
+ SocketUtils.findAvailableUdpSocket(-500);
+ }
+ catch (IllegalArgumentException e) {
+ Assert.assertEquals("'seed' must not be negative", e.getMessage());
+ return;
+
+ }
+
+ Assert.fail("Expected an IllegalArgumentException to be thrown.");
+ }
+
+}