Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing retry logic to restTemplate #17375

Merged
merged 13 commits into from
Dec 12, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -436,4 +436,8 @@ public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case,

public static final String GENERATE_MARSHAL_JSON = "generateMarshalJSON";
public static final String GENERATE_MARSHAL_JSON_DESC = "Generate MarshalJSON method";

public static final String MAX_ATTEMPTS_FOR_RETRY = "maxAttemptsForRetry";

public static final String WAIT_TIME_OF_THREAD = "waitTimeMillis";
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ public class JavaClientCodegen extends AbstractJavaCodegen
protected boolean generateClientAsBean = false;
protected boolean useEnumCaseInsensitive = false;

protected int maxAttemptsForRetry = 1;
protected long waitTimeMillis = 10l;

private static class MpRestClientVersion {
public final String rootPackage;
public final String pomTemplate;
Expand Down Expand Up @@ -465,6 +468,20 @@ public void processOpts() {
if (additionalProperties.containsKey(USE_ENUM_CASE_INSENSITIVE)) {
this.setUseEnumCaseInsensitive(Boolean.parseBoolean(additionalProperties.get(USE_ENUM_CASE_INSENSITIVE).toString()));
}

if (additionalProperties.containsKey(CodegenConstants.MAX_ATTEMPTS_FOR_RETRY)) {
this.setMaxAttemptsForRetry(Integer.parseInt(additionalProperties.get(CodegenConstants.MAX_ATTEMPTS_FOR_RETRY).toString()));
}
else {
additionalProperties.put(CodegenConstants.MAX_ATTEMPTS_FOR_RETRY, maxAttemptsForRetry);
}

if (additionalProperties.containsKey(CodegenConstants.WAIT_TIME_OF_THREAD)) {
this.setWaitTimeMillis(Long.parseLong((additionalProperties.get(CodegenConstants.WAIT_TIME_OF_THREAD).toString())));
}
else {
additionalProperties.put(CodegenConstants.WAIT_TIME_OF_THREAD, waitTimeMillis);
}
writePropertyBack(USE_ENUM_CASE_INSENSITIVE, useEnumCaseInsensitive);

final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/");
Expand Down Expand Up @@ -1240,6 +1257,14 @@ public void setUseEnumCaseInsensitive(boolean useEnumCaseInsensitive) {
this.useEnumCaseInsensitive = useEnumCaseInsensitive;
}

public void setMaxAttemptsForRetry(int maxAttemptsForRetry) {
this.maxAttemptsForRetry= maxAttemptsForRetry;
}

public void setWaitTimeMillis(long waitTimeMillis) {
this.waitTimeMillis= waitTimeMillis;
}

/**
* Serialization library.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
Expand Down Expand Up @@ -105,6 +106,10 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
private HttpHeaders defaultHeaders = new HttpHeaders();
private MultiValueMap<String, String> defaultCookies = new LinkedMultiValueMap<String, String>();

private int maxAttemptsForRetry = {{maxAttemptsForRetry}};

private long waitTimeMillis = {{waitTimeMillis}};

private String basePath = "{{basePath}}";

private RestTemplate restTemplate;
Expand Down Expand Up @@ -167,6 +172,46 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return this;
}

/**
* Get the max attempts for retry
*
* @return int the max attempts
*/
public int getMaxAttemptsForRetry() {
return maxAttemptsForRetry;
}

/**
* Set the max attempts for retry
*
* @param getMaxAttemptsForRetry the max attempts for retry
* @return ApiClient this client
*/
public ApiClient setMaxAttemptsForRetry(int maxAttemptsForRetry) {
this.maxAttemptsForRetry = maxAttemptsForRetry;
return this;
}

/**
* Get the wait time in milliseconds
*
* @return long wait time in milliseconds
*/
public long getWaitTimeMillis() {
return waitTimeMillis;
}

/**
* Set the wait time in milliseconds
*
* @param waitTimeMillis the wait time in milliseconds
* @return ApiClient this client
*/
public ApiClient setWaitTimeMillis(long waitTimeMillis) {
this.waitTimeMillis = waitTimeMillis;
return this;
}

/**
* Get authentications (key: authentication name, value: authentication).
*
Expand Down Expand Up @@ -721,7 +766,23 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {

RequestEntity<Object> requestEntity = requestBuilder.body(selectBody(body, formParams, contentType));

ResponseEntity<T> responseEntity = restTemplate.exchange(requestEntity, returnType);
ResponseEntity<T> responseEntity = null;
int attempts = 0;
while (attempts < maxAttemptsForRetry) {
try {
responseEntity = restTemplate.exchange(requestEntity, returnType);
break;
} catch (HttpServerErrorException ex) {
rubiniselvaraj marked this conversation as resolved.
Show resolved Hide resolved
attempts++;
if (attempts < maxAttemptsForRetry) {
try {
Thread.sleep(waitTimeMillis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}

if (responseEntity.getStatusCode().is2xxSuccessful()) {
return responseEntity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
Expand Down Expand Up @@ -79,6 +80,10 @@ private String collectionToString(Collection<?> collection) {
private HttpHeaders defaultHeaders = new HttpHeaders();
private MultiValueMap<String, String> defaultCookies = new LinkedMultiValueMap<String, String>();

private int maxAttemptsForRetry = 1;

private long waitTimeMillis = 10;

private String basePath = "http://localhost:3000";

private RestTemplate restTemplate;
Expand Down Expand Up @@ -136,6 +141,46 @@ public ApiClient setBasePath(String basePath) {
return this;
}

/**
* Get the max attempts for retry
*
* @return int the max attempts
*/
public int getMaxAttemptsForRetry() {
return maxAttemptsForRetry;
}

/**
* Set the max attempts for retry
*
* @param getMaxAttemptsForRetry the max attempts for retry
* @return ApiClient this client
*/
public ApiClient setMaxAttemptsForRetry(int maxAttemptsForRetry) {
this.maxAttemptsForRetry = maxAttemptsForRetry;
return this;
}

/**
* Get the wait time in milliseconds
*
* @return long wait time in milliseconds
*/
public long getWaitTimeMillis() {
return waitTimeMillis;
}

/**
* Set the wait time in milliseconds
*
* @param waitTimeMillis the wait time in milliseconds
* @return ApiClient this client
*/
public ApiClient setWaitTimeMillis(long waitTimeMillis) {
this.waitTimeMillis = waitTimeMillis;
return this;
}

/**
* Get authentications (key: authentication name, value: authentication).
*
Expand Down Expand Up @@ -637,7 +682,23 @@ public <T> ResponseEntity<T> invokeAPI(String path, HttpMethod method, Map<Strin

RequestEntity<Object> requestEntity = requestBuilder.body(selectBody(body, formParams, contentType));

ResponseEntity<T> responseEntity = restTemplate.exchange(requestEntity, returnType);
ResponseEntity<T> responseEntity = null;
int attempts = 0;
while (attempts < maxAttemptsForRetry) {
try {
responseEntity = restTemplate.exchange(requestEntity, returnType);
break;
} catch (HttpServerErrorException ex) {
attempts++;
if (attempts < maxAttemptsForRetry) {
try {
Thread.sleep(waitTimeMillis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}

if (responseEntity.getStatusCode().is2xxSuccessful()) {
return responseEntity;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Echo Server API
* Echo Server API
*
* The version of the OpenAPI document: 0.1.0
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/


package org.openapitools.client;

import org.junit.Assert;
import org.openapitools.client.api.*;
import org.openapitools.client.model.*;
import org.junit.Test;
import org.junit.Ignore;

import java.io.IOException;
import java.util.*;


/**
* API tests
*/
public class CustomTest {

private final QueryApi api = new QueryApi();
private final BodyApi bodyApi = new BodyApi();

/**
* Test body parameter(s)
* <p>
* Test body parameter(s)
*
*/
@Test
public void testEchoBodyPet() {
Pet pet = new Pet().id(12345L).name("Hello World").
photoUrls(Arrays.asList(new String[]{"http://a.com", "http://b.com"})).category(new Category().id(987L).name("new category"));

Pet p = bodyApi.testEchoBodyPet(pet);
Assert.assertNotNull(p);
Assert.assertEquals("Hello World", p.getName());
Assert.assertEquals(Long.valueOf(12345L), p.getId());

// response is empty body
Pet p2 = bodyApi.testEchoBodyPet(null);
Assert.assertNull(p2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
Expand Down Expand Up @@ -77,6 +78,10 @@ private String collectionToString(Collection<?> collection) {
private HttpHeaders defaultHeaders = new HttpHeaders();
private MultiValueMap<String, String> defaultCookies = new LinkedMultiValueMap<String, String>();

private int maxAttemptsForRetry = 1;

private long waitTimeMillis = 10;

private String basePath = "http://localhost";

private RestTemplate restTemplate;
Expand Down Expand Up @@ -132,6 +137,46 @@ public ApiClient setBasePath(String basePath) {
return this;
}

/**
* Get the max attempts for retry
*
* @return int the max attempts
*/
public int getMaxAttemptsForRetry() {
return maxAttemptsForRetry;
}

/**
* Set the max attempts for retry
*
* @param getMaxAttemptsForRetry the max attempts for retry
* @return ApiClient this client
*/
public ApiClient setMaxAttemptsForRetry(int maxAttemptsForRetry) {
this.maxAttemptsForRetry = maxAttemptsForRetry;
return this;
}

/**
* Get the wait time in milliseconds
*
* @return long wait time in milliseconds
*/
public long getWaitTimeMillis() {
return waitTimeMillis;
}

/**
* Set the wait time in milliseconds
*
* @param waitTimeMillis the wait time in milliseconds
* @return ApiClient this client
*/
public ApiClient setWaitTimeMillis(long waitTimeMillis) {
this.waitTimeMillis = waitTimeMillis;
return this;
}

/**
* Get authentications (key: authentication name, value: authentication).
*
Expand Down Expand Up @@ -580,7 +625,23 @@ public <T> ResponseEntity<T> invokeAPI(String path, HttpMethod method, Map<Strin

RequestEntity<Object> requestEntity = requestBuilder.body(selectBody(body, formParams, contentType));

ResponseEntity<T> responseEntity = restTemplate.exchange(requestEntity, returnType);
ResponseEntity<T> responseEntity = null;
int attempts = 0;
while (attempts < maxAttemptsForRetry) {
try {
responseEntity = restTemplate.exchange(requestEntity, returnType);
break;
} catch (HttpServerErrorException ex) {
attempts++;
if (attempts < maxAttemptsForRetry) {
try {
Thread.sleep(waitTimeMillis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}

if (responseEntity.getStatusCode().is2xxSuccessful()) {
return responseEntity;
Expand Down
Loading