diff --git a/support/src/test/java/org/springframework/ws/transport/support/FreePortScanner.java b/support/src/test/java/org/springframework/ws/transport/support/FreePortScanner.java new file mode 100644 index 00000000..514b3620 --- /dev/null +++ b/support/src/test/java/org/springframework/ws/transport/support/FreePortScanner.java @@ -0,0 +1,99 @@ +/* + * Copyright 2005-2011 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.ws.transport.support; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.util.Random; + +import org.springframework.util.Assert; + +/** + * Utility class that finds free BSD ports for use in testing scenario's. + * + * @author Ben Hale + * @author Arjen Poutsma + */ +public abstract class FreePortScanner { + + private static final int MIN_SAFE_PORT = 1024; + + private static final int MAX_PORT = 65535; + + private static final Random random = new Random(); + + /** + * Returns the number of a free port in the default range. + */ + public static int getFreePort() { + return getFreePort(MIN_SAFE_PORT, MAX_PORT); + } + + /** + * Returns the number of a free port in the given range. + */ + public static int getFreePort(int minPort, int maxPort) { + Assert.isTrue(minPort > 0, "'minPort' must be larger than 0"); + Assert.isTrue(maxPort > minPort, "'maxPort' must be larger than minPort"); + int portRange = maxPort - minPort; + int candidatePort; + int searchCounter = 0; + do { + if (++searchCounter > portRange) { + throw new IllegalStateException( + String.format("There were no ports available in the range %d to %d", minPort, maxPort)); + } + candidatePort = getRandomPort(minPort, portRange); + } + while (!isPortAvailable(candidatePort)); + + return candidatePort; + } + + private static int getRandomPort(int minPort, int portRange) { + return minPort + random.nextInt(portRange); + } + + private static boolean isPortAvailable(int port) { + ServerSocket serverSocket; + try { + serverSocket = new ServerSocket(); + } + catch (IOException ex) { + throw new IllegalStateException("Unable to create ServerSocket.", ex); + } + + try { + InetSocketAddress sa = new InetSocketAddress(port); + serverSocket.bind(sa); + return true; + } + catch (IOException ex) { + return false; + } + finally { + try { + serverSocket.close(); + } + catch (IOException ex) { + // ignore + } + } + } + +}