All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkus.test.utils.SocketUtils Maven / Gradle / Ivy

package io.quarkus.test.utils;

import java.io.IOException;
import java.net.ServerSocket;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

import io.quarkus.test.configuration.PropertyLookup;

public final class SocketUtils {

    private static final PropertyLookup PORT_RANGE_MIN_PROPERTY = new PropertyLookup("port.range.min", "1100");
    private static final PropertyLookup PORT_RANGE_MAX_PROPERTY = new PropertyLookup("port.range.max", "49151");
    private static final PropertyLookup PORT_RESOLUTION_STRATEGY_PROPERTY = new PropertyLookup("port.resolution.strategy");

    private static final int PORT_RANGE_MIN = PORT_RANGE_MIN_PROPERTY.getAsInteger();
    private static final int PORT_RANGE_MAX = PORT_RANGE_MAX_PROPERTY.getAsInteger();
    private static final String PORT_RESOLUTION_RANDOM_STRATEGY = "random";

    private static final AtomicInteger CURRENT_MIN_PORT = new AtomicInteger(PORT_RANGE_MIN);
    private static final Random RND = new Random(System.nanoTime());

    private SocketUtils() {

    }

    public static synchronized int findAvailablePort() {
        if (PORT_RESOLUTION_RANDOM_STRATEGY.equals(PORT_RESOLUTION_STRATEGY_PROPERTY.get())) {
            return findRandomAvailablePort();
        }

        return findNextAvailablePort();
    }

    public static int findRandomAvailablePort() {
        int portRange = PORT_RANGE_MAX - PORT_RANGE_MIN;
        int candidatePort;
        int searchCounter = 0;
        do {
            if (searchCounter > portRange) {
                throw new IllegalStateException(
                        String.format("Could not find an available port in the range [%d, %d] after %d attempts",
                                PORT_RANGE_MIN, PORT_RANGE_MAX, searchCounter));
            }

            candidatePort = PORT_RANGE_MIN + RND.nextInt((PORT_RANGE_MAX - PORT_RANGE_MIN) + 1);
            searchCounter++;
        } while (!isPortAvailable(candidatePort));

        return candidatePort;
    }

    public static synchronized int findNextAvailablePort() {
        int candidate;
        do {
            candidate = CURRENT_MIN_PORT.incrementAndGet();
            if (isPortAvailable(candidate)) {
                return candidate;
            }
        } while (candidate <= PORT_RANGE_MAX);

        throw new IllegalStateException(String.format("Could not find an available port in the range [%d, %d]",
                PORT_RANGE_MIN, PORT_RANGE_MAX));
    }

    private static boolean isPortAvailable(int port) {
        if (port < PORT_RANGE_MIN || port > PORT_RANGE_MAX) {
            throw new IllegalArgumentException("Invalid start port: " + port);
        }

        try (ServerSocket ss = new ServerSocket(port)) {
            ss.setReuseAddress(true);
            return true;
        } catch (IOException ignored) {
            // do nothing: port not available
        }

        return false;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy