Fix handling of ResponseException from legacy client dependency.

Original Pull Request #3146
Closes #3144

Signed-off-by: Peter-Josef Meisch <pj.meisch@sothawo.com>
This commit is contained in:
Peter-Josef Meisch 2025-08-04 20:50:47 +02:00 committed by GitHub
parent 006cda6de6
commit e49bb63df4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 223 additions and 220 deletions

View File

@ -24,6 +24,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.elasticsearch.client.ResponseException; import org.elasticsearch.client.ResponseException;
import org.jspecify.annotations.Nullable;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DataIntegrityViolationException;
@ -33,6 +34,7 @@ import org.springframework.data.elasticsearch.NoSuchIndexException;
import org.springframework.data.elasticsearch.ResourceNotFoundException; import org.springframework.data.elasticsearch.ResourceNotFoundException;
import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
import org.springframework.data.elasticsearch.VersionConflictException; import org.springframework.data.elasticsearch.VersionConflictException;
import org.springframework.util.ClassUtils;
/** /**
* Simple {@link PersistenceExceptionTranslator} for Elasticsearch. Convert the given runtime exception to an * Simple {@link PersistenceExceptionTranslator} for Elasticsearch. Convert the given runtime exception to an
@ -45,6 +47,9 @@ import org.springframework.data.elasticsearch.VersionConflictException;
*/ */
public class ElasticsearchExceptionTranslator implements PersistenceExceptionTranslator { public class ElasticsearchExceptionTranslator implements PersistenceExceptionTranslator {
public static final boolean LEGACY_RESTCLIENT_PRESENT = ClassUtils
.isPresent("org.elasticsearch.client.ResponseException", ElasticsearchExceptionTranslator.class.getClassLoader());
private final JsonpMapper jsonpMapper; private final JsonpMapper jsonpMapper;
public ElasticsearchExceptionTranslator(JsonpMapper jsonpMapper) { public ElasticsearchExceptionTranslator(JsonpMapper jsonpMapper) {
@ -68,7 +73,7 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra
} }
@Override @Override
public DataAccessException translateExceptionIfPossible(RuntimeException ex) { public @Nullable DataAccessException translateExceptionIfPossible(RuntimeException ex) {
checkForConflictException(ex); checkForConflictException(ex);
@ -118,7 +123,7 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra
Integer status = null; Integer status = null;
String message = null; String message = null;
if (exception instanceof ResponseException responseException) { if (LEGACY_RESTCLIENT_PRESENT && exception instanceof ResponseException responseException) {
// this code is for the old RestClient // this code is for the old RestClient
status = responseException.getResponse().getStatusLine().getStatusCode(); status = responseException.getResponse().getStatusLine().getStatusCode();
message = responseException.getMessage(); message = responseException.getMessage();

View File

@ -658,7 +658,7 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
QueryResponse response = sqlClient.query(requestConverter.sqlQueryRequest(query)); QueryResponse response = sqlClient.query(requestConverter.sqlQueryRequest(query));
return responseConverter.sqlResponse(response); return responseConverter.sqlResponse(response);
} catch (IOException e) { } catch (Exception e) {
throw exceptionTranslator.translateException(e); throw exceptionTranslator.translateException(e);
} }
} }

View File

@ -32,7 +32,6 @@ import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.support.HttpHeaders; import org.springframework.data.elasticsearch.support.HttpHeaders;
import org.springframework.data.elasticsearch.support.VersionInfo;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -42,269 +41,268 @@ import org.springframework.util.Assert;
*/ */
public final class Rest5Clients { public final class Rest5Clients {
// values copied from Rest5ClientBuilder // values copied from Rest5ClientBuilder
public static final int DEFAULT_SOCKET_TIMEOUT_MILLIS = 30000; public static final int DEFAULT_SOCKET_TIMEOUT_MILLIS = 30000;
public static final int DEFAULT_RESPONSE_TIMEOUT_MILLIS = 0; // meaning infinite public static final int DEFAULT_RESPONSE_TIMEOUT_MILLIS = 0; // meaning infinite
private Rest5Clients() { private Rest5Clients() {}
}
/** /**
* Creates a low level {@link Rest5Client} for the given configuration. * Creates a low level {@link Rest5Client} for the given configuration.
* *
* @param clientConfiguration must not be {@literal null} * @param clientConfiguration must not be {@literal null}
* @return the {@link Rest5Client} * @return the {@link Rest5Client}
*/ */
public static Rest5Client getRest5Client(ClientConfiguration clientConfiguration) { public static Rest5Client getRest5Client(ClientConfiguration clientConfiguration) {
return getRest5ClientBuilder(clientConfiguration).build(); return getRest5ClientBuilder(clientConfiguration).build();
} }
private static Rest5ClientBuilder getRest5ClientBuilder(ClientConfiguration clientConfiguration) { private static Rest5ClientBuilder getRest5ClientBuilder(ClientConfiguration clientConfiguration) {
HttpHost[] httpHosts = getHttpHosts(clientConfiguration); HttpHost[] httpHosts = getHttpHosts(clientConfiguration);
Rest5ClientBuilder builder = Rest5Client.builder(httpHosts); Rest5ClientBuilder builder = Rest5Client.builder(httpHosts);
if (clientConfiguration.getPathPrefix() != null) { if (clientConfiguration.getPathPrefix() != null) {
builder.setPathPrefix(clientConfiguration.getPathPrefix()); builder.setPathPrefix(clientConfiguration.getPathPrefix());
} }
HttpHeaders headers = clientConfiguration.getDefaultHeaders(); HttpHeaders headers = clientConfiguration.getDefaultHeaders();
if (!headers.isEmpty()) { if (!headers.isEmpty()) {
builder.setDefaultHeaders(toHeaderArray(headers)); builder.setDefaultHeaders(toHeaderArray(headers));
} }
// RestClientBuilder configuration callbacks from the consumer // RestClientBuilder configuration callbacks from the consumer
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurationCallback : clientConfiguration for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurationCallback : clientConfiguration
.getClientConfigurers()) { .getClientConfigurers()) {
if (clientConfigurationCallback instanceof ElasticsearchRest5ClientConfigurationCallback configurationCallback) { if (clientConfigurationCallback instanceof ElasticsearchRest5ClientConfigurationCallback configurationCallback) {
builder = configurationCallback.configure(builder); builder = configurationCallback.configure(builder);
} }
} }
Duration connectTimeout = clientConfiguration.getConnectTimeout(); Duration connectTimeout = clientConfiguration.getConnectTimeout();
Duration socketTimeout = clientConfiguration.getSocketTimeout(); Duration socketTimeout = clientConfiguration.getSocketTimeout();
builder.setHttpClientConfigCallback(httpAsyncClientBuilder -> { builder.setHttpClientConfigCallback(httpAsyncClientBuilder -> {
httpAsyncClientBuilder.setUserAgent(VersionInfo.clientVersions()); if (clientConfiguration.getProxy().isPresent()) {
if (clientConfiguration.getProxy().isPresent()) { var proxy = clientConfiguration.getProxy().get();
var proxy = clientConfiguration.getProxy().get(); try {
try { var proxyRoutePlanner = new DefaultProxyRoutePlanner(HttpHost.create(proxy));
var proxyRoutePlanner = new DefaultProxyRoutePlanner(HttpHost.create(proxy)); httpAsyncClientBuilder.setRoutePlanner(proxyRoutePlanner);
httpAsyncClientBuilder.setRoutePlanner(proxyRoutePlanner); } catch (URISyntaxException e) {
} catch (URISyntaxException e) { throw new RuntimeException(e);
throw new RuntimeException(e); }
} }
} httpAsyncClientBuilder.addRequestInterceptorFirst((request, entity, context) -> {
httpAsyncClientBuilder.addRequestInterceptorFirst((request, entity, context) -> { clientConfiguration.getHeadersSupplier().get().forEach((header, values) -> {
clientConfiguration.getHeadersSupplier().get().forEach((header, values) -> { // The accept and content-type headers are already put on the request, despite this being the first
// The accept and content-type headers are already put on the request, despite this being the first // interceptor.
// interceptor. if ("Accept".equalsIgnoreCase(header) || " Content-Type".equalsIgnoreCase(header)) {
if ("Accept".equalsIgnoreCase(header) || " Content-Type".equalsIgnoreCase(header)) { request.removeHeaders(header);
request.removeHeaders(header); }
} values.forEach(value -> request.addHeader(header, value));
values.forEach(value -> request.addHeader(header, value)); });
}); });
});
// add httpclient configurator callbacks provided by the configuration // add httpclient configurator callbacks provided by the configuration
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
.getClientConfigurers()) { .getClientConfigurers()) {
if (clientConfigurer instanceof ElasticsearchHttpClientConfigurationCallback httpClientConfigurer) { if (clientConfigurer instanceof ElasticsearchHttpClientConfigurationCallback httpClientConfigurer) {
httpAsyncClientBuilder = httpClientConfigurer.configure(httpAsyncClientBuilder); httpAsyncClientBuilder = httpClientConfigurer.configure(httpAsyncClientBuilder);
} }
} }
}); });
builder.setConnectionConfigCallback(connectionConfigBuilder -> { builder.setConnectionConfigCallback(connectionConfigBuilder -> {
if (!connectTimeout.isNegative()) { if (!connectTimeout.isNegative()) {
connectionConfigBuilder.setConnectTimeout( connectionConfigBuilder.setConnectTimeout(
Timeout.of(Math.toIntExact(connectTimeout.toMillis()), TimeUnit.MILLISECONDS)); Timeout.of(Math.toIntExact(connectTimeout.toMillis()), TimeUnit.MILLISECONDS));
} }
if (!socketTimeout.isNegative()) { if (!socketTimeout.isNegative()) {
var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS); var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS);
connectionConfigBuilder.setSocketTimeout(soTimeout); connectionConfigBuilder.setSocketTimeout(soTimeout);
} else { } else {
connectionConfigBuilder.setSocketTimeout(Timeout.of(DEFAULT_SOCKET_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); connectionConfigBuilder.setSocketTimeout(Timeout.of(DEFAULT_SOCKET_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
} }
// add connectionConfig configurator callbacks provided by the configuration // add connectionConfig configurator callbacks provided by the configuration
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
.getClientConfigurers()) { .getClientConfigurers()) {
if (clientConfigurer instanceof ElasticsearchConnectionConfigurationCallback connectionConfigurationCallback) { if (clientConfigurer instanceof ElasticsearchConnectionConfigurationCallback connectionConfigurationCallback) {
connectionConfigBuilder = connectionConfigurationCallback.configure(connectionConfigBuilder); connectionConfigBuilder = connectionConfigurationCallback.configure(connectionConfigBuilder);
} }
} }
}); });
builder.setConnectionManagerCallback(poolingAsyncClientConnectionManagerBuilder -> { builder.setConnectionManagerCallback(poolingAsyncClientConnectionManagerBuilder -> {
SSLContext sslContext = null; SSLContext sslContext = null;
try { try {
sslContext = clientConfiguration.getCaFingerprint().isPresent() sslContext = clientConfiguration.getCaFingerprint().isPresent()
? TransportUtils.sslContextFromCaFingerprint(clientConfiguration.getCaFingerprint().get()) ? TransportUtils.sslContextFromCaFingerprint(clientConfiguration.getCaFingerprint().get())
: (clientConfiguration.getSslContext().isPresent() : (clientConfiguration.getSslContext().isPresent()
? clientConfiguration.getSslContext().get() ? clientConfiguration.getSslContext().get()
: SSLContext.getDefault()); : SSLContext.getDefault());
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("could not create the default ssl context", e); throw new IllegalStateException("could not create the default ssl context", e);
} }
poolingAsyncClientConnectionManagerBuilder.setTlsStrategy(new BasicClientTlsStrategy(sslContext)); poolingAsyncClientConnectionManagerBuilder.setTlsStrategy(new BasicClientTlsStrategy(sslContext));
// add connectionManager configurator callbacks provided by the configuration // add connectionManager configurator callbacks provided by the configuration
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
.getClientConfigurers()) { .getClientConfigurers()) {
if (clientConfigurer instanceof ElasticsearchConnectionManagerCallback connectionManagerCallback) { if (clientConfigurer instanceof ElasticsearchConnectionManagerCallback connectionManagerCallback) {
poolingAsyncClientConnectionManagerBuilder = connectionManagerCallback.configure(poolingAsyncClientConnectionManagerBuilder); poolingAsyncClientConnectionManagerBuilder = connectionManagerCallback
} .configure(poolingAsyncClientConnectionManagerBuilder);
} }
}); }
});
builder.setRequestConfigCallback(requestConfigBuilder -> { builder.setRequestConfigCallback(requestConfigBuilder -> {
if (!socketTimeout.isNegative()) { if (!socketTimeout.isNegative()) {
var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS); var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS);
requestConfigBuilder.setConnectionRequestTimeout(soTimeout); requestConfigBuilder.setConnectionRequestTimeout(soTimeout);
} else { } else {
requestConfigBuilder requestConfigBuilder
.setConnectionRequestTimeout(Timeout.of(DEFAULT_RESPONSE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); .setConnectionRequestTimeout(Timeout.of(DEFAULT_RESPONSE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
} }
// add connectionConfig configurator callbacks provided by the configuration // add connectionConfig configurator callbacks provided by the configuration
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
.getClientConfigurers()) { .getClientConfigurers()) {
if (clientConfigurer instanceof ElasticsearchRequestConfigCallback requestConfigCallback) { if (clientConfigurer instanceof ElasticsearchRequestConfigCallback requestConfigCallback) {
requestConfigBuilder = requestConfigCallback.configure(requestConfigBuilder); requestConfigBuilder = requestConfigCallback.configure(requestConfigBuilder);
} }
} }
}); });
return builder; return builder;
} }
private static HttpHost @NonNull [] getHttpHosts(ClientConfiguration clientConfiguration) { private static HttpHost @NonNull [] getHttpHosts(ClientConfiguration clientConfiguration) {
List<InetSocketAddress> hosts = clientConfiguration.getEndpoints(); List<InetSocketAddress> hosts = clientConfiguration.getEndpoints();
boolean useSsl = clientConfiguration.useSsl(); boolean useSsl = clientConfiguration.useSsl();
return hosts.stream() return hosts.stream()
.map(it -> (useSsl ? "https" : "http") + "://" + it.getHostString() + ':' + it.getPort()) .map(it -> (useSsl ? "https" : "http") + "://" + it.getHostString() + ':' + it.getPort())
.map(URI::create) .map(URI::create)
.map(HttpHost::create) .map(HttpHost::create)
.toArray(HttpHost[]::new); .toArray(HttpHost[]::new);
} }
private static Header[] toHeaderArray(HttpHeaders headers) { private static Header[] toHeaderArray(HttpHeaders headers) {
return headers.entrySet().stream() // return headers.entrySet().stream() //
.flatMap(entry -> entry.getValue().stream() // .flatMap(entry -> entry.getValue().stream() //
.map(value -> new BasicHeader(entry.getKey(), value))) // .map(value -> new BasicHeader(entry.getKey(), value))) //
.toList().toArray(new Header[0]); .toList().toArray(new Header[0]);
} }
/** /**
* {@link ClientConfiguration.ClientConfigurationCallback} to configure the Rest5Client client with a * {@link ClientConfiguration.ClientConfigurationCallback} to configure the Rest5Client client with a
* {@link Rest5ClientBuilder} * {@link Rest5ClientBuilder}
* *
* @since 6.0 * @since 6.0
*/ */
public interface ElasticsearchRest5ClientConfigurationCallback public interface ElasticsearchRest5ClientConfigurationCallback
extends ClientConfiguration.ClientConfigurationCallback<Rest5ClientBuilder> { extends ClientConfiguration.ClientConfigurationCallback<Rest5ClientBuilder> {
static ElasticsearchRest5ClientConfigurationCallback from( static ElasticsearchRest5ClientConfigurationCallback from(
Function<Rest5ClientBuilder, Rest5ClientBuilder> rest5ClientBuilderCallback) { Function<Rest5ClientBuilder, Rest5ClientBuilder> rest5ClientBuilderCallback) {
Assert.notNull(rest5ClientBuilderCallback, "rest5ClientBuilderCallback must not be null"); Assert.notNull(rest5ClientBuilderCallback, "rest5ClientBuilderCallback must not be null");
return rest5ClientBuilderCallback::apply; return rest5ClientBuilderCallback::apply;
} }
} }
/** /**
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure * {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
* the Elasticsearch Rest5Client's Http client with a {@link HttpAsyncClientBuilder} * the Elasticsearch Rest5Client's Http client with a {@link HttpAsyncClientBuilder}
* *
* @since 6.0 * @since 6.0
*/ */
public interface ElasticsearchHttpClientConfigurationCallback public interface ElasticsearchHttpClientConfigurationCallback
extends ClientConfiguration.ClientConfigurationCallback<HttpAsyncClientBuilder> { extends ClientConfiguration.ClientConfigurationCallback<HttpAsyncClientBuilder> {
static Rest5Clients.ElasticsearchHttpClientConfigurationCallback from( static Rest5Clients.ElasticsearchHttpClientConfigurationCallback from(
Function<HttpAsyncClientBuilder, HttpAsyncClientBuilder> httpClientBuilderCallback) { Function<HttpAsyncClientBuilder, HttpAsyncClientBuilder> httpClientBuilderCallback) {
Assert.notNull(httpClientBuilderCallback, "httpClientBuilderCallback must not be null"); Assert.notNull(httpClientBuilderCallback, "httpClientBuilderCallback must not be null");
return httpClientBuilderCallback::apply; return httpClientBuilderCallback::apply;
} }
} }
/** /**
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure * {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
* the Elasticsearch Rest5Client's connection with a {@link ConnectionConfig.Builder} * the Elasticsearch Rest5Client's connection with a {@link ConnectionConfig.Builder}
* *
* @since 6.0 * @since 6.0
*/ */
public interface ElasticsearchConnectionConfigurationCallback public interface ElasticsearchConnectionConfigurationCallback
extends ClientConfiguration.ClientConfigurationCallback<ConnectionConfig.Builder> { extends ClientConfiguration.ClientConfigurationCallback<ConnectionConfig.Builder> {
static ElasticsearchConnectionConfigurationCallback from( static ElasticsearchConnectionConfigurationCallback from(
Function<ConnectionConfig.Builder, ConnectionConfig.Builder> connectionConfigBuilderCallback) { Function<ConnectionConfig.Builder, ConnectionConfig.Builder> connectionConfigBuilderCallback) {
Assert.notNull(connectionConfigBuilderCallback, "connectionConfigBuilderCallback must not be null"); Assert.notNull(connectionConfigBuilderCallback, "connectionConfigBuilderCallback must not be null");
return connectionConfigBuilderCallback::apply; return connectionConfigBuilderCallback::apply;
} }
} }
/** /**
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure * {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
* the Elasticsearch Rest5Client's connection manager with a {@link PoolingAsyncClientConnectionManagerBuilder} * the Elasticsearch Rest5Client's connection manager with a {@link PoolingAsyncClientConnectionManagerBuilder}
* *
* @since 6.0 * @since 6.0
*/ */
public interface ElasticsearchConnectionManagerCallback public interface ElasticsearchConnectionManagerCallback
extends ClientConfiguration.ClientConfigurationCallback<PoolingAsyncClientConnectionManagerBuilder> { extends ClientConfiguration.ClientConfigurationCallback<PoolingAsyncClientConnectionManagerBuilder> {
static ElasticsearchConnectionManagerCallback from( static ElasticsearchConnectionManagerCallback from(
Function<PoolingAsyncClientConnectionManagerBuilder, PoolingAsyncClientConnectionManagerBuilder> connectionManagerBuilderCallback) { Function<PoolingAsyncClientConnectionManagerBuilder, PoolingAsyncClientConnectionManagerBuilder> connectionManagerBuilderCallback) {
Assert.notNull(connectionManagerBuilderCallback, "connectionManagerBuilderCallback must not be null"); Assert.notNull(connectionManagerBuilderCallback, "connectionManagerBuilderCallback must not be null");
return connectionManagerBuilderCallback::apply; return connectionManagerBuilderCallback::apply;
} }
} }
/** /**
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure * {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
* the Elasticsearch Rest5Client's connection manager with a {@link RequestConfig.Builder} * the Elasticsearch Rest5Client's connection manager with a {@link RequestConfig.Builder}
* *
* @since 6.0 * @since 6.0
*/ */
public interface ElasticsearchRequestConfigCallback public interface ElasticsearchRequestConfigCallback
extends ClientConfiguration.ClientConfigurationCallback<RequestConfig.Builder> { extends ClientConfiguration.ClientConfigurationCallback<RequestConfig.Builder> {
static ElasticsearchRequestConfigCallback from( static ElasticsearchRequestConfigCallback from(
Function<RequestConfig.Builder, RequestConfig.Builder> requestConfigBuilderCallback) { Function<RequestConfig.Builder, RequestConfig.Builder> requestConfigBuilderCallback) {
Assert.notNull(requestConfigBuilderCallback, "requestConfigBuilderCallback must not be null"); Assert.notNull(requestConfigBuilderCallback, "requestConfigBuilderCallback must not be null");
return requestConfigBuilderCallback::apply; return requestConfigBuilderCallback::apply;
} }
} }
public static Rest5ClientOptions.Builder getRest5ClientOptionsBuilder(@Nullable TransportOptions transportOptions) { public static Rest5ClientOptions.Builder getRest5ClientOptionsBuilder(@Nullable TransportOptions transportOptions) {
if (transportOptions instanceof Rest5ClientOptions rest5ClientOptions) { if (transportOptions instanceof Rest5ClientOptions rest5ClientOptions) {
return rest5ClientOptions.toBuilder(); return rest5ClientOptions.toBuilder();
} }
var builder = new Rest5ClientOptions.Builder(RequestOptions.DEFAULT.toBuilder()); var builder = new Rest5ClientOptions.Builder(RequestOptions.DEFAULT.toBuilder());
if (transportOptions != null) { if (transportOptions != null) {
transportOptions.headers().forEach(header -> builder.addHeader(header.getKey(), header.getValue())); transportOptions.headers().forEach(header -> builder.addHeader(header.getKey(), header.getValue()));
transportOptions.queryParameters().forEach(builder::setParameter); transportOptions.queryParameters().forEach(builder::setParameter);
builder.onWarnings(transportOptions.onWarnings()); builder.onWarnings(transportOptions.onWarnings());
} }
return builder; return builder;
} }
} }