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

[Java][Jersey2] Fix generated Jersey 2 ApiClient to be thread-safe #818

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,11 @@ public void processOpts() {
if ("retrofit2".equals(getLibrary()) && !usePlayWS) {
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
}
} else if ("jersey2".equals(getLibrary()) || "resteasy".equals(getLibrary())) {
} else if ("jersey2".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
supportingFiles.add(new SupportingFile("ApiResponse.mustache", invokerFolder, "ApiResponse.java"));
additionalProperties.put("jackson", "true");
} else if ("resteasy".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
additionalProperties.put("jackson", "true");
} else if("jersey1".equals(getLibrary())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,6 @@ public class ApiClient {

protected Map<String, Authentication> authentications;

protected int statusCode;
protected Map<String, List<String>> responseHeaders;

protected DateFormat dateFormat;

public ApiClient() {
Expand Down Expand Up @@ -121,22 +118,6 @@ public class ApiClient {
return this;
}

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

/**
* Gets the response headers of the previous request
* @return Response headers
*/
public Map<String, List<String>> getResponseHeaders() {
return responseHeaders;
}

/**
* Get authentications (key: authentication name, value: authentication).
* @return Map of authentication object
Expand Down Expand Up @@ -673,7 +654,7 @@ public class ApiClient {
* @return The response body in type of string
* @throws ApiException API exception
*/
public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType) throws ApiException {
public <T> ApiResponse<T> invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType) throws ApiException {
updateParamsForAuth(authNames, queryParams, headerParams);

// Not using `.target(this.basePath).path(path)` below,
Expand All @@ -689,7 +670,7 @@ public class ApiClient {
}

Invocation.Builder invocationBuilder = target.request();

if (accept != null) {
invocationBuilder = invocationBuilder.accept(accept);
}
Expand Down Expand Up @@ -732,16 +713,16 @@ public class ApiClient {
throw new ApiException(500, "unknown method type " + method);
}

statusCode = response.getStatusInfo().getStatusCode();
responseHeaders = buildResponseHeaders(response);
final int statusCode = response.getStatusInfo().getStatusCode();
final Map<String, List<String>> responseHeaders = buildResponseHeaders(response);

if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) {
return null;
return new ApiResponse<>(statusCode, responseHeaders);
} else if (response.getStatusInfo().getFamily() == Status.Family.SUCCESSFUL) {
if (returnType == null)
return null;
return new ApiResponse<>(statusCode, responseHeaders);
else
return deserialize(response, returnType);
return new ApiResponse<>(statusCode, responseHeaders, deserialize(response, returnType));
} else {
String message = "error";
String respBody = null;
Expand Down Expand Up @@ -812,6 +793,8 @@ public class ApiClient {
* Update query and header parameters based on authentication settings.
*
* @param authNames The authentications to apply
* @param queryParams The query parameters
* @param headerParams The header parameters
*/
protected void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams) {
for (String authName : authNames) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{{>licenseInfo}}

package {{invokerPackage}};

import java.util.List;
import java.util.Map;

/**
* API response returned by API call.
*
* @param <T> The type of data that is deserialized from response body
*/
public class ApiResponse<T> {
private final int statusCode;
private final Map<String, List<String>> headers;
private final T data;

/**
* @param statusCode The status code of HTTP response
* @param headers The headers of HTTP response
*/
public ApiResponse(int statusCode, Map<String, List<String>> headers) {
this(statusCode, headers, null);
}

/**
* @param statusCode The status code of HTTP response
* @param headers The headers of HTTP response
* @param data The object deserialized from response bod
*/
public ApiResponse(int statusCode, Map<String, List<String>> headers, T data) {
this.statusCode = statusCode;
this.headers = headers;
this.data = data;
}

public int getStatusCode() {
return statusCode;
}

public Map<String, List<String>> getHeaders() {
return headers;
}

public T getData() {
return data;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package {{package}};

import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.ApiClient;
import {{invokerPackage}}.ApiResponse;
import {{invokerPackage}}.Configuration;
import {{invokerPackage}}.Pair;

Expand Down Expand Up @@ -62,6 +63,35 @@ public class {{classname}} {
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#parameters}}{{{dataType}}} {{paramName}}{{#has this 'more'}}, {{/has}}{{/parameters}}) throws ApiException {
{{#returnType}}
return {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}).getData();
{{/returnType}}{{^returnType}}
{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/returnType}}
}

/**
* {{summary}}
* {{notes}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
{{#returnType}}
* @return ApiResponse&lt;{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Void{{/returnType}}&gt;
{{/returnType}}
* @throws ApiException if fails to make API call
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
Object {{localVariablePrefix}}localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#parameters}}
{{#required}}
Expand Down Expand Up @@ -110,7 +140,7 @@ public class {{classname}} {
GenericType<{{{returnType}}}> {{localVariablePrefix}}localVarReturnType = new GenericType<{{{returnType}}}>() {};
return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, {{localVariablePrefix}}localVarReturnType);
{{/returnType}}{{^returnType}}
{{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, null);
return {{localVariablePrefix}}apiClient.invokeAPI({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAccept, {{localVariablePrefix}}localVarContentType, {{localVariablePrefix}}localVarAuthNames, null);
{{/returnType}}
}
{{/contents}}
Expand Down