Java.libraries.resttemplate.ApiClient.mustache Maven / Gradle / Ivy
{{>licenseInfo}}
package {{invokerPackage}};
{{#withXml}}
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
{{/withXml}}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.InvalidMediaTypeException;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.RequestEntity.BodyBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
{{#withXml}}
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
{{/withXml}}
import org.springframework.stereotype.Component;
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.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.DefaultUriBuilderFactory;
{{#openApiNullable}}
import org.openapitools.jackson.nullable.JsonNullableModule;
{{/openApiNullable}}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;
import java.util.function.Supplier;
{{#jsr310}}
import java.time.OffsetDateTime;
{{/jsr310}}
import {{invokerPackage}}.auth.Authentication;
{{#hasHttpBasicMethods}}
import {{invokerPackage}}.auth.HttpBasicAuth;
{{/hasHttpBasicMethods}}
{{#hasHttpBearerMethods}}
import {{invokerPackage}}.auth.HttpBearerAuth;
{{/hasHttpBearerMethods}}
{{#hasApiKeyMethods}}
import {{invokerPackage}}.auth.ApiKeyAuth;
{{/hasApiKeyMethods}}
{{#hasOAuthMethods}}
import {{invokerPackage}}.auth.OAuth;
{{/hasOAuthMethods}}
{{>generatedAnnotation}}
{{#generateClientAsBean}}
@Component("{{invokerPackage}}.ApiClient")
{{/generateClientAsBean}}
public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
public enum CollectionFormat {
CSV(","), TSV("\t"), SSV(" "), PIPES("|"), MULTI(null);
private final String separator;
private CollectionFormat(String separator) {
this.separator = separator;
}
private String collectionToString(Collection> collection) {
return StringUtils.collectionToDelimitedString(collection, separator);
}
}
private boolean debugging = false;
private HttpHeaders defaultHeaders = new HttpHeaders();
private MultiValueMap defaultCookies = new LinkedMultiValueMap();
private int maxAttemptsForRetry = {{maxAttemptsForRetry}};
private long waitTimeMillis = {{waitTimeMillis}};
private String basePath = "{{basePath}}";
private RestTemplate restTemplate;
private Map authentications;
private DateFormat dateFormat;
public ApiClient() {
this.restTemplate = buildRestTemplate();
init();
}
{{#generateClientAsBean}}
@Autowired
{{/generateClientAsBean}}
public ApiClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
init();
}
protected void init() {
// Use RFC3339 format for date and datetime.
// See http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
this.dateFormat = new RFC3339DateFormat();
// Use UTC as the default time zone.
this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
// Set default User-Agent.
setUserAgent("Java-SDK");
// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap();{{#authMethods}}{{#isBasic}}{{#isBasicBasic}}
authentications.put("{{name}}", new HttpBasicAuth());{{/isBasicBasic}}{{#isBasicBearer}}
authentications.put("{{name}}", new HttpBearerAuth("{{scheme}}"));{{/isBasicBearer}}{{/isBasic}}{{#isApiKey}}
authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{#isKeyInQuery}}"query"{{/isKeyInQuery}}{{#isKeyInCookie}}"cookie"{{/isKeyInCookie}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}}
authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}}
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);
}
/**
* Get the current base path
*
* @return String the base path
*/
public String getBasePath() {
return basePath;
}
/**
* Set the base path, which should include the host
*
* @param basePath the base path
* @return ApiClient this client
*/
public ApiClient setBasePath(String basePath) {
this.basePath = 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 maxAttemptsForRetry 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).
*
* @return Map the currently configured authentication types
*/
public Map getAuthentications() {
return authentications;
}
/**
* Get authentication for the given name.
*
* @param authName The authentication name
* @return The authentication, null if not found
*/
public Authentication getAuthentication(String authName) {
return authentications.get(authName);
}
{{#hasHttpBearerMethods}}
/**
* Helper method to set access token for the first Bearer authentication.
*
* @param bearerToken Bearer token
*/
public void setBearerToken(String bearerToken) {
setBearerToken(() -> bearerToken);
}
/**
* Helper method to set the supplier of access tokens for Bearer authentication.
*
* @param tokenSupplier The supplier of bearer tokens
*/
public void setBearerToken(Supplier tokenSupplier) {
for (Authentication auth : authentications.values()) {
if (auth instanceof HttpBearerAuth) {
((HttpBearerAuth) auth).setBearerToken(tokenSupplier);
return;
}
}
throw new RuntimeException("No Bearer authentication configured!");
}
{{/hasHttpBearerMethods}}
{{#hasHttpBasicMethods}}
/**
* Helper method to set username for the first HTTP basic authentication.
*
* @param username Username
*/
public void setUsername(String username) {
for (Authentication auth : authentications.values()) {
if (auth instanceof HttpBasicAuth) {
((HttpBasicAuth) auth).setUsername(username);
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
}
/**
* Helper method to set password for the first HTTP basic authentication.
* @param password Password
*/
public void setPassword(String password) {
for (Authentication auth : authentications.values()) {
if (auth instanceof HttpBasicAuth) {
((HttpBasicAuth) auth).setPassword(password);
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
}
{{/hasHttpBasicMethods}}
{{#hasApiKeyMethods}}
/**
* Helper method to set API key value for the first API key authentication.
*
* @param apiKey the API key
*/
public void setApiKey(String apiKey) {
for (Authentication auth : authentications.values()) {
if (auth instanceof ApiKeyAuth) {
((ApiKeyAuth) auth).setApiKey(apiKey);
return;
}
}
throw new RuntimeException("No API key authentication configured!");
}
/**
* Helper method to set API key prefix for the first API key authentication.
*
* @param apiKeyPrefix API key prefix
*/
public void setApiKeyPrefix(String apiKeyPrefix) {
for (Authentication auth : authentications.values()) {
if (auth instanceof ApiKeyAuth) {
((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
return;
}
}
throw new RuntimeException("No API key authentication configured!");
}
{{/hasApiKeyMethods}}
{{#hasOAuthMethods}}
/**
* Helper method to set access token for the first OAuth2 authentication.
*
* @param accessToken Access token
*/
public void setAccessToken(String accessToken) {
setAccessToken(() -> accessToken);
}
/**
* Helper method to set the supplier of access tokens for OAuth2 authentication.
*
* @param tokenSupplier The supplier of bearer tokens
*/
public void setAccessToken(Supplier tokenSupplier) {
for (Authentication auth : authentications.values()) {
if (auth instanceof OAuth) {
((OAuth) auth).setAccessToken(tokenSupplier);
return;
}
}
throw new RuntimeException("No OAuth2 authentication configured!");
}
{{/hasOAuthMethods}}
/**
* Set the User-Agent header's value (by adding to the default header map).
*
* @param userAgent the user agent string
* @return ApiClient this client
*/
public ApiClient setUserAgent(String userAgent) {
addDefaultHeader("User-Agent", userAgent);
return this;
}
/**
* Add a default header.
*
* @param name The header's name
* @param value The header's value
* @return ApiClient this client
*/
public ApiClient addDefaultHeader(String name, String value) {
if (defaultHeaders.containsKey(name)) {
defaultHeaders.remove(name);
}
defaultHeaders.add(name, value);
return this;
}
/**
* Add a default cookie.
*
* @param name The cookie's name
* @param value The cookie's value
* @return ApiClient this client
*/
public ApiClient addDefaultCookie(String name, String value) {
if (defaultCookies.containsKey(name)) {
defaultCookies.remove(name);
}
defaultCookies.add(name, value);
return this;
}
public void setDebugging(boolean debugging) {
List currentInterceptors = this.restTemplate.getInterceptors();
if (debugging) {
if (currentInterceptors == null) {
currentInterceptors = new ArrayList();
}
ClientHttpRequestInterceptor interceptor = new ApiClientHttpRequestInterceptor();
currentInterceptors.add(interceptor);
this.restTemplate.setInterceptors(currentInterceptors);
} else {
if (currentInterceptors != null && !currentInterceptors.isEmpty()) {
Iterator iter = currentInterceptors.iterator();
while (iter.hasNext()) {
ClientHttpRequestInterceptor interceptor = iter.next();
if (interceptor instanceof ApiClientHttpRequestInterceptor) {
iter.remove();
}
}
this.restTemplate.setInterceptors(currentInterceptors);
}
}
this.debugging = debugging;
}
/**
* Check that whether debugging is enabled for this API client.
* @return boolean true if this client is enabled for debugging, false otherwise
*/
public boolean isDebugging() {
return debugging;
}
/**
* Get the date format used to parse/format date parameters.
* @return DateFormat format
*/
public DateFormat getDateFormat() {
return dateFormat;
}
/**
* Set the date format used to parse/format date parameters.
* @param dateFormat Date format
* @return API client
*/
public ApiClient setDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
return this;
}
/**
* Parse the given string into Date object.
*
* @param str the string to parse
* @return the Date parsed from the string
*/
public Date parseDate(String str) {
try {
return dateFormat.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
/**
* Format the given Date object into string.
*
* @param date the date to format
* @return the formatted date as string
*/
public String formatDate(Date date) {
return dateFormat.format(date);
}
/**
* Format the given parameter object into string.
*
* @param param the object to convert
* @return String the parameter represented as a String
*/
public String parameterToString(Object param) {
if (param == null) {
return "";
} else if (param instanceof Date) {
return formatDate( (Date) param);
} {{#jsr310}}else if (param instanceof OffsetDateTime) {
return formatOffsetDateTime((OffsetDateTime) param);
} {{/jsr310}}else if (param instanceof Collection) {
StringBuilder b = new StringBuilder();
for (Object o : (Collection>) param) {
if (b.length() > 0) {
b.append(",");
}
b.append(String.valueOf(o));
}
return b.toString();
} else {
return String.valueOf(param);
}
}
/**
* Formats the specified collection path parameter to a string value.
*
* @param collectionFormat The collection format of the parameter.
* @param values The values of the parameter.
* @return String representation of the parameter
*/
public String collectionPathParameterToString(CollectionFormat collectionFormat, Collection> values) {
// create the value based on the collection format
if (CollectionFormat.MULTI.equals(collectionFormat)) {
// not valid for path params
return parameterToString(values);
}
// collectionFormat is assumed to be "csv" by default
if (collectionFormat == null) {
collectionFormat = CollectionFormat.CSV;
}
return collectionFormat.collectionToString(values);
}
/**
* Converts a parameter to a {@link MultiValueMap} for use in REST requests
*
* @param collectionFormat The format to convert to
* @param name The name of the parameter
* @param value The parameter's value
* @return a Map containing the String value(s) of the input parameter
*/
public MultiValueMap parameterToMultiValueMap(CollectionFormat collectionFormat, String name, Object value) {
final MultiValueMap params = new LinkedMultiValueMap();
if (name == null || name.isEmpty() || value == null) {
return params;
}
if (collectionFormat == null) {
collectionFormat = CollectionFormat.CSV;
}
if (value instanceof Map) {
@SuppressWarnings("unchecked")
final Map valuesMap = (Map) value;
for (final Entry entry : valuesMap.entrySet()) {
params.add(entry.getKey(), parameterToString(entry.getValue()));
}
return params;
}
Collection> valueCollection = null;
if (value instanceof Collection) {
valueCollection = (Collection>) value;
} else {
params.add(name, parameterToString(value));
return params;
}
if (valueCollection.isEmpty()) {
return params;
}
if (collectionFormat.equals(CollectionFormat.MULTI)) {
for (Object item : valueCollection) {
params.add(name, parameterToString(item));
}
return params;
}
List values = new ArrayList();
for (Object o : valueCollection) {
values.add(parameterToString(o));
}
params.add(name, collectionFormat.collectionToString(values));
return params;
}
/**
* Check if the given {@code String} is a JSON MIME.
*
* @param mediaType the input MediaType
* @return boolean true if the MediaType represents JSON, false otherwise
*/
public boolean isJsonMime(String mediaType) {
// "* / *" is default to JSON
if ("*/*".equals(mediaType)) {
return true;
}
try {
return isJsonMime(MediaType.parseMediaType(mediaType));
} catch (InvalidMediaTypeException e) {
}
return false;
}
/**
* Check if the given MIME is a JSON MIME.
* JSON MIME examples:
* application/json
* application/json; charset=UTF8
* APPLICATION/JSON
*
* @param mediaType the input MediaType
* @return boolean true if the MediaType represents JSON, false otherwise
*/
public boolean isJsonMime(MediaType mediaType) {
return mediaType != null && (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType) || mediaType.getSubtype().matches("^.*\\+json[;]?\\s*$"));
}
/**
* Check if the given {@code String} is a Problem JSON MIME (RFC-7807).
*
* @param mediaType the input MediaType
* @return boolean true if the MediaType represents Problem JSON, false otherwise
*/
public boolean isProblemJsonMime(String mediaType) {
return "application/problem+json".equalsIgnoreCase(mediaType);
}
/**
* Select the Accept header's value from the given accepts array:
* if JSON exists in the given array, use it;
* otherwise use all of them (joining into a string)
*
* @param accepts The accepts array to select from
* @return List The list of MediaTypes to use for the Accept header
*/
public List selectHeaderAccept(String[] accepts) {
if (accepts.length == 0) {
return null;
}
for (String accept : accepts) {
MediaType mediaType = MediaType.parseMediaType(accept);
if (isJsonMime(mediaType) && !isProblemJsonMime(accept)) {
return Collections.singletonList(mediaType);
}
}
return MediaType.parseMediaTypes(StringUtils.arrayToCommaDelimitedString(accepts));
}
/**
* Select the Content-Type header's value from the given array:
* if JSON exists in the given array, use it;
* otherwise use the first one of the array.
*
* @param contentTypes The Content-Type array to select from
* @return MediaType The Content-Type header to use. If the given array is empty, JSON will be used.
*/
public MediaType selectHeaderContentType(String[] contentTypes) {
if (contentTypes.length == 0) {
return MediaType.APPLICATION_JSON;
}
for (String contentType : contentTypes) {
MediaType mediaType = MediaType.parseMediaType(contentType);
if (isJsonMime(mediaType)) {
return mediaType;
}
}
return MediaType.parseMediaType(contentTypes[0]);
}
/**
* Select the body to use for the request
*
* @param obj the body object
* @param formParams the form parameters
* @param contentType the content type of the request
* @return Object the selected body
*/
protected Object selectBody(Object obj, MultiValueMap formParams, MediaType contentType) {
boolean isForm = MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType) || MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(contentType);
return isForm ? formParams : obj;
}
/**
* Expand path template with variables
*
* @param pathTemplate path template with placeholders
* @param variables variables to replace
* @return path with placeholders replaced by variables
*/
public String expandPath(String pathTemplate, Map variables) {
return restTemplate.getUriTemplateHandler().expand(pathTemplate, variables).toString();
}
/**
* Include queryParams in uriParams taking into account the paramName
*
* @param queryParams The query parameters
* @param uriParams The path parameters
* return templatized query string
*/
public String generateQueryUri(MultiValueMap queryParams, Map uriParams) {
StringBuilder queryBuilder = new StringBuilder();
queryParams.forEach((name, values) -> {
try {
final String encodedName = URLEncoder.encode(name.toString(), "UTF-8");
if (CollectionUtils.isEmpty(values)) {
if (queryBuilder.length() != 0) {
queryBuilder.append('&');
}
queryBuilder.append(encodedName);
} else {
int valueItemCounter = 0;
for (Object value : values) {
if (queryBuilder.length() != 0) {
queryBuilder.append('&');
}
queryBuilder.append(encodedName);
if (value != null) {
String templatizedKey = encodedName + valueItemCounter++;
uriParams.put(templatizedKey, value.toString());
queryBuilder.append('=').append("{").append(templatizedKey).append("}");
}
}
}
} catch (UnsupportedEncodingException e) {
}
});
return queryBuilder.toString();
}
/**
* Invoke API by sending HTTP request with the given options.
*
* @param the return type to use
* @param path The sub-path of the HTTP URL
* @param method The request method
* @param pathParams The path parameters
* @param queryParams The query parameters
* @param body The request body object
* @param headerParams The header parameters
* @param cookieParams The cookie parameters
* @param formParams The form parameters
* @param accept The request's Accept header
* @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 ResponseEntity<T> The response of the chosen type
*/
public ResponseEntity invokeAPI(String path, HttpMethod method, Map pathParams, MultiValueMap queryParams, Object body, HttpHeaders headerParams, MultiValueMap cookieParams, MultiValueMap formParams, List accept, MediaType contentType, String[] authNames, ParameterizedTypeReference returnType) throws RestClientException {
updateParamsForAuth(authNames, queryParams, headerParams, cookieParams);
Map uriParams = new HashMap<>();
uriParams.putAll(pathParams);
String finalUri = path;
if (queryParams != null && !queryParams.isEmpty()) {
//Include queryParams in uriParams taking into account the paramName
String queryUri = generateQueryUri(queryParams, uriParams);
//Append to finalUri the templatized query string like "?param1={param1Value}&.......
finalUri += "?" + queryUri;
}
String expandedPath = this.expandPath(finalUri, uriParams);
final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(basePath).path(expandedPath);
URI uri;
try {
uri = new URI(builder.build().toUriString());
} catch (URISyntaxException ex) {
throw new RestClientException("Could not build URL: " + builder.toUriString(), ex);
}
final BodyBuilder requestBuilder = RequestEntity.method(method, UriComponentsBuilder.fromHttpUrl(basePath).toUriString() + finalUri, uriParams);
if (accept != null) {
requestBuilder.accept(accept.toArray(new MediaType[accept.size()]));
}
if (contentType != null) {
requestBuilder.contentType(contentType);
}
addHeadersToRequest(headerParams, requestBuilder);
addHeadersToRequest(defaultHeaders, requestBuilder);
addCookiesToRequest(cookieParams, requestBuilder);
addCookiesToRequest(defaultCookies, requestBuilder);
RequestEntity
© 2015 - 2024 Weber Informatics LLC | Privacy Policy