From 296ba95906c29fc48e4e663672ea1fdcde03297c Mon Sep 17 00:00:00 2001 From: Weix Sun Date: Sat, 19 Nov 2022 17:35:39 +0800 Subject: [PATCH] Replace usage of removed SocketUtils in Spring 6 with TestSocketUtils --- .licenserc.yaml | 1 + .../config/spring/EmbeddedZooKeeper.java | 4 +- dubbo-config/pom.xml | 6 + .../test/common/utils/TestSocketUtils.java | 108 ++++++++++++++++++ pom.xml | 1 + 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/utils/TestSocketUtils.java diff --git a/.licenserc.yaml b/.licenserc.yaml index fcbf54b12bd..dc186df636a 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -76,6 +76,7 @@ header: - 'dubbo-common/src/main/java/org/apache/dubbo/common/utils/CIDRUtils.java' - 'dubbo-common/src/main/java/org/apache/dubbo/common/utils/Utf8Utils.java' - 'dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/EmbeddedZooKeeper.java' + - 'dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/utils/TestSocketUtils.java' comment: on-failure diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/EmbeddedZooKeeper.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/EmbeddedZooKeeper.java index 009f371bb9f..c1b2d94c9e6 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/EmbeddedZooKeeper.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/EmbeddedZooKeeper.java @@ -17,12 +17,12 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.test.common.utils.TestSocketUtils; import org.apache.zookeeper.server.ServerConfig; import org.apache.zookeeper.server.ZooKeeperServerMain; import org.apache.zookeeper.server.quorum.QuorumPeerConfig; import org.springframework.context.SmartLifecycle; import org.springframework.util.ErrorHandler; -import org.springframework.util.SocketUtils; import java.io.File; import java.lang.reflect.Method; @@ -83,7 +83,7 @@ public class EmbeddedZooKeeper implements SmartLifecycle { * Construct an EmbeddedZooKeeper with a random port. */ public EmbeddedZooKeeper() { - clientPort = SocketUtils.findAvailableTcpPort(); + clientPort = TestSocketUtils.findAvailableTcpPort(); } /** diff --git a/dubbo-config/pom.xml b/dubbo-config/pom.xml index 168b5ba810d..dcbb5355ebb 100644 --- a/dubbo-config/pom.xml +++ b/dubbo-config/pom.xml @@ -41,5 +41,11 @@ ${project.parent.version} test + + org.apache.dubbo + dubbo-test-common + ${project.parent.version} + test + diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/utils/TestSocketUtils.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/utils/TestSocketUtils.java new file mode 100644 index 00000000000..e46c83a2cec --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/utils/TestSocketUtils.java @@ -0,0 +1,108 @@ +/* + * Copyright 2002-2022 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 + * + * https://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.apache.dubbo.test.common.utils; + +import java.net.InetAddress; +import java.net.ServerSocket; +import java.security.SecureRandom; + +import javax.net.ServerSocketFactory; + +import org.apache.dubbo.common.utils.Assert; + +/** + * Simple utility for finding available TCP ports on {@code localhost} for use in + * integration testing scenarios. + * + *

{@code TestSocketUtils} can be used in integration tests which start an + * external server on an available random port. However, these utilities make no + * guarantee about the subsequent availability of a given port and are therefore + * unreliable. Instead of using {@code TestSocketUtils} to find an available local + * port for a server, it is recommended that you rely on a server's ability to + * start on a random ephemeral port that it selects or is assigned by the + * operating system. To interact with that server, you should query the server + * for the port it is currently using. + * + * @since 3.2 + */ +public class TestSocketUtils { + + /** + * The minimum value for port ranges used when finding an available TCP port. + */ + static final int PORT_RANGE_MIN = 1024; + + /** + * The maximum value for port ranges used when finding an available TCP port. + */ + static final int PORT_RANGE_MAX = 65535; + + private static final int PORT_RANGE_PLUS_ONE = PORT_RANGE_MAX - PORT_RANGE_MIN + 1; + + private static final int MAX_ATTEMPTS = 1_000; + + private static final SecureRandom random = new SecureRandom(); + + private static final TestSocketUtils INSTANCE = new TestSocketUtils(); + + private TestSocketUtils() { + } + + /** + * Find an available TCP port randomly selected from the range [1024, 65535]. + * @return an available TCP port number + * @throws IllegalStateException if no available port could be found + */ + public static int findAvailableTcpPort() { + return INSTANCE.findAvailableTcpPortInternal(); + } + + + /** + * Internal implementation of {@link #findAvailableTcpPort()}. + *

Package-private solely for testing purposes. + */ + int findAvailableTcpPortInternal() { + int candidatePort; + int searchCounter = 0; + do { + Assert.assertTrue(++searchCounter <= MAX_ATTEMPTS, String.format( + "Could not find an available TCP port in the range [%d, %d] after %d attempts", + PORT_RANGE_MIN, PORT_RANGE_MAX, MAX_ATTEMPTS)); + candidatePort = PORT_RANGE_MIN + random.nextInt(PORT_RANGE_PLUS_ONE); + } + while (!isPortAvailable(candidatePort)); + + return candidatePort; + } + + /** + * Determine if the specified TCP port is currently available on {@code localhost}. + *

Package-private solely for testing purposes. + */ + boolean isPortAvailable(int port) { + try { + ServerSocket serverSocket = ServerSocketFactory.getDefault() + .createServerSocket(port, 1, InetAddress.getByName("localhost")); + serverSocket.close(); + return true; + } + catch (Exception ex) { + return false; + } + } + +} diff --git a/pom.xml b/pom.xml index af5165094d7..d6985bde292 100644 --- a/pom.xml +++ b/pom.xml @@ -327,6 +327,7 @@ **/org/apache/dubbo/common/utils/Utf8Utils.java, **/org/apache/dubbo/common/serialize/protobuf/support/wrapper/MapValue.java, **/org/apache/dubbo/common/serialize/protobuf/support/wrapper/ThrowablePB.java, + **/org/apache/dubbo/test/common/utils/TestSocketUtils.java, **/org/apache/dubbo/triple/TripleWrapper.java, **/istio/v1/auth/**/*, **/com/google/rpc/*,