-
-
Couldn't load subscription status.
- Fork 2
SocketUtils is internalized. The library has been changed. #4
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| package com.asarkar.spring.test.redis | ||
|
|
||
| import org.springframework.util.Assert | ||
| import java.net.DatagramSocket | ||
| import java.net.InetAddress | ||
| import java.net.ServerSocket | ||
| import java.util.Random | ||
| import javax.net.ServerSocketFactory | ||
|
|
||
| /** | ||
| * Simple utility methods for working with network sockets for example, | ||
| * for finding available ports on `localhost`. | ||
| * | ||
| * Within this class, a TCP port refers to a port for a [ServerSocket]; | ||
| * whereas, a UDP port refers to a port for a [DatagramSocket]. | ||
| * | ||
| * org.springframework.util.SocketUtils was removed in Spring 6. | ||
| * From Springboot 3.2.3 version, SocketUtils cannot be used. | ||
| * org.springframework.test.util.TestSocketUtils can be used as an alternative, but embedded-redis-spring has to support older versions, so org.springframework.util.SocketUtils was copied. | ||
| * | ||
| * @author fennec-fox | ||
| * @since 1.1.2 | ||
| */ | ||
fennec-fox marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| object SocketUtils { | ||
| /** | ||
| * The default minimum value for port ranges used when finding an available | ||
| * socket port. | ||
| */ | ||
| private const val PORT_RANGE_MIN: Int = 1024 | ||
|
|
||
| /** | ||
| * The default maximum value for port ranges used when finding an available | ||
| * socket port. | ||
| */ | ||
| const val PORT_RANGE_MAX: Int = 65535 | ||
|
|
||
| private val random = Random(System.nanoTime()) | ||
|
|
||
| /** | ||
| * Find an available TCP port randomly selected from the range | ||
| * [`minPort`, `maxPort`]. | ||
| * @param minPort the minimum port number | ||
| * @param maxPort the maximum port number | ||
| * @return an available TCP port number | ||
| * @throws IllegalStateException if no available port could be found | ||
| */ | ||
| /** | ||
| * Find an available TCP port randomly selected from the range | ||
| * [`minPort`, {@value #PORT_RANGE_MAX}]. | ||
| * @param minPort the minimum port number | ||
| * @return an available TCP port number | ||
| * @throws IllegalStateException if no available port could be found | ||
| */ | ||
| /** | ||
| * Find an available TCP port randomly selected from the range | ||
| * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. | ||
| * @return an available TCP port number | ||
| * @throws IllegalStateException if no available port could be found | ||
| */ | ||
| @JvmOverloads | ||
| fun findAvailableTcpPort(minPort: Int = PORT_RANGE_MIN, maxPort: Int = PORT_RANGE_MAX): Int { | ||
| return SocketType.TCP.findAvailablePort(minPort, maxPort) | ||
| } | ||
|
|
||
| private enum class SocketType { | ||
| TCP { | ||
| override fun isPortAvailable(port: Int): Boolean { | ||
| try { | ||
| val serverSocket = ServerSocketFactory.getDefault().createServerSocket( | ||
| port, | ||
| 1, | ||
| InetAddress.getByName("localhost") | ||
| ) | ||
| serverSocket.close() | ||
| return true | ||
| } catch (ex: Exception) { | ||
| return false | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * Determine if the specified port for this `SocketType` is | ||
| * currently available on `localhost`. | ||
| */ | ||
| protected abstract fun isPortAvailable(port: Int): Boolean | ||
|
|
||
| /** | ||
| * Find a pseudo-random port number within the range | ||
| * [`minPort`, `maxPort`]. | ||
| * @param minPort the minimum port number | ||
| * @param maxPort the maximum port number | ||
| * @return a random port number within the specified range | ||
| */ | ||
| private fun findRandomPort(minPort: Int, maxPort: Int): Int { | ||
| val portRange = maxPort - minPort | ||
| return minPort + random.nextInt(portRange + 1) | ||
| } | ||
|
|
||
| /** | ||
| * Find an available port for this `SocketType`, randomly selected | ||
| * from the range [`minPort`, `maxPort`]. | ||
| * @param minPort the minimum port number | ||
| * @param maxPort the maximum port number | ||
| * @return an available port number for this socket type | ||
| * @throws IllegalStateException if no available port could be found | ||
| */ | ||
| fun findAvailablePort(minPort: Int, maxPort: Int): Int { | ||
| Assert.isTrue(minPort > 0, "'minPort' must be greater than 0") | ||
| Assert.isTrue(maxPort >= minPort, "'maxPort' must be greater than or equal to 'minPort'") | ||
| Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to $PORT_RANGE_MAX") | ||
|
|
||
| val portRange = maxPort - minPort | ||
| var candidatePort: Int | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I need to review this more closely, but is it possible for multiple threads to enter the do-while loop? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code is a conversion of the existing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @asarkar Could you please check the PR again? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, but I would like to see some tests for SocketUtils. If Spring has some, feel free to use those, but otherwise, we need new tests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @asarkar The current PR was created because SocketUtils in Spring is not available. I will add the test code for SocketUtils mentioned above soon. |
||
| var searchCounter = 0 | ||
| do { | ||
| check(searchCounter <= portRange) { | ||
| "Could not find an available $name port in the range [$minPort, $maxPort] after $searchCounter attempts" | ||
| } | ||
| candidatePort = findRandomPort(minPort, maxPort) | ||
| searchCounter++ | ||
| } while (!isPortAvailable(candidatePort)) | ||
|
|
||
| return candidatePort | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.