Skip to content

Commit

Permalink
Merge pull request swagger-api#9737 from thomasJoei/feature/fix-issue…
Browse files Browse the repository at this point in the history
…-9685

[Issue 9685] Make RestTemplate thread safe by using the withHttpInfo pattern used …
  • Loading branch information
HugoMario authored Oct 3, 2019
2 parents c9252e8 + 781ee9a commit 3a8874b
Show file tree
Hide file tree
Showing 11 changed files with 619 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,6 @@ public class ApiClient {
private RestTemplate restTemplate;

private Map<String, Authentication> authentications;

private HttpStatus statusCode;
private MultiValueMap<String, String> responseHeaders;

private DateFormat dateFormat;

Expand Down Expand Up @@ -146,22 +143,6 @@ public class ApiClient {
return this;
}

/**
* Gets the status code of the previous request
* @return HttpStatus the status code
*/
public HttpStatus getStatusCode() {
return statusCode;
}

/**
* Gets the response headers of the previous request
* @return MultiValueMap a map of response headers
*/
public MultiValueMap<String, String> getResponseHeaders() {
return responseHeaders;
}

/**
* Get authentications (key: authentication name, value: authentication).
* @return Map the currently configured authentication types
Expand Down Expand Up @@ -520,9 +501,9 @@ public class ApiClient {
* @param contentType The request's Content-Type header
* @param authNames The authentications to apply
* @param returnType The return type into which to deserialize the response
* @return The response body in chosen type
* @return ResponseEntity&lt;T&gt; The response of the chosen type
*/
public <T> T invokeAPI(String path, HttpMethod method, MultiValueMap<String, String> queryParams, Object body, HttpHeaders headerParams, MultiValueMap<String, Object> formParams, List<MediaType> accept, MediaType contentType, String[] authNames, ParameterizedTypeReference<T> returnType) throws RestClientException {
public <T> ResponseEntity<T> invokeAPI(String path, HttpMethod method, MultiValueMap<String, String> queryParams, Object body, HttpHeaders headerParams, MultiValueMap<String, Object> formParams, List<MediaType> accept, MediaType contentType, String[] authNames, ParameterizedTypeReference<T> returnType) throws RestClientException {
updateParamsForAuth(authNames, queryParams, headerParams);
final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(basePath).path(path);
Expand All @@ -544,20 +525,12 @@ public class ApiClient {
RequestEntity<Object> requestEntity = requestBuilder.body(selectBody(body, formParams, contentType));

ResponseEntity<T> responseEntity = restTemplate.exchange(requestEntity, returnType);

statusCode = responseEntity.getStatusCode();
responseHeaders = responseEntity.getHeaders();

if (responseEntity.getStatusCode() == HttpStatus.NO_CONTENT) {
return null;
} else if (responseEntity.getStatusCode().is2xxSuccessful()) {
if (returnType == null) {
return null;
}
return responseEntity.getBody();
if (responseEntity.getStatusCode().is2xxSuccessful()) {
return responseEntity;
} else {
// The error handler built into the RestTemplate should handle 400 and 500 series errors.
throw new RestClientException("API returned " + statusCode + " and it wasn't handled by the RestTemplate error handler");
throw new RestClientException("API returned " + responseEntity.getStatusCode() + " and it wasn't handled by the RestTemplate error handler");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

{{>generatedAnnotation}}
@Component("{{package}}.{{classname}}")
Expand Down Expand Up @@ -51,16 +52,53 @@ public class {{classname}} {
/**
* {{summary}}
* {{notes}}
{{#responses}} * <p><b>{{code}}</b>{{#message}} - {{message}}{{/message}}
{{/responses}}{{#allParams}} * @param {{paramName}} {{description}}{{^description}}The {{paramName}} parameter{{/description}}
{{/allParams}}{{#returnType}} * @return {{returnType}}
{{/returnType}} * @throws RestClientException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
{{#responses}}
* <p><b>{{code}}</b>{{#message}} - {{message}}{{/message}}
{{/responses}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
{{#returnType}}
* @return {{returnType}}
{{/returnType}}
* @throws RestClientException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws RestClientException {
{{#returnType}}
return {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}).getBody();
{{/returnType}}
{{^returnType}}
{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/returnType}}
}

/**
* {{summary}}
* {{notes}}
{{#responses}}
* <p><b>{{code}}</b>{{#message}} - {{message}}{{/message}}
{{/responses}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
* @return ResponseEntity&lt;{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Void{{/returnType}}&gt;
* @throws RestClientException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public ResponseEntity<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws RestClientException {
Object {{localVariablePrefix}}postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
Expand All @@ -72,18 +110,18 @@ public class {{classname}} {
final Map<String, Object> uriVariables = new HashMap<String, Object>();{{#pathParams}}
uriVariables.put("{{baseName}}", {{{paramName}}});{{/pathParams}}{{/hasPathParams}}
String {{localVariablePrefix}}path = UriComponentsBuilder.fromPath("{{{path}}}"){{#hasPathParams}}.buildAndExpand(uriVariables){{/hasPathParams}}{{^hasPathParams}}.build(){{/hasPathParams}}.toUriString();

final MultiValueMap<String, String> {{localVariablePrefix}}queryParams = new LinkedMultiValueMap<String, String>();
final HttpHeaders {{localVariablePrefix}}headerParams = new HttpHeaders();
final MultiValueMap<String, Object> {{localVariablePrefix}}formParams = new LinkedMultiValueMap<String, Object>();{{#hasQueryParams}}

{{#queryParams}}{{localVariablePrefix}}queryParams.putAll({{localVariablePrefix}}apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{collectionFormat}}}".toUpperCase()){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));{{#hasMore}}
{{/hasMore}}{{/queryParams}}{{/hasQueryParams}}{{#hasHeaderParams}}

{{#headerParams}}if ({{paramName}} != null)
{{localVariablePrefix}}headerParams.add("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));{{#hasMore}}
{{/hasMore}}{{/headerParams}}{{/hasHeaderParams}}{{#hasFormParams}}

{{#formParams}}if ({{paramName}} != null)
{{localVariablePrefix}}formParams.add("{{baseName}}", {{#isFile}}new FileSystemResource({{paramName}}){{/isFile}}{{^isFile}}{{paramName}}{{/isFile}});{{#hasMore}}
{{/hasMore}}{{/formParams}}{{/hasFormParams}}
Expand All @@ -100,7 +138,7 @@ public class {{classname}} {
String[] {{localVariablePrefix}}authNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };

{{#returnType}}ParameterizedTypeReference<{{{returnType}}}> {{localVariablePrefix}}returnType = new ParameterizedTypeReference<{{{returnType}}}>() {};{{/returnType}}{{^returnType}}ParameterizedTypeReference<Void> {{localVariablePrefix}}returnType = new ParameterizedTypeReference<Void>() {};{{/returnType}}
{{#returnType}}return {{/returnType}}{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, HttpMethod.{{httpMethod}}, {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType);
return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}path, HttpMethod.{{httpMethod}}, {{localVariablePrefix}}queryParams, {{localVariablePrefix}}postBody, {{localVariablePrefix}}headerParams, {{localVariablePrefix}}formParams, {{localVariablePrefix}}accept, {{localVariablePrefix}}contentType, {{localVariablePrefix}}authNames, {{localVariablePrefix}}returnType);
}
{{/operation}}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.4.8-SNAPSHOT
2.4.9-SNAPSHOT
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.4.8-SNAPSHOT
2.4.9-SNAPSHOT
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ private String collectionToString(Collection<? extends CharSequence> collection)
private RestTemplate restTemplate;

private Map<String, Authentication> authentications;

private HttpStatus statusCode;
private MultiValueMap<String, String> responseHeaders;

private DateFormat dateFormat;

Expand Down Expand Up @@ -136,22 +133,6 @@ public ApiClient setBasePath(String basePath) {
return this;
}

/**
* Gets the status code of the previous request
* @return HttpStatus the status code
*/
public HttpStatus getStatusCode() {
return statusCode;
}

/**
* Gets the response headers of the previous request
* @return MultiValueMap a map of response headers
*/
public MultiValueMap<String, String> getResponseHeaders() {
return responseHeaders;
}

/**
* Get authentications (key: authentication name, value: authentication).
* @return Map the currently configured authentication types
Expand Down Expand Up @@ -508,9 +489,9 @@ protected Object selectBody(Object obj, MultiValueMap<String, Object> formParams
* @param contentType The request's Content-Type header
* @param authNames The authentications to apply
* @param returnType The return type into which to deserialize the response
* @return The response body in chosen type
* @return ResponseEntity&lt;T&gt; The response of the chosen type
*/
public <T> T invokeAPI(String path, HttpMethod method, MultiValueMap<String, String> queryParams, Object body, HttpHeaders headerParams, MultiValueMap<String, Object> formParams, List<MediaType> accept, MediaType contentType, String[] authNames, ParameterizedTypeReference<T> returnType) throws RestClientException {
public <T> ResponseEntity<T> invokeAPI(String path, HttpMethod method, MultiValueMap<String, String> queryParams, Object body, HttpHeaders headerParams, MultiValueMap<String, Object> formParams, List<MediaType> accept, MediaType contentType, String[] authNames, ParameterizedTypeReference<T> returnType) throws RestClientException {
updateParamsForAuth(authNames, queryParams, headerParams);

final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(basePath).path(path);
Expand All @@ -532,20 +513,12 @@ public <T> T invokeAPI(String path, HttpMethod method, MultiValueMap<String, Str
RequestEntity<Object> requestEntity = requestBuilder.body(selectBody(body, formParams, contentType));

ResponseEntity<T> responseEntity = restTemplate.exchange(requestEntity, returnType);

statusCode = responseEntity.getStatusCode();
responseHeaders = responseEntity.getHeaders();

if (responseEntity.getStatusCode() == HttpStatus.NO_CONTENT) {
return null;
} else if (responseEntity.getStatusCode().is2xxSuccessful()) {
if (returnType == null) {
return null;
}
return responseEntity.getBody();
if (responseEntity.getStatusCode().is2xxSuccessful()) {
return responseEntity;
} else {
// The error handler built into the RestTemplate should handle 400 and 500 series errors.
throw new RestClientException("API returned " + statusCode + " and it wasn't handled by the RestTemplate error handler");
throw new RestClientException("API returned " + responseEntity.getStatusCode() + " and it wasn't handled by the RestTemplate error handler");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;


@Component("io.swagger.client.api.AnotherFakeApi")
Expand Down Expand Up @@ -49,11 +50,23 @@ public void setApiClient(ApiClient apiClient) {
* To test special tags
* To test special tags
* <p><b>200</b> - successful operation
* @param body client model
* @param body client model (required)
* @return Client
* @throws RestClientException if an error occurs while attempting to invoke the API
*/
public Client testSpecialTags(Client body) throws RestClientException {
return testSpecialTagsWithHttpInfo(body).getBody();
}

/**
* To test special tags
* To test special tags
* <p><b>200</b> - successful operation
* @param body client model (required)
* @return ResponseEntity&lt;Client&gt;
* @throws RestClientException if an error occurs while attempting to invoke the API
*/
public ResponseEntity<Client> testSpecialTagsWithHttpInfo(Client body) throws RestClientException {
Object postBody = body;

// verify the required parameter 'body' is set
Expand All @@ -62,7 +75,7 @@ public Client testSpecialTags(Client body) throws RestClientException {
}

String path = UriComponentsBuilder.fromPath("/another-fake/dummy").build().toUriString();

final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
final HttpHeaders headerParams = new HttpHeaders();
final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();
Expand Down
Loading

0 comments on commit 3a8874b

Please sign in to comment.