From e49bb63df492f5bb86660d6ecdfd8aa2ae01b727 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 4 Aug 2025 20:50:47 +0200 Subject: [PATCH] Fix handling of ResponseException from legacy client dependency. Original Pull Request #3146 Closes #3144 Signed-off-by: Peter-Josef Meisch --- .../elc/ElasticsearchExceptionTranslator.java | 9 +- .../client/elc/ElasticsearchTemplate.java | 2 +- .../client/elc/rest5_client/Rest5Clients.java | 432 +++++++++--------- 3 files changed, 223 insertions(+), 220 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchExceptionTranslator.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchExceptionTranslator.java index 6f454e60b..929d8952e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchExceptionTranslator.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchExceptionTranslator.java @@ -24,6 +24,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.elasticsearch.client.ResponseException; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; 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.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.VersionConflictException; +import org.springframework.util.ClassUtils; /** * 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 static final boolean LEGACY_RESTCLIENT_PRESENT = ClassUtils + .isPresent("org.elasticsearch.client.ResponseException", ElasticsearchExceptionTranslator.class.getClassLoader()); + private final JsonpMapper jsonpMapper; public ElasticsearchExceptionTranslator(JsonpMapper jsonpMapper) { @@ -68,7 +73,7 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra } @Override - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { + public @Nullable DataAccessException translateExceptionIfPossible(RuntimeException ex) { checkForConflictException(ex); @@ -118,7 +123,7 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra Integer status = null; String message = null; - if (exception instanceof ResponseException responseException) { + if (LEGACY_RESTCLIENT_PRESENT && exception instanceof ResponseException responseException) { // this code is for the old RestClient status = responseException.getResponse().getStatusLine().getStatusCode(); message = responseException.getMessage(); diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchTemplate.java index 3e0d6235d..2ed185b97 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchTemplate.java @@ -658,7 +658,7 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate { QueryResponse response = sqlClient.query(requestConverter.sqlQueryRequest(query)); return responseConverter.sqlResponse(response); - } catch (IOException e) { + } catch (Exception e) { throw exceptionTranslator.translateException(e); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/rest5_client/Rest5Clients.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/rest5_client/Rest5Clients.java index 885083a5f..22d60a9cc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/rest5_client/Rest5Clients.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/rest5_client/Rest5Clients.java @@ -32,7 +32,6 @@ import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.support.HttpHeaders; -import org.springframework.data.elasticsearch.support.VersionInfo; import org.springframework.util.Assert; /** @@ -42,269 +41,268 @@ import org.springframework.util.Assert; */ public final class Rest5Clients { - // values copied from Rest5ClientBuilder - public static final int DEFAULT_SOCKET_TIMEOUT_MILLIS = 30000; - public static final int DEFAULT_RESPONSE_TIMEOUT_MILLIS = 0; // meaning infinite + // values copied from Rest5ClientBuilder + public static final int DEFAULT_SOCKET_TIMEOUT_MILLIS = 30000; + 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. - * - * @param clientConfiguration must not be {@literal null} - * @return the {@link Rest5Client} - */ - public static Rest5Client getRest5Client(ClientConfiguration clientConfiguration) { - return getRest5ClientBuilder(clientConfiguration).build(); - } + /** + * Creates a low level {@link Rest5Client} for the given configuration. + * + * @param clientConfiguration must not be {@literal null} + * @return the {@link Rest5Client} + */ + public static Rest5Client getRest5Client(ClientConfiguration clientConfiguration) { + return getRest5ClientBuilder(clientConfiguration).build(); + } - private static Rest5ClientBuilder getRest5ClientBuilder(ClientConfiguration clientConfiguration) { + private static Rest5ClientBuilder getRest5ClientBuilder(ClientConfiguration clientConfiguration) { - HttpHost[] httpHosts = getHttpHosts(clientConfiguration); - Rest5ClientBuilder builder = Rest5Client.builder(httpHosts); + HttpHost[] httpHosts = getHttpHosts(clientConfiguration); + Rest5ClientBuilder builder = Rest5Client.builder(httpHosts); - if (clientConfiguration.getPathPrefix() != null) { - builder.setPathPrefix(clientConfiguration.getPathPrefix()); - } + if (clientConfiguration.getPathPrefix() != null) { + builder.setPathPrefix(clientConfiguration.getPathPrefix()); + } - HttpHeaders headers = clientConfiguration.getDefaultHeaders(); + HttpHeaders headers = clientConfiguration.getDefaultHeaders(); - if (!headers.isEmpty()) { - builder.setDefaultHeaders(toHeaderArray(headers)); - } + if (!headers.isEmpty()) { + builder.setDefaultHeaders(toHeaderArray(headers)); + } - // RestClientBuilder configuration callbacks from the consumer - for (ClientConfiguration.ClientConfigurationCallback clientConfigurationCallback : clientConfiguration - .getClientConfigurers()) { - if (clientConfigurationCallback instanceof ElasticsearchRest5ClientConfigurationCallback configurationCallback) { - builder = configurationCallback.configure(builder); - } - } + // RestClientBuilder configuration callbacks from the consumer + for (ClientConfiguration.ClientConfigurationCallback clientConfigurationCallback : clientConfiguration + .getClientConfigurers()) { + if (clientConfigurationCallback instanceof ElasticsearchRest5ClientConfigurationCallback configurationCallback) { + builder = configurationCallback.configure(builder); + } + } - Duration connectTimeout = clientConfiguration.getConnectTimeout(); - Duration socketTimeout = clientConfiguration.getSocketTimeout(); + Duration connectTimeout = clientConfiguration.getConnectTimeout(); + Duration socketTimeout = clientConfiguration.getSocketTimeout(); - builder.setHttpClientConfigCallback(httpAsyncClientBuilder -> { + builder.setHttpClientConfigCallback(httpAsyncClientBuilder -> { - httpAsyncClientBuilder.setUserAgent(VersionInfo.clientVersions()); - if (clientConfiguration.getProxy().isPresent()) { - var proxy = clientConfiguration.getProxy().get(); - try { - var proxyRoutePlanner = new DefaultProxyRoutePlanner(HttpHost.create(proxy)); - httpAsyncClientBuilder.setRoutePlanner(proxyRoutePlanner); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } - httpAsyncClientBuilder.addRequestInterceptorFirst((request, entity, context) -> { - clientConfiguration.getHeadersSupplier().get().forEach((header, values) -> { - // The accept and content-type headers are already put on the request, despite this being the first - // interceptor. - if ("Accept".equalsIgnoreCase(header) || " Content-Type".equalsIgnoreCase(header)) { - request.removeHeaders(header); - } - values.forEach(value -> request.addHeader(header, value)); - }); - }); + if (clientConfiguration.getProxy().isPresent()) { + var proxy = clientConfiguration.getProxy().get(); + try { + var proxyRoutePlanner = new DefaultProxyRoutePlanner(HttpHost.create(proxy)); + httpAsyncClientBuilder.setRoutePlanner(proxyRoutePlanner); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + httpAsyncClientBuilder.addRequestInterceptorFirst((request, entity, context) -> { + clientConfiguration.getHeadersSupplier().get().forEach((header, values) -> { + // The accept and content-type headers are already put on the request, despite this being the first + // interceptor. + if ("Accept".equalsIgnoreCase(header) || " Content-Type".equalsIgnoreCase(header)) { + request.removeHeaders(header); + } + values.forEach(value -> request.addHeader(header, value)); + }); + }); - // add httpclient configurator callbacks provided by the configuration - for (ClientConfiguration.ClientConfigurationCallback clientConfigurer : clientConfiguration - .getClientConfigurers()) { - if (clientConfigurer instanceof ElasticsearchHttpClientConfigurationCallback httpClientConfigurer) { - httpAsyncClientBuilder = httpClientConfigurer.configure(httpAsyncClientBuilder); - } - } - }); + // add httpclient configurator callbacks provided by the configuration + for (ClientConfiguration.ClientConfigurationCallback clientConfigurer : clientConfiguration + .getClientConfigurers()) { + if (clientConfigurer instanceof ElasticsearchHttpClientConfigurationCallback httpClientConfigurer) { + httpAsyncClientBuilder = httpClientConfigurer.configure(httpAsyncClientBuilder); + } + } + }); - builder.setConnectionConfigCallback(connectionConfigBuilder -> { + builder.setConnectionConfigCallback(connectionConfigBuilder -> { - if (!connectTimeout.isNegative()) { - connectionConfigBuilder.setConnectTimeout( - Timeout.of(Math.toIntExact(connectTimeout.toMillis()), TimeUnit.MILLISECONDS)); - } - if (!socketTimeout.isNegative()) { - var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS); - connectionConfigBuilder.setSocketTimeout(soTimeout); - } else { - connectionConfigBuilder.setSocketTimeout(Timeout.of(DEFAULT_SOCKET_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); - } + if (!connectTimeout.isNegative()) { + connectionConfigBuilder.setConnectTimeout( + Timeout.of(Math.toIntExact(connectTimeout.toMillis()), TimeUnit.MILLISECONDS)); + } + if (!socketTimeout.isNegative()) { + var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS); + connectionConfigBuilder.setSocketTimeout(soTimeout); + } else { + connectionConfigBuilder.setSocketTimeout(Timeout.of(DEFAULT_SOCKET_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); + } - // add connectionConfig configurator callbacks provided by the configuration - for (ClientConfiguration.ClientConfigurationCallback clientConfigurer : clientConfiguration - .getClientConfigurers()) { - if (clientConfigurer instanceof ElasticsearchConnectionConfigurationCallback connectionConfigurationCallback) { - connectionConfigBuilder = connectionConfigurationCallback.configure(connectionConfigBuilder); - } - } - }); + // add connectionConfig configurator callbacks provided by the configuration + for (ClientConfiguration.ClientConfigurationCallback clientConfigurer : clientConfiguration + .getClientConfigurers()) { + if (clientConfigurer instanceof ElasticsearchConnectionConfigurationCallback connectionConfigurationCallback) { + connectionConfigBuilder = connectionConfigurationCallback.configure(connectionConfigBuilder); + } + } + }); - builder.setConnectionManagerCallback(poolingAsyncClientConnectionManagerBuilder -> { + builder.setConnectionManagerCallback(poolingAsyncClientConnectionManagerBuilder -> { - SSLContext sslContext = null; - try { - sslContext = clientConfiguration.getCaFingerprint().isPresent() - ? TransportUtils.sslContextFromCaFingerprint(clientConfiguration.getCaFingerprint().get()) - : (clientConfiguration.getSslContext().isPresent() - ? clientConfiguration.getSslContext().get() - : SSLContext.getDefault()); - } catch (NoSuchAlgorithmException e) { - throw new IllegalStateException("could not create the default ssl context", e); - } - poolingAsyncClientConnectionManagerBuilder.setTlsStrategy(new BasicClientTlsStrategy(sslContext)); + SSLContext sslContext = null; + try { + sslContext = clientConfiguration.getCaFingerprint().isPresent() + ? TransportUtils.sslContextFromCaFingerprint(clientConfiguration.getCaFingerprint().get()) + : (clientConfiguration.getSslContext().isPresent() + ? clientConfiguration.getSslContext().get() + : SSLContext.getDefault()); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("could not create the default ssl context", e); + } + poolingAsyncClientConnectionManagerBuilder.setTlsStrategy(new BasicClientTlsStrategy(sslContext)); - // add connectionManager configurator callbacks provided by the configuration - for (ClientConfiguration.ClientConfigurationCallback clientConfigurer : clientConfiguration - .getClientConfigurers()) { - if (clientConfigurer instanceof ElasticsearchConnectionManagerCallback connectionManagerCallback) { - poolingAsyncClientConnectionManagerBuilder = connectionManagerCallback.configure(poolingAsyncClientConnectionManagerBuilder); - } - } - }); + // add connectionManager configurator callbacks provided by the configuration + for (ClientConfiguration.ClientConfigurationCallback clientConfigurer : clientConfiguration + .getClientConfigurers()) { + if (clientConfigurer instanceof ElasticsearchConnectionManagerCallback connectionManagerCallback) { + poolingAsyncClientConnectionManagerBuilder = connectionManagerCallback + .configure(poolingAsyncClientConnectionManagerBuilder); + } + } + }); - builder.setRequestConfigCallback(requestConfigBuilder -> { + builder.setRequestConfigCallback(requestConfigBuilder -> { - if (!socketTimeout.isNegative()) { - var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS); - requestConfigBuilder.setConnectionRequestTimeout(soTimeout); - } else { - requestConfigBuilder - .setConnectionRequestTimeout(Timeout.of(DEFAULT_RESPONSE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); - } - // add connectionConfig configurator callbacks provided by the configuration - for (ClientConfiguration.ClientConfigurationCallback clientConfigurer : clientConfiguration - .getClientConfigurers()) { - if (clientConfigurer instanceof ElasticsearchRequestConfigCallback requestConfigCallback) { - requestConfigBuilder = requestConfigCallback.configure(requestConfigBuilder); - } - } - }); + if (!socketTimeout.isNegative()) { + var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS); + requestConfigBuilder.setConnectionRequestTimeout(soTimeout); + } else { + requestConfigBuilder + .setConnectionRequestTimeout(Timeout.of(DEFAULT_RESPONSE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); + } + // add connectionConfig configurator callbacks provided by the configuration + for (ClientConfiguration.ClientConfigurationCallback clientConfigurer : clientConfiguration + .getClientConfigurers()) { + if (clientConfigurer instanceof ElasticsearchRequestConfigCallback requestConfigCallback) { + requestConfigBuilder = requestConfigCallback.configure(requestConfigBuilder); + } + } + }); - return builder; - } + return builder; + } - private static HttpHost @NonNull [] getHttpHosts(ClientConfiguration clientConfiguration) { - List hosts = clientConfiguration.getEndpoints(); - boolean useSsl = clientConfiguration.useSsl(); - return hosts.stream() - .map(it -> (useSsl ? "https" : "http") + "://" + it.getHostString() + ':' + it.getPort()) - .map(URI::create) - .map(HttpHost::create) - .toArray(HttpHost[]::new); - } + private static HttpHost @NonNull [] getHttpHosts(ClientConfiguration clientConfiguration) { + List hosts = clientConfiguration.getEndpoints(); + boolean useSsl = clientConfiguration.useSsl(); + return hosts.stream() + .map(it -> (useSsl ? "https" : "http") + "://" + it.getHostString() + ':' + it.getPort()) + .map(URI::create) + .map(HttpHost::create) + .toArray(HttpHost[]::new); + } - private static Header[] toHeaderArray(HttpHeaders headers) { - return headers.entrySet().stream() // - .flatMap(entry -> entry.getValue().stream() // - .map(value -> new BasicHeader(entry.getKey(), value))) // - .toList().toArray(new Header[0]); - } + private static Header[] toHeaderArray(HttpHeaders headers) { + return headers.entrySet().stream() // + .flatMap(entry -> entry.getValue().stream() // + .map(value -> new BasicHeader(entry.getKey(), value))) // + .toList().toArray(new Header[0]); + } - /** - * {@link ClientConfiguration.ClientConfigurationCallback} to configure the Rest5Client client with a - * {@link Rest5ClientBuilder} - * - * @since 6.0 - */ - public interface ElasticsearchRest5ClientConfigurationCallback - extends ClientConfiguration.ClientConfigurationCallback { + /** + * {@link ClientConfiguration.ClientConfigurationCallback} to configure the Rest5Client client with a + * {@link Rest5ClientBuilder} + * + * @since 6.0 + */ + public interface ElasticsearchRest5ClientConfigurationCallback + extends ClientConfiguration.ClientConfigurationCallback { - static ElasticsearchRest5ClientConfigurationCallback from( - Function rest5ClientBuilderCallback) { + static ElasticsearchRest5ClientConfigurationCallback from( + Function 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 - * the Elasticsearch Rest5Client's Http client with a {@link HttpAsyncClientBuilder} - * - * @since 6.0 - */ - public interface ElasticsearchHttpClientConfigurationCallback - extends ClientConfiguration.ClientConfigurationCallback { + /** + * {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure + * the Elasticsearch Rest5Client's Http client with a {@link HttpAsyncClientBuilder} + * + * @since 6.0 + */ + public interface ElasticsearchHttpClientConfigurationCallback + extends ClientConfiguration.ClientConfigurationCallback { - static Rest5Clients.ElasticsearchHttpClientConfigurationCallback from( - Function httpClientBuilderCallback) { + static Rest5Clients.ElasticsearchHttpClientConfigurationCallback from( + Function 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 - * the Elasticsearch Rest5Client's connection with a {@link ConnectionConfig.Builder} - * - * @since 6.0 - */ - public interface ElasticsearchConnectionConfigurationCallback - extends ClientConfiguration.ClientConfigurationCallback { + /** + * {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure + * the Elasticsearch Rest5Client's connection with a {@link ConnectionConfig.Builder} + * + * @since 6.0 + */ + public interface ElasticsearchConnectionConfigurationCallback + extends ClientConfiguration.ClientConfigurationCallback { - static ElasticsearchConnectionConfigurationCallback from( - Function connectionConfigBuilderCallback) { + static ElasticsearchConnectionConfigurationCallback from( + Function 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 - * the Elasticsearch Rest5Client's connection manager with a {@link PoolingAsyncClientConnectionManagerBuilder} - * - * @since 6.0 - */ - public interface ElasticsearchConnectionManagerCallback - extends ClientConfiguration.ClientConfigurationCallback { + /** + * {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure + * the Elasticsearch Rest5Client's connection manager with a {@link PoolingAsyncClientConnectionManagerBuilder} + * + * @since 6.0 + */ + public interface ElasticsearchConnectionManagerCallback + extends ClientConfiguration.ClientConfigurationCallback { - static ElasticsearchConnectionManagerCallback from( - Function connectionManagerBuilderCallback) { + static ElasticsearchConnectionManagerCallback from( + Function 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 - * the Elasticsearch Rest5Client's connection manager with a {@link RequestConfig.Builder} - * - * @since 6.0 - */ - public interface ElasticsearchRequestConfigCallback - extends ClientConfiguration.ClientConfigurationCallback { + /** + * {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure + * the Elasticsearch Rest5Client's connection manager with a {@link RequestConfig.Builder} + * + * @since 6.0 + */ + public interface ElasticsearchRequestConfigCallback + extends ClientConfiguration.ClientConfigurationCallback { - static ElasticsearchRequestConfigCallback from( - Function requestConfigBuilderCallback) { + static ElasticsearchRequestConfigCallback from( + Function 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) { - return rest5ClientOptions.toBuilder(); - } + if (transportOptions instanceof Rest5ClientOptions rest5ClientOptions) { + return rest5ClientOptions.toBuilder(); + } - var builder = new Rest5ClientOptions.Builder(RequestOptions.DEFAULT.toBuilder()); + var builder = new Rest5ClientOptions.Builder(RequestOptions.DEFAULT.toBuilder()); - if (transportOptions != null) { - transportOptions.headers().forEach(header -> builder.addHeader(header.getKey(), header.getValue())); - transportOptions.queryParameters().forEach(builder::setParameter); - builder.onWarnings(transportOptions.onWarnings()); - } + if (transportOptions != null) { + transportOptions.headers().forEach(header -> builder.addHeader(header.getKey(), header.getValue())); + transportOptions.queryParameters().forEach(builder::setParameter); + builder.onWarnings(transportOptions.onWarnings()); + } - return builder; - } + return builder; + } }