From d42411ef339050467c023058e38aed30970cc2ef Mon Sep 17 00:00:00 2001 From: "igor.petrenko" Date: Thu, 30 Apr 2026 14:18:30 +0300 Subject: [PATCH 1/2] CE-156 oap-template: RandomSocketAddressResolver --- .../java/oap/http/client/OapHttpClient.java | 10 ++++++ .../client/RandomSocketAddressResolver.java | 33 +++++++++++++++++++ pom.xml | 2 +- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 oap-http/oap-http/src/main/java/oap/http/client/RandomSocketAddressResolver.java diff --git a/oap-http/oap-http/src/main/java/oap/http/client/OapHttpClient.java b/oap-http/oap-http/src/main/java/oap/http/client/OapHttpClient.java index 6dcad2ee92..3afd009c3a 100644 --- a/oap-http/oap-http/src/main/java/oap/http/client/OapHttpClient.java +++ b/oap-http/oap-http/src/main/java/oap/http/client/OapHttpClient.java @@ -15,6 +15,7 @@ import org.eclipse.jetty.client.WWWAuthenticationProtocolHandler; import org.eclipse.jetty.http.HttpCookieStore; import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.util.SocketAddressResolver; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.VirtualThreadPool; import org.xbill.DNS.Address; @@ -57,6 +58,7 @@ public static class OapHttpClientBuilder { private HttpCookieStore cookieStore; private ConnectionPool.Factory connectionPoolFactory; private ConnectionPoolFactoryType connectionPoolFactoryType; + private SocketAddressResolver socketAddressResolver; public OapHttpClientBuilder transport( AbstractConnectorHttpClientTransport httpClientTransport ) { this.httpClientTransport = httpClientTransport; @@ -112,6 +114,12 @@ public OapHttpClientBuilder withConnectionPoolFactoryType( ConnectionPoolFactory return this; } + public OapHttpClientBuilder withSocketAddressResolver( SocketAddressResolver socketAddressResolver ) { + this.socketAddressResolver = socketAddressResolver; + + return this; + } + @SneakyThrows public HttpClient build() { HttpClient httpClient = httpClientTransport != null ? new HttpClient( httpClientTransport ) : new HttpClient(); @@ -141,6 +149,8 @@ public HttpClient build() { promise.failed( e ); } } ); + } else if( socketAddressResolver != null ) { + httpClient.setSocketAddressResolver( socketAddressResolver ); } if( metrics != null ) { diff --git a/oap-http/oap-http/src/main/java/oap/http/client/RandomSocketAddressResolver.java b/oap-http/oap-http/src/main/java/oap/http/client/RandomSocketAddressResolver.java new file mode 100644 index 0000000000..4c4057bf8a --- /dev/null +++ b/oap-http/oap-http/src/main/java/oap/http/client/RandomSocketAddressResolver.java @@ -0,0 +1,33 @@ +package oap.http.client; + +import org.apache.commons.lang3.RandomUtils; +import org.eclipse.jetty.util.Promise; +import org.eclipse.jetty.util.SocketAddressResolver; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.List; +import java.util.Map; + +public class RandomSocketAddressResolver implements SocketAddressResolver { + private static final RandomUtils RANDOM_UTILS = RandomUtils.insecure(); + + @Override + public void resolve( String host, int port, Map context, Promise> promise ) { + try { + InetAddress[] addresses = InetAddress.getAllByName( host ); + + int length = addresses.length; + if( length > 0 ) { + int i = length > 1 ? RANDOM_UTILS.randomInt( 0, length ) : 0; + promise.succeeded( List.of( new InetSocketAddress( addresses[i], port ) ) ); + } else { + promise.failed( new UnknownHostException() ); + } + + } catch( Throwable ex ) { + promise.failed( ex ); + } + } +} diff --git a/pom.xml b/pom.xml index d7f3301b60..1163ba775b 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ - 25.6.5 + 25.6.6 25.0.1 25.0.0 From 1b867a906e6198d619c412e248bff5c9464ec25c Mon Sep 17 00:00:00 2001 From: "igor.petrenko" Date: Thu, 30 Apr 2026 14:23:04 +0300 Subject: [PATCH 2/2] CE-156 oap-template: RandomSocketAddressResolver --- .../RoundRobinSocketAddressResolver.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 oap-http/oap-http/src/main/java/oap/http/client/RoundRobinSocketAddressResolver.java diff --git a/oap-http/oap-http/src/main/java/oap/http/client/RoundRobinSocketAddressResolver.java b/oap-http/oap-http/src/main/java/oap/http/client/RoundRobinSocketAddressResolver.java new file mode 100644 index 0000000000..2cb3d91616 --- /dev/null +++ b/oap-http/oap-http/src/main/java/oap/http/client/RoundRobinSocketAddressResolver.java @@ -0,0 +1,33 @@ +package oap.http.client; + +import org.eclipse.jetty.util.Promise; +import org.eclipse.jetty.util.SocketAddressResolver; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +public class RoundRobinSocketAddressResolver implements SocketAddressResolver { + private final AtomicInteger counter = new AtomicInteger(); + + @Override + public void resolve( String host, int port, Map context, Promise> promise ) { + try { + InetAddress[] addresses = InetAddress.getAllByName( host ); + + int length = addresses.length; + if( length > 0 ) { + int i = length > 1 ? counter.incrementAndGet() % length : 0; + promise.succeeded( List.of( new InetSocketAddress( addresses[i], port ) ) ); + } else { + promise.failed( new UnknownHostException() ); + } + + } catch( Throwable ex ) { + promise.failed( ex ); + } + } +}