From 506faf8a613e7c4438668ea2897248b969ac45ba Mon Sep 17 00:00:00 2001 From: Rob Rudin Date: Fri, 19 Sep 2025 15:19:45 -0400 Subject: [PATCH] MLE-23230 Applying RetryInterceptor in test plumbing This avoids hardcoding it in the actual client and let's us still see the results for the tests. Also fixed a warning from Polaris about the interceptor. --- .../client/functionaltest/ConnectedRESTQA.java | 8 ++++++++ .../com/marklogic/client/impl/okhttp/OkHttpUtil.java | 3 --- .../marklogic/client/impl/okhttp/RetryInterceptor.java | 10 ++++------ .../test/java/com/marklogic/client/test/Common.java | 9 +++++++++ 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/functionaltest/ConnectedRESTQA.java b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/functionaltest/ConnectedRESTQA.java index 40c6e17d5..52f1d743f 100644 --- a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/functionaltest/ConnectedRESTQA.java +++ b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/functionaltest/ConnectedRESTQA.java @@ -15,7 +15,9 @@ import com.marklogic.client.DatabaseClientFactory; import com.marklogic.client.FailedRequestException; import com.marklogic.client.admin.ServerConfigurationManager; +import com.marklogic.client.extra.okhttpclient.OkHttpClientConfigurator; import com.marklogic.client.impl.SSLUtil; +import com.marklogic.client.impl.okhttp.RetryInterceptor; import com.marklogic.client.io.DocumentMetadataHandle; import com.marklogic.client.io.DocumentMetadataHandle.Capability; import com.marklogic.client.query.QueryManager; @@ -45,6 +47,12 @@ public abstract class ConnectedRESTQA { + static { + DatabaseClientFactory.removeConfigurators(); + DatabaseClientFactory.addConfigurator((OkHttpClientConfigurator) client -> + client.addInterceptor(new RetryInterceptor(3, 1000, 2, 8000))); + } + private static Properties testProperties = null; private static String authType; diff --git a/marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/OkHttpUtil.java b/marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/OkHttpUtil.java index 93a273db8..3dff7a53d 100644 --- a/marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/OkHttpUtil.java +++ b/marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/OkHttpUtil.java @@ -78,9 +78,6 @@ public static OkHttpClient.Builder newOkHttpClientBuilder(String host, DatabaseC OkHttpUtil.configureSocketFactory(clientBuilder, sslContext, trustManager); OkHttpUtil.configureHostnameVerifier(clientBuilder, sslVerifier); - // Trying this out for all calls initially to see how the regression test piplines do. - clientBuilder.addInterceptor(new RetryInterceptor(3, 1000, 2, 8000)); - return clientBuilder; } diff --git a/marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/RetryInterceptor.java b/marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/RetryInterceptor.java index eeaaf0294..dd6879a53 100644 --- a/marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/RetryInterceptor.java +++ b/marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/RetryInterceptor.java @@ -17,7 +17,7 @@ * OkHttp interceptor that retries requests on certain connection failures, * which can be helpful when MarkLogic is temporarily unavailable during restarts. */ -class RetryInterceptor implements Interceptor { +public class RetryInterceptor implements Interceptor { private final static Logger logger = org.slf4j.LoggerFactory.getLogger(RetryInterceptor.class); @@ -26,7 +26,7 @@ class RetryInterceptor implements Interceptor { private final double backoffMultiplier; private final long maxDelayMs; - RetryInterceptor(int maxRetries, long initialDelayMs, double backoffMultiplier, long maxDelayMs) { + public RetryInterceptor(int maxRetries, long initialDelayMs, double backoffMultiplier, long maxDelayMs) { this.maxRetries = maxRetries; this.initialDelayMs = initialDelayMs; this.backoffMultiplier = backoffMultiplier; @@ -36,14 +36,11 @@ class RetryInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); - IOException lastException = null; for (int attempt = 0; attempt <= maxRetries; attempt++) { try { return chain.proceed(request); } catch (IOException e) { - lastException = e; - if (attempt == maxRetries || !isRetryableException(e)) { logger.warn("Not retryable: {}; {}", e.getClass(), e.getMessage()); throw e; @@ -57,7 +54,8 @@ public Response intercept(Chain chain) throws IOException { } } - throw lastException; + // This should never be reached due to loop logic, but is required for compilation. + throw new IllegalStateException("Unexpected end of retry loop"); } private boolean isRetryableException(IOException e) { diff --git a/marklogic-client-api/src/test/java/com/marklogic/client/test/Common.java b/marklogic-client-api/src/test/java/com/marklogic/client/test/Common.java index bf2d51a47..9b11eee9d 100644 --- a/marklogic-client-api/src/test/java/com/marklogic/client/test/Common.java +++ b/marklogic-client-api/src/test/java/com/marklogic/client/test/Common.java @@ -8,9 +8,12 @@ import com.marklogic.client.DatabaseClient; import com.marklogic.client.DatabaseClientBuilder; import com.marklogic.client.DatabaseClientFactory; +import com.marklogic.client.extra.okhttpclient.OkHttpClientConfigurator; +import com.marklogic.client.impl.okhttp.RetryInterceptor; import com.marklogic.client.io.DocumentMetadataHandle; import com.marklogic.mgmt.ManageClient; import com.marklogic.mgmt.ManageConfig; +import okhttp3.OkHttpClient; import org.springframework.util.FileCopyUtils; import org.w3c.dom.DOMException; import org.w3c.dom.Document; @@ -29,6 +32,12 @@ public class Common { + static { + DatabaseClientFactory.removeConfigurators(); + DatabaseClientFactory.addConfigurator((OkHttpClientConfigurator) client -> + client.addInterceptor(new RetryInterceptor(3, 1000, 2, 8000))); + } + final public static String USER = "rest-writer"; final public static String PASS = "x"; final public static String REST_ADMIN_USER = "rest-admin";