Skip to content

Commit

Permalink
2408 Allow retries to be enabled on default Apache HTTP client
Browse files Browse the repository at this point in the history
  • Loading branch information
krystiansola committed Oct 2, 2023
1 parent 4b6b53c commit edafb4a
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2278,6 +2278,7 @@ You can adjust configuration settings for the HTTP client used by Karate using t
`abortSuiteOnFailure` | boolean | defaults to `false`, to not attempt to run any more tests upon a failure
`ntlmAuth` | JSON | See [NTLM Authentication](#ntlm-authentication)
`matchEachEmptyAllowed` | boolean | defaults to `false`, [`match each`](#match-each) by default expects the array to be non-empty, refer to [this issue](https://github.com/karatelabs/karate/issues/2364) to understand why you may want to over-ride this.
`httpRetryEnabled` | boolean | defaults to `false`, retry when the http requests fails with an exception `org.apache.httpNoHttpResponseException`. For details see [this issue](https://github.com/karatelabs/karate/issues/2408)

Examples:
```cucumber
Expand Down
12 changes: 12 additions & 0 deletions karate-core/src/main/java/com/intuit/karate/core/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ public class Config {

// ntlm authentication
private boolean ntlmEnabled = false;
private boolean httpRetryEnabled = false;
private String ntlmUsername;
private String ntlmPassword;
private String ntlmDomain;
Expand Down Expand Up @@ -383,6 +384,7 @@ public Config(Config parent) {
imageComparisonOptions = parent.imageComparisonOptions;
matchEachEmptyAllowed = parent.matchEachEmptyAllowed;
ntlmEnabled = parent.ntlmEnabled;
httpRetryEnabled = parent.httpRetryEnabled;
ntlmUsername = parent.ntlmUsername;
ntlmPassword = parent.ntlmPassword;
ntlmDomain = parent.ntlmDomain;
Expand Down Expand Up @@ -513,6 +515,12 @@ public boolean isPrintEnabled() {
return printEnabled;
}

public boolean isHttpRetryEnabled()
{
return httpRetryEnabled;
}


public Map<String, Map<String, Object>> getCustomOptions() {
return customOptions;
}
Expand Down Expand Up @@ -665,4 +673,8 @@ public void setNtlmWorkstation(String ntlmWorkstation) {
this.ntlmWorkstation = ntlmWorkstation;
}

public void setHttpRetryEnabled(boolean httpRetryEnabled)
{
this.httpRetryEnabled = httpRetryEnabled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,12 @@ public ApacheHttpClient(ScenarioEngine engine) {

private void configure(Config config) {
clientBuilder = HttpClientBuilder.create();
clientBuilder.disableAutomaticRetries();
if (config.isHttpRetryEnabled()) {
clientBuilder.setRetryHandler(new CustomHttpRequestRetryHandler(logger));
} else {
clientBuilder.disableAutomaticRetries();
}

if (!config.isFollowRedirects()) {
clientBuilder.disableRedirectHandling();
} else { // support redirect on POST by default
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.intuit.karate.http;

import java.io.IOException;

import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.protocol.HttpContext;

import com.intuit.karate.Logger;

/**
* Calls will retry the call when the client throws a NoHttpResponseException.
* This is usually the case when there is steal connection. The retry cause that
* the connection is renewed and the second call will succeed.
*/
public class CustomHttpRequestRetryHandler implements HttpRequestRetryHandler
{
private final Logger logger;

public CustomHttpRequestRetryHandler(Logger logger)
{
this.logger = logger;
}

@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context)
{
if (exception instanceof NoHttpResponseException && executionCount < 1)
{
logger.error("Thrown an NoHttpResponseException retry...");
return true;
}
else
{
logger.error("Thrown an exception {}", exception.getMessage());
return false;
}
}
}

0 comments on commit edafb4a

Please sign in to comment.