();
+ authentications.put("petstore_auth", new OAuth());
+ authentications.put("api_key", new ApiKeyAuth("header", "api_key"));
+ authentications.put("api_key_query", new ApiKeyAuth("query", "api_key_query"));
+ authentications.put("http_basic_test", new HttpBasicAuth());
+ authentications.put("bearer_test", new HttpBearerAuth("bearer"));
+ // Prevent the authentications from being modified.
+ authentications = Collections.unmodifiableMap(authentications);
+
+ this.httpClient = httpClient;
+ }
+
+ public ApiClient() {
+ this(HttpClients.createDefault());
+ }
+
+ public static DateFormat buildDefaultDateFormat() {
+ return new RFC3339DateFormat();
+ }
+
+ /**
+ * Returns the current object mapper used for JSON serialization/deserialization.
+ *
+ * Note: If you make changes to the object mapper, remember to set it back via
+ * setObjectMapper
in order to trigger HTTP client rebuilding.
+ *
+ * @return Object mapper
+ */
+ public ObjectMapper getObjectMapper() {
+ return objectMapper;
+ }
+
+ /**
+ * Sets the object mapper.
+ *
+ * @param objectMapper object mapper
+ * @return API client
+ */
+ public ApiClient setObjectMapper(ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ return this;
+ }
+
+ public CloseableHttpClient getHttpClient() {
+ return httpClient;
+ }
+
+ /**
+ * Sets the HTTP client.
+ *
+ * @param httpClient HTTP client
+ * @return API client
+ */
+ public ApiClient setHttpClient(CloseableHttpClient httpClient) {
+ this.httpClient = httpClient;
+ return this;
+ }
+
+ public String getBasePath() {
+ return basePath;
+ }
+
+ /**
+ * Sets the base path.
+ *
+ * @param basePath base path
+ * @return API client
+ */
+ public ApiClient setBasePath(String basePath) {
+ this.basePath = basePath;
+ this.serverIndex = null;
+ return this;
+ }
+
+ public List getServers() {
+ return servers;
+ }
+
+ /**
+ * Sets the server.
+ *
+ * @param servers a list of server configuration
+ * @return API client
+ */
+ public ApiClient setServers(List servers) {
+ this.servers = servers;
+ return this;
+ }
+
+ public Integer getServerIndex() {
+ return serverIndex;
+ }
+
+ /**
+ * Sets the server index.
+ *
+ * @param serverIndex server index
+ * @return API client
+ */
+ public ApiClient setServerIndex(Integer serverIndex) {
+ this.serverIndex = serverIndex;
+ return this;
+ }
+
+ public Map getServerVariables() {
+ return serverVariables;
+ }
+
+ /**
+ * Sets the server variables.
+ *
+ * @param serverVariables server variables
+ * @return API client
+ */
+ public ApiClient setServerVariables(Map serverVariables) {
+ this.serverVariables = serverVariables;
+ 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> getResponseHeaders() {
+ return responseHeaders;
+ }
+
+ /**
+ * Get authentications (key: authentication name, value: authentication).
+ * @return Map of authentication
+ */
+ 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);
+ }
+
+ /**
+ * The path of temporary folder used to store downloaded files from endpoints
+ * with file response. The default value is null
, i.e. using
+ * the system's default temporary folder.
+ *
+ * @return Temp folder path
+ */
+ public String getTempFolderPath() {
+ return tempFolderPath;
+ }
+
+ /**
+ * Helper method to set access token for the first Bearer authentication.
+ * @param bearerToken Bearer token
+ * @return API client
+ */
+ public ApiClient setBearerToken(String bearerToken) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof HttpBearerAuth) {
+ ((HttpBearerAuth) auth).setBearerToken(bearerToken);
+ return this;
+ }
+ }
+ throw new RuntimeException("No Bearer authentication configured!");
+ }
+
+ /**
+ * Helper method to set the supplier of access tokens for Bearer authentication.
+ *
+ * @param tokenSupplier the token supplier function
+ */
+ 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!");
+ }
+
+ /**
+ * Helper method to set username for the first HTTP basic authentication.
+ * @param username Username
+ * @return API client
+ */
+ public ApiClient setUsername(String username) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof HttpBasicAuth) {
+ ((HttpBasicAuth) auth).setUsername(username);
+ return this;
+ }
+ }
+ throw new RuntimeException("No HTTP basic authentication configured!");
+ }
+
+ /**
+ * Helper method to set password for the first HTTP basic authentication.
+ * @param password Password
+ * @return API client
+ */
+ public ApiClient setPassword(String password) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof HttpBasicAuth) {
+ ((HttpBasicAuth) auth).setPassword(password);
+ return this;
+ }
+ }
+ throw new RuntimeException("No HTTP basic authentication configured!");
+ }
+
+
+ /**
+ * Helper method to set API key value for the first API key authentication.
+ * @param apiKey the API key
+ * @return API client
+ */
+ public ApiClient setApiKey(String apiKey) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof ApiKeyAuth) {
+ ((ApiKeyAuth) auth).setApiKey(apiKey);
+ return this;
+ }
+ }
+ 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
+ * @return API client
+ */
+ public ApiClient setApiKeyPrefix(String apiKeyPrefix) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof ApiKeyAuth) {
+ ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
+ return this;
+ }
+ }
+ throw new RuntimeException("No API key authentication configured!");
+ }
+
+
+ /**
+ * Helper method to set access token for the first OAuth2 authentication.
+ * @param accessToken Access token
+ * @return API client
+ */
+ public ApiClient setAccessToken(String accessToken) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof OAuth) {
+ ((OAuth) auth).setAccessToken(accessToken);
+ return this;
+ }
+ }
+ throw new RuntimeException("No OAuth2 authentication configured!");
+ }
+
+
+ /**
+ * Set the User-Agent header's value (by adding to the default header map).
+ * @param userAgent User agent
+ * @return API client
+ */
+ public ApiClient setUserAgent(String userAgent) {
+ addDefaultHeader("User-Agent", userAgent);
+ return this;
+ }
+
+ /**
+ * Set temp folder path
+ * @param tempFolderPath Temp folder path
+ * @return API client
+ */
+ public ApiClient setTempFolderPath(String tempFolderPath) {
+ this.tempFolderPath = tempFolderPath;
+ return this;
+ }
+
+ /**
+ * Add a default header.
+ *
+ * @param key The header's key
+ * @param value The header's value
+ * @return API client
+ */
+ public ApiClient addDefaultHeader(String key, String value) {
+ defaultHeaderMap.put(key, value);
+ return this;
+ }
+
+ /**
+ * Add a default cookie.
+ *
+ * @param key The cookie's key
+ * @param value The cookie's value
+ * @return API client
+ */
+ public ApiClient addDefaultCookie(String key, String value) {
+ defaultCookieMap.put(key, value);
+ return this;
+ }
+
+ /**
+ * Check that whether debugging is enabled for this API client.
+ * @return True if debugging is on
+ */
+ public boolean isDebugging() {
+ return debugging;
+ }
+
+ /**
+ * Enable/disable debugging for this API client.
+ *
+ * @param debugging To enable (true) or disable (false) debugging
+ * @return API client
+ */
+ public ApiClient setDebugging(boolean debugging) {
+ // TODO: implement debugging mode
+ this.debugging = debugging;
+ return this;
+ }
+
+ /**
+ * Connect timeout (in milliseconds).
+ * @return Connection timeout
+ */
+ public int getConnectTimeout() {
+ return connectionTimeout;
+ }
+
+ /**
+ * Set the connect timeout (in milliseconds).
+ * A value of 0 means no timeout, otherwise values must be between 1 and
+ * {@link Integer#MAX_VALUE}.
+ * @param connectionTimeout Connection timeout in milliseconds
+ * @return API client
+ */
+ public ApiClient setConnectTimeout(int connectionTimeout) {
+ this.connectionTimeout = connectionTimeout;
+ return this;
+ }
+
+ /**
+ * Get the date format used to parse/format date parameters.
+ * @return Date 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;
+ // Also set the date format for model (de)serialization with Date properties.
+ this.objectMapper.setDateFormat((DateFormat) dateFormat.clone());
+ return this;
+ }
+
+ /**
+ * Parse the given string into Date object.
+ * @param str String
+ * @return Date
+ */
+ public Date parseDate(String str) {
+ try {
+ return dateFormat.parse(str);
+ } catch (java.text.ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Format the given Date object into string.
+ * @param date Date
+ * @return Date in string format
+ */
+ public String formatDate(Date date) {
+ return dateFormat.format(date);
+ }
+
+ /**
+ * Format the given parameter object into string.
+ * @param param Object
+ * @return Object in string format
+ */
+ public String parameterToString(Object param) {
+ if (param == null) {
+ return "";
+ } else if (param instanceof Date) {
+ return formatDate((Date) param);
+ } else if (param instanceof OffsetDateTime) {
+ return formatOffsetDateTime((OffsetDateTime) param);
+ } 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 query parameter to a list containing a single {@code Pair} object.
+ *
+ * Note that {@code value} must not be a collection.
+ *
+ * @param name The name of the parameter.
+ * @param value The value of the parameter.
+ * @return A list containing a single {@code Pair} object.
+ */
+ public List parameterToPair(String name, Object value) {
+ List params = new ArrayList();
+
+ // preconditions
+ if (name == null || name.isEmpty() || value == null || value instanceof Collection) {
+ return params;
+ }
+
+ params.add(new Pair(name, escapeString(parameterToString(value))));
+ return params;
+ }
+
+ /**
+ * Formats the specified collection query parameters to a list of {@code Pair} objects.
+ *
+ * Note that the values of each of the returned Pair objects are percent-encoded.
+ *
+ * @param collectionFormat The collection format of the parameter.
+ * @param name The name of the parameter.
+ * @param value The value of the parameter.
+ * @return A list of {@code Pair} objects.
+ */
+ public List parameterToPairs(String collectionFormat, String name, Collection value) {
+ List params = new ArrayList();
+
+ // preconditions
+ if (name == null || name.isEmpty() || value == null || value.isEmpty()) {
+ return params;
+ }
+
+ // create the params based on the collection format
+ if ("multi".equals(collectionFormat)) {
+ for (Object item : value) {
+ params.add(new Pair(name, escapeString(parameterToString(item))));
+ }
+ return params;
+ }
+
+ // collectionFormat is assumed to be "csv" by default
+ String delimiter = ",";
+
+ // escape all delimiters except commas, which are URI reserved
+ // characters
+ if ("ssv".equals(collectionFormat)) {
+ delimiter = escapeString(" ");
+ } else if ("tsv".equals(collectionFormat)) {
+ delimiter = escapeString("\t");
+ } else if ("pipes".equals(collectionFormat)) {
+ delimiter = escapeString("|");
+ }
+
+ StringBuilder sb = new StringBuilder() ;
+ for (Object item : value) {
+ sb.append(delimiter);
+ sb.append(escapeString(parameterToString(item)));
+ }
+
+ params.add(new Pair(name, sb.substring(delimiter.length())));
+
+ return params;
+ }
+
+ /**
+ * Check if the given MIME is a JSON MIME.
+ * JSON MIME examples:
+ * application/json
+ * application/json; charset=UTF8
+ * APPLICATION/JSON
+ * application/vnd.company+json
+ * @param mime MIME
+ * @return True if MIME type is boolean
+ */
+ public boolean isJsonMime(String mime) {
+ String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$";
+ return mime != null && (mime.matches(jsonMime) || mime.equals("*/*"));
+ }
+
+ /**
+ * 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 The Accept header to use. If the given array is empty,
+ * null will be returned (not to set the Accept header explicitly).
+ */
+ public String selectHeaderAccept(String[] accepts) {
+ if (accepts.length == 0) {
+ return null;
+ }
+ for (String accept : accepts) {
+ if (isJsonMime(accept)) {
+ return accept;
+ }
+ }
+ return StringUtil.join(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 The Content-Type header to use. If the given array is empty,
+ * or matches "any", JSON will be used.
+ */
+ public String selectHeaderContentType(String[] contentTypes) {
+ if (contentTypes.length == 0 || contentTypes[0].equals("*/*")) {
+ return "application/json";
+ }
+ for (String contentType : contentTypes) {
+ if (isJsonMime(contentType)) {
+ return contentType;
+ }
+ }
+ return contentTypes[0];
+ }
+
+ /**
+ * Escape the given string to be used as URL query value.
+ * @param str String
+ * @return Escaped string
+ */
+ public String escapeString(String str) {
+ try {
+ return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20");
+ } catch (UnsupportedEncodingException e) {
+ return str;
+ }
+ }
+
+ /**
+ * Transforms response headers into map.
+ *
+ * @param headers HTTP headers
+ * @return a map of string array
+ */
+ protected Map> transformResponseHeaders(Header[] headers) {
+ Map> headersMap = new HashMap<>();
+ for (Header header : headers) {
+ List valuesList = headersMap.get(header.getName());
+ if (valuesList != null) {
+ valuesList.add(header.getValue());
+ } else {
+ valuesList = new ArrayList<>();
+ valuesList.add(header.getValue());
+ headersMap.put(header.getName(), valuesList);
+ }
+ }
+ return headersMap;
+ }
+
+ /**
+ * Parse content type object from header value
+ */
+ private ContentType getContentType(String headerValue) throws ApiException {
+ try {
+ return ContentType.parse(headerValue);
+ } catch (UnsupportedCharsetException e) {
+ throw new ApiException("Could not parse content type " + headerValue);
+ }
+ }
+
+ /**
+ * Get content type of a response or null if one was not provided
+ */
+ private String getResponseMimeType(HttpResponse response) throws ApiException {
+ Header contentTypeHeader = response.getFirstHeader("Content-Type");
+ if (contentTypeHeader != null) {
+ return getContentType(contentTypeHeader.getValue()).getMimeType();
+ }
+ return null;
+ }
+
+ /**
+ * Serialize the given Java object into string according the given
+ * Content-Type (only JSON is supported for now).
+ * @param obj Object
+ * @param contentType Content type
+ * @param formParams Form parameters
+ * @return Object
+ * @throws ApiException API exception
+ */
+ public HttpEntity serialize(Object obj, Map formParams, ContentType contentType) throws ApiException {
+ String mimeType = contentType.getMimeType();
+ if (isJsonMime(mimeType)) {
+ try {
+ return new StringEntity(objectMapper.writeValueAsString(obj), contentType.withCharset(StandardCharsets.UTF_8));
+ } catch (JsonProcessingException e) {
+ throw new ApiException(e);
+ }
+ } else if (mimeType.equals(ContentType.MULTIPART_FORM_DATA.getMimeType())) {
+ MultipartEntityBuilder multiPartBuilder = MultipartEntityBuilder.create();
+ for (Entry paramEntry : formParams.entrySet()) {
+ Object value = paramEntry.getValue();
+ if (value instanceof File) {
+ multiPartBuilder.addBinaryBody(paramEntry.getKey(), (File) value);
+ } else if (value instanceof byte[]) {
+ multiPartBuilder.addBinaryBody(paramEntry.getKey(), (byte[]) value);
+ } else {
+ Charset charset = contentType.getCharset();
+ if (charset != null) {
+ ContentType customContentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset);
+ multiPartBuilder.addTextBody(paramEntry.getKey(), parameterToString(paramEntry.getValue()),
+ customContentType);
+ } else {
+ multiPartBuilder.addTextBody(paramEntry.getKey(), parameterToString(paramEntry.getValue()));
+ }
+ }
+ }
+ return multiPartBuilder.build();
+ } else if (mimeType.equals(ContentType.APPLICATION_FORM_URLENCODED.getMimeType())) {
+ List formValues = new ArrayList<>();
+ for (Entry paramEntry : formParams.entrySet()) {
+ formValues.add(new BasicNameValuePair(paramEntry.getKey(), parameterToString(paramEntry.getValue())));
+ }
+ return new UrlEncodedFormEntity(formValues, contentType.getCharset());
+ } else {
+ // Handle files with unknown content type
+ if (obj instanceof File) {
+ return new FileEntity((File) obj, contentType);
+ } else if (obj instanceof byte[]) {
+ return new ByteArrayEntity((byte[]) obj, contentType);
+ }
+ throw new ApiException("Serialization for content type '" + contentType + "' not supported");
+ }
+ }
+
+ /**
+ * Deserialize response body to Java object according to the Content-Type.
+ *
+ * @param Type
+ * @param response Response
+ * @param valueType Return type
+ * @return Deserialized object
+ * @throws ApiException API exception
+ * @throws IOException IO exception
+ */
+ @SuppressWarnings("unchecked")
+ public T deserialize(CloseableHttpResponse response, TypeReference valueType) throws ApiException, IOException, ParseException {
+ if (valueType == null) {
+ return null;
+ }
+ HttpEntity entity = response.getEntity();
+ Type valueRawType = valueType.getType();
+ if (valueRawType.equals(byte[].class)) {
+ return (T) EntityUtils.toByteArray(entity);
+ } else if (valueRawType.equals(File.class)) {
+ return (T) downloadFileFromResponse(response);
+ }
+ String mimeType = getResponseMimeType(response);
+ if (mimeType == null || isJsonMime(mimeType)) {
+ // Assume json if no mime type
+ // convert input stream to string
+ java.util.Scanner s = new java.util.Scanner(entity.getContent()).useDelimiter("\\A");
+ String content = (String) (s.hasNext() ? s.next() : "");
+
+ if ("".equals(content)) { // returns null for empty body
+ return null;
+ }
+
+ return objectMapper.readValue(content, valueType);
+ } else if ("text/plain".equalsIgnoreCase(mimeType)) {
+ // convert input stream to string
+ java.util.Scanner s = new java.util.Scanner(entity.getContent()).useDelimiter("\\A");
+ return (T) (s.hasNext() ? s.next() : "");
+ } else {
+ throw new ApiException(
+ "Deserialization for content type '" + mimeType + "' not supported for type '" + valueType + "'",
+ response.getCode(),
+ responseHeaders,
+ EntityUtils.toString(entity)
+ );
+ }
+ }
+
+ private File downloadFileFromResponse(CloseableHttpResponse response) throws IOException {
+ Header contentDispositionHeader = response.getFirstHeader("Content-Disposition");
+ String contentDisposition = contentDispositionHeader == null ? null : contentDispositionHeader.getValue();
+ File file = prepareDownloadFile(contentDisposition);
+ Files.copy(response.getEntity().getContent(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ return file;
+ }
+
+ protected File prepareDownloadFile(String contentDisposition) throws IOException {
+ String filename = null;
+ if (contentDisposition != null && !"".equals(contentDisposition)) {
+ // Get filename from the Content-Disposition header.
+ Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
+ Matcher matcher = pattern.matcher(contentDisposition);
+ if (matcher.find())
+ filename = matcher.group(1);
+ }
+
+ String prefix;
+ String suffix = null;
+ if (filename == null) {
+ prefix = "download-";
+ suffix = "";
+ } else {
+ int pos = filename.lastIndexOf('.');
+ if (pos == -1) {
+ prefix = filename + "-";
+ } else {
+ prefix = filename.substring(0, pos) + "-";
+ suffix = filename.substring(pos);
+ }
+ // Files.createTempFile requires the prefix to be at least three characters long
+ if (prefix.length() < 3)
+ prefix = "download-";
+ }
+
+ if (tempFolderPath == null)
+ return Files.createTempFile(prefix, suffix).toFile();
+ else
+ return Files.createTempFile(Paths.get(tempFolderPath), prefix, suffix).toFile();
+ }
+
+ /**
+ * Build full URL by concatenating base path, the given sub path and query parameters.
+ *
+ * @param path The sub path
+ * @param queryParams The query parameters
+ * @param collectionQueryParams The collection query parameters
+ * @param urlQueryDeepObject URL query string of the deep object parameters
+ * @return The full URL
+ */
+ private String buildUrl(String path, List queryParams, List collectionQueryParams, String urlQueryDeepObject) {
+ String baseURL;
+ if (serverIndex != null) {
+ if (serverIndex < 0 || serverIndex >= servers.size()) {
+ throw new ArrayIndexOutOfBoundsException(String.format(
+ "Invalid index %d when selecting the host settings. Must be less than %d", serverIndex, servers.size()
+ ));
+ }
+ baseURL = servers.get(serverIndex).URL(serverVariables);
+ } else {
+ baseURL = basePath;
+ }
+
+ final StringBuilder url = new StringBuilder();
+ url.append(baseURL).append(path);
+
+ if (queryParams != null && !queryParams.isEmpty()) {
+ // support (constant) query string in `path`, e.g. "/posts?draft=1"
+ String prefix = path.contains("?") ? "&" : "?";
+ for (Pair param : queryParams) {
+ if (param.getValue() != null) {
+ if (prefix != null) {
+ url.append(prefix);
+ prefix = null;
+ } else {
+ url.append("&");
+ }
+ String value = parameterToString(param.getValue());
+ // query parameter value already escaped as part of parameterToPair
+ url.append(escapeString(param.getName())).append("=").append(value);
+ }
+ }
+ }
+
+ if (collectionQueryParams != null && !collectionQueryParams.isEmpty()) {
+ String prefix = url.toString().contains("?") ? "&" : "?";
+ for (Pair param : collectionQueryParams) {
+ if (param.getValue() != null) {
+ if (prefix != null) {
+ url.append(prefix);
+ prefix = null;
+ } else {
+ url.append("&");
+ }
+ String value = parameterToString(param.getValue());
+ // collection query parameter value already escaped as part of parameterToPairs
+ url.append(escapeString(param.getName())).append("=").append(value);
+ }
+ }
+ }
+
+ if (urlQueryDeepObject != null && urlQueryDeepObject.length() > 0) {
+ url.append(url.toString().contains("?") ? "&" : "?");
+ url.append(urlQueryDeepObject);
+ }
+
+ return url.toString();
+ }
+
+ protected boolean isSuccessfulStatus(int statusCode) {
+ return statusCode >= 200 && statusCode < 300;
+ }
+
+ protected boolean isBodyAllowed(String method) {
+ return bodyMethods.contains(method);
+ }
+
+ protected Cookie buildCookie(String key, String value, URI uri) {
+ BasicClientCookie cookie = new BasicClientCookie(key, value);
+ cookie.setDomain(uri.getHost());
+ cookie.setPath("/");
+ return cookie;
+ }
+
+ protected T processResponse(CloseableHttpResponse response, TypeReference returnType) throws ApiException, IOException, ParseException {
+ statusCode = response.getCode();
+ if (statusCode == HttpStatus.SC_NO_CONTENT) {
+ return null;
+ }
+
+ responseHeaders = transformResponseHeaders(response.getHeaders());
+ if (isSuccessfulStatus(statusCode)) {
+ return this.deserialize(response, returnType);
+ } else {
+ String message = EntityUtils.toString(response.getEntity());
+ throw new ApiException(message, statusCode, responseHeaders, message);
+ }
+ }
+
+ /**
+ * Invoke API by sending HTTP request with the given options.
+ *
+ * @param Type
+ * @param path The sub-path of the HTTP URL
+ * @param method The request method, one of "GET", "POST", "PUT", and "DELETE"
+ * @param queryParams The query parameters
+ * @param collectionQueryParams The collection query parameters
+ * @param urlQueryDeepObject A URL query string for deep object parameters
+ * @param body The request body object - if it is not binary, otherwise null
+ * @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 Return type
+ * @return The response body in type of string
+ * @throws ApiException API exception
+ */
+ public T invokeAPI(
+ String path,
+ String method,
+ List queryParams,
+ List collectionQueryParams,
+ String urlQueryDeepObject,
+ Object body,
+ Map headerParams,
+ Map cookieParams,
+ Map formParams,
+ String accept,
+ String contentType,
+ String[] authNames,
+ TypeReference returnType) throws ApiException {
+ if (body != null && !formParams.isEmpty()) {
+ throw new ApiException("Cannot have body and form params");
+ }
+
+ updateParamsForAuth(authNames, queryParams, headerParams, cookieParams);
+ final String url = buildUrl(path, queryParams, collectionQueryParams, urlQueryDeepObject);
+
+ ClassicRequestBuilder builder = ClassicRequestBuilder.create(method);
+ builder.setUri(url);
+
+ if (accept != null) {
+ builder.addHeader("Accept", accept);
+ }
+ for (Entry keyValue : headerParams.entrySet()) {
+ builder.addHeader(keyValue.getKey(), keyValue.getValue());
+ }
+ for (Map.Entry keyValue : defaultHeaderMap.entrySet()) {
+ if (!headerParams.containsKey(keyValue.getKey())) {
+ builder.addHeader(keyValue.getKey(), keyValue.getValue());
+ }
+ }
+
+ BasicCookieStore store = new BasicCookieStore();
+ for (Entry keyValue : cookieParams.entrySet()) {
+ store.addCookie(buildCookie(keyValue.getKey(), keyValue.getValue(), builder.getUri()));
+ }
+ for (Entry keyValue : defaultCookieMap.entrySet()) {
+ if (!cookieParams.containsKey(keyValue.getKey())) {
+ store.addCookie(buildCookie(keyValue.getKey(), keyValue.getValue(), builder.getUri()));
+ }
+ }
+
+ HttpClientContext context = HttpClientContext.create();
+ context.setCookieStore(store);
+
+ ContentType contentTypeObj = getContentType(contentType);
+ if (body != null || !formParams.isEmpty()) {
+ if (isBodyAllowed(method)) {
+ // Add entity if we have content and a valid method
+ builder.setEntity(serialize(body, formParams, contentTypeObj));
+ } else {
+ throw new ApiException("method " + method + " does not support a request body");
+ }
+ } else {
+ // for empty body
+ builder.setEntity(new StringEntity("", contentTypeObj));
+ }
+
+ try (CloseableHttpResponse response = httpClient.execute(builder.build(), context)) {
+ return processResponse(response, returnType);
+ } catch (IOException | ParseException e) {
+ throw new ApiException(e);
+ }
+ }
+
+ /**
+ * Update query and header parameters based on authentication settings.
+ *
+ * @param authNames The authentications to apply
+ * @param queryParams Query parameters
+ * @param headerParams Header parameters
+ * @param cookieParams Cookie parameters
+ */
+ private void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams, Map cookieParams) {
+ for (String authName : authNames) {
+ Authentication auth = authentications.get(authName);
+ if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);
+ auth.applyToParams(queryParams, headerParams, cookieParams);
+ }
+ }
+}
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/ApiException.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/ApiException.java
new file mode 100644
index 00000000000..5825ae3b27c
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/ApiException.java
@@ -0,0 +1,102 @@
+/*
+ * OpenAPI Petstore
+ * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * 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 java.util.Map;
+import java.util.List;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.4.0-SNAPSHOT")
+public class ApiException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ private int code = 0;
+ private Map> responseHeaders = null;
+ private String responseBody = null;
+
+ public ApiException() {}
+
+ public ApiException(Throwable throwable) {
+ super(throwable);
+ }
+
+ public ApiException(String message) {
+ super(message);
+ }
+
+ public ApiException(String message, Throwable throwable, int code, Map> responseHeaders, String responseBody) {
+ super(message, throwable);
+ this.code = code;
+ this.responseHeaders = responseHeaders;
+ this.responseBody = responseBody;
+ }
+
+ public ApiException(String message, int code, Map> responseHeaders, String responseBody) {
+ this(message, (Throwable) null, code, responseHeaders, responseBody);
+ }
+
+ public ApiException(String message, Throwable throwable, int code, Map> responseHeaders) {
+ this(message, throwable, code, responseHeaders, null);
+ }
+
+ public ApiException(int code, Map> responseHeaders, String responseBody) {
+ this("Response Code: " + code + " Response Body: " + responseBody, (Throwable) null, code, responseHeaders, responseBody);
+ }
+
+ public ApiException(int code, String message) {
+ super(message);
+ this.code = code;
+ }
+
+ public ApiException(int code, String message, Map> responseHeaders, String responseBody) {
+ this(code, message);
+ this.responseHeaders = responseHeaders;
+ this.responseBody = responseBody;
+ }
+
+ /**
+ * Get the HTTP status code.
+ *
+ * @return HTTP status code
+ */
+ public int getCode() {
+ return code;
+ }
+
+ /**
+ * Get the HTTP response headers.
+ *
+ * @return A map of list of string
+ */
+ public Map> getResponseHeaders() {
+ return responseHeaders;
+ }
+
+ /**
+ * Get the HTTP response body.
+ *
+ * @return Response body in the form of string
+ */
+ public String getResponseBody() {
+ return responseBody;
+ }
+
+ @Override
+ public String toString() {
+ return "ApiException{" +
+ "code=" + code +
+ ", responseHeaders=" + responseHeaders +
+ ", responseBody='" + responseBody + '\'' +
+ '}';
+ }
+}
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/Configuration.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/Configuration.java
new file mode 100644
index 00000000000..5b715b4cce3
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/Configuration.java
@@ -0,0 +1,41 @@
+/*
+ * OpenAPI Petstore
+ * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * 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;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.4.0-SNAPSHOT")
+public class Configuration {
+ public static final String VERSION = "1.0.0";
+
+ private static ApiClient defaultApiClient = new ApiClient();
+
+ /**
+ * Get the default API client, which would be used when creating API
+ * instances without providing an API client.
+ *
+ * @return Default API client
+ */
+ public static ApiClient getDefaultApiClient() {
+ return defaultApiClient;
+ }
+
+ /**
+ * Set the default API client, which would be used when creating API
+ * instances without providing an API client.
+ *
+ * @param apiClient API client
+ */
+ public static void setDefaultApiClient(ApiClient apiClient) {
+ defaultApiClient = apiClient;
+ }
+}
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/JavaTimeFormatter.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/JavaTimeFormatter.java
new file mode 100644
index 00000000000..4d7ba4bf4db
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/JavaTimeFormatter.java
@@ -0,0 +1,64 @@
+/*
+ * OpenAPI Petstore
+ * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * 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 java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+
+/**
+ * Class that add parsing/formatting support for Java 8+ {@code OffsetDateTime} class.
+ * It's generated for java clients when {@code AbstractJavaCodegen#dateLibrary} specified as {@code java8}.
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.4.0-SNAPSHOT")
+public class JavaTimeFormatter {
+
+ private DateTimeFormatter offsetDateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
+
+ /**
+ * Get the date format used to parse/format {@code OffsetDateTime} parameters.
+ * @return DateTimeFormatter
+ */
+ public DateTimeFormatter getOffsetDateTimeFormatter() {
+ return offsetDateTimeFormatter;
+ }
+
+ /**
+ * Set the date format used to parse/format {@code OffsetDateTime} parameters.
+ * @param offsetDateTimeFormatter {@code DateTimeFormatter}
+ */
+ public void setOffsetDateTimeFormatter(DateTimeFormatter offsetDateTimeFormatter) {
+ this.offsetDateTimeFormatter = offsetDateTimeFormatter;
+ }
+
+ /**
+ * Parse the given string into {@code OffsetDateTime} object.
+ * @param str String
+ * @return {@code OffsetDateTime}
+ */
+ public OffsetDateTime parseOffsetDateTime(String str) {
+ try {
+ return OffsetDateTime.parse(str, offsetDateTimeFormatter);
+ } catch (DateTimeParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ /**
+ * Format the given {@code OffsetDateTime} object into string.
+ * @param offsetDateTime {@code OffsetDateTime}
+ * @return {@code OffsetDateTime} in string format
+ */
+ public String formatOffsetDateTime(OffsetDateTime offsetDateTime) {
+ return offsetDateTimeFormatter.format(offsetDateTime);
+ }
+}
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/Pair.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/Pair.java
new file mode 100644
index 00000000000..4199baf8396
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/Pair.java
@@ -0,0 +1,57 @@
+/*
+ * OpenAPI Petstore
+ * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * 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;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.4.0-SNAPSHOT")
+public class Pair {
+ private String name = "";
+ private String value = "";
+
+ public Pair (String name, String value) {
+ setName(name);
+ setValue(value);
+ }
+
+ private void setName(String name) {
+ if (!isValidString(name)) {
+ return;
+ }
+
+ this.name = name;
+ }
+
+ private void setValue(String value) {
+ if (!isValidString(value)) {
+ return;
+ }
+
+ this.value = value;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+
+ private boolean isValidString(String arg) {
+ if (arg == null) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/RFC3339DateFormat.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/RFC3339DateFormat.java
new file mode 100644
index 00000000000..f94cba613ba
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/RFC3339DateFormat.java
@@ -0,0 +1,57 @@
+/*
+ * OpenAPI Petstore
+ * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * 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 com.fasterxml.jackson.databind.util.StdDateFormat;
+
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.util.Date;
+import java.text.DecimalFormat;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+public class RFC3339DateFormat extends DateFormat {
+ private static final long serialVersionUID = 1L;
+ private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC");
+
+ private final StdDateFormat fmt = new StdDateFormat()
+ .withTimeZone(TIMEZONE_Z)
+ .withColonInTimeZone(true);
+
+ public RFC3339DateFormat() {
+ this.calendar = new GregorianCalendar();
+ this.numberFormat = new DecimalFormat();
+ }
+
+ @Override
+ public Date parse(String source) {
+ return parse(source, new ParsePosition(0));
+ }
+
+ @Override
+ public Date parse(String source, ParsePosition pos) {
+ return fmt.parse(source, pos);
+ }
+
+ @Override
+ public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
+ return fmt.format(date, toAppendTo, fieldPosition);
+ }
+
+ @Override
+ public Object clone() {
+ return super.clone();
+ }
+}
\ No newline at end of file
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/ServerConfiguration.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/ServerConfiguration.java
new file mode 100644
index 00000000000..59edc528a44
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/ServerConfiguration.java
@@ -0,0 +1,58 @@
+package org.openapitools.client;
+
+import java.util.Map;
+
+/**
+ * Representing a Server configuration.
+ */
+public class ServerConfiguration {
+ public String URL;
+ public String description;
+ public Map variables;
+
+ /**
+ * @param URL A URL to the target host.
+ * @param description A description of the host designated by the URL.
+ * @param variables A map between a variable name and its value. The value is used for substitution in the server's URL template.
+ */
+ public ServerConfiguration(String URL, String description, Map variables) {
+ this.URL = URL;
+ this.description = description;
+ this.variables = variables;
+ }
+
+ /**
+ * Format URL template using given variables.
+ *
+ * @param variables A map between a variable name and its value.
+ * @return Formatted URL.
+ */
+ public String URL(Map variables) {
+ String url = this.URL;
+
+ // go through variables and replace placeholders
+ for (Map.Entry variable: this.variables.entrySet()) {
+ String name = variable.getKey();
+ ServerVariable serverVariable = variable.getValue();
+ String value = serverVariable.defaultValue;
+
+ if (variables != null && variables.containsKey(name)) {
+ value = variables.get(name);
+ if (serverVariable.enumValues.size() > 0 && !serverVariable.enumValues.contains(value)) {
+ throw new IllegalArgumentException("The variable " + name + " in the server URL has invalid value " + value + ".");
+ }
+ }
+ url = url.replace("{" + name + "}", value);
+ }
+ return url;
+ }
+
+ /**
+ * Format URL template using default server variables.
+ *
+ * @return Formatted URL.
+ */
+ public String URL() {
+ return URL(null);
+ }
+}
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/ServerVariable.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/ServerVariable.java
new file mode 100644
index 00000000000..c2f13e21666
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/ServerVariable.java
@@ -0,0 +1,23 @@
+package org.openapitools.client;
+
+import java.util.HashSet;
+
+/**
+ * Representing a Server Variable for server URL template substitution.
+ */
+public class ServerVariable {
+ public String description;
+ public String defaultValue;
+ public HashSet enumValues = null;
+
+ /**
+ * @param description A description for the server variable.
+ * @param defaultValue The default value to use for substitution.
+ * @param enumValues An enumeration of string values to be used if the substitution options are from a limited set.
+ */
+ public ServerVariable(String description, String defaultValue, HashSet enumValues) {
+ this.description = description;
+ this.defaultValue = defaultValue;
+ this.enumValues = enumValues;
+ }
+}
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/StringUtil.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/StringUtil.java
new file mode 100644
index 00000000000..d002fa8f6db
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/StringUtil.java
@@ -0,0 +1,83 @@
+/*
+ * OpenAPI Petstore
+ * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * 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 java.util.Collection;
+import java.util.Iterator;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.4.0-SNAPSHOT")
+public class StringUtil {
+ /**
+ * Check if the given array contains the given value (with case-insensitive comparison).
+ *
+ * @param array The array
+ * @param value The value to search
+ * @return true if the array contains the value
+ */
+ public static boolean containsIgnoreCase(String[] array, String value) {
+ for (String str : array) {
+ if (value == null && str == null) {
+ return true;
+ }
+ if (value != null && value.equalsIgnoreCase(str)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Join an array of strings with the given separator.
+ *
+ * Note: This might be replaced by utility method from commons-lang or guava someday
+ * if one of those libraries is added as dependency.
+ *
+ *
+ * @param array The array of strings
+ * @param separator The separator
+ * @return the resulting string
+ */
+ public static String join(String[] array, String separator) {
+ int len = array.length;
+ if (len == 0) {
+ return "";
+ }
+
+ StringBuilder out = new StringBuilder();
+ out.append(array[0]);
+ for (int i = 1; i < len; i++) {
+ out.append(separator).append(array[i]);
+ }
+ return out.toString();
+ }
+
+ /**
+ * Join a list of strings with the given separator.
+ *
+ * @param list The list of strings
+ * @param separator The separator
+ * @return the resulting string
+ */
+ public static String join(Collection list, String separator) {
+ Iterator iterator = list.iterator();
+ StringBuilder out = new StringBuilder();
+ if (iterator.hasNext()) {
+ out.append(iterator.next());
+ }
+ while (iterator.hasNext()) {
+ out.append(separator).append(iterator.next());
+ }
+ return out.toString();
+ }
+}
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/api/AnotherFakeApi.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/api/AnotherFakeApi.java
new file mode 100644
index 00000000000..6df1da11854
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/api/AnotherFakeApi.java
@@ -0,0 +1,128 @@
+/*
+ * OpenAPI Petstore
+ * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * 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.api;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+
+import org.openapitools.client.ApiException;
+import org.openapitools.client.ApiClient;
+import org.openapitools.client.Configuration;
+import org.openapitools.client.Pair;
+
+import org.openapitools.client.model.Client;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringJoiner;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.4.0-SNAPSHOT")
+public class AnotherFakeApi {
+
+
+ private ApiClient apiClient;
+
+ public AnotherFakeApi() {
+ this(Configuration.getDefaultApiClient());
+ }
+
+ public AnotherFakeApi(ApiClient apiClient) {
+ this.apiClient = apiClient;
+ }
+
+ public ApiClient getApiClient() {
+ return apiClient;
+ }
+
+ public void setApiClient(ApiClient apiClient) {
+ this.apiClient = apiClient;
+ }
+
+ /**
+ * To test special tags
+ * To test special tags and operation ID starting with number
+ * @param client client model (required)
+ * @return Client
+ * @throws ApiException if fails to make API call
+ */
+ public Client call123testSpecialTags(Client client) throws ApiException {
+ return this.call123testSpecialTags(client, Collections.emptyMap());
+ }
+
+
+ /**
+ * To test special tags
+ * To test special tags and operation ID starting with number
+ * @param client client model (required)
+ * @param additionalHeaders additionalHeaders for this call
+ * @return Client
+ * @throws ApiException if fails to make API call
+ */
+ public Client call123testSpecialTags(Client client, Map additionalHeaders) throws ApiException {
+ Object localVarPostBody = client;
+
+ // verify the required parameter 'client' is set
+ if (client == null) {
+ throw new ApiException(400, "Missing the required parameter 'client' when calling call123testSpecialTags");
+ }
+
+ // create path and map variables
+ String localVarPath = "/another-fake/dummy";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+
+ localVarHeaderParams.putAll(additionalHeaders);
+
+
+
+ final String[] localVarAccepts = {
+ "application/json"
+ };
+ final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
+
+ final String[] localVarContentTypes = {
+ "application/json"
+ };
+ final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
+
+ String[] localVarAuthNames = new String[] { };
+
+ TypeReference localVarReturnType = new TypeReference() {};
+ return apiClient.invokeAPI(
+ localVarPath,
+ "PATCH",
+ localVarQueryParams,
+ localVarCollectionQueryParams,
+ localVarQueryStringJoiner.toString(),
+ localVarPostBody,
+ localVarHeaderParams,
+ localVarCookieParams,
+ localVarFormParams,
+ localVarAccept,
+ localVarContentType,
+ localVarAuthNames,
+ localVarReturnType
+ );
+ }
+
+}
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/api/DefaultApi.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/api/DefaultApi.java
new file mode 100644
index 00000000000..15e92d8c047
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/api/DefaultApi.java
@@ -0,0 +1,121 @@
+/*
+ * OpenAPI Petstore
+ * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * 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.api;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+
+import org.openapitools.client.ApiException;
+import org.openapitools.client.ApiClient;
+import org.openapitools.client.Configuration;
+import org.openapitools.client.Pair;
+
+import org.openapitools.client.model.FooGetDefaultResponse;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringJoiner;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.4.0-SNAPSHOT")
+public class DefaultApi {
+
+
+ private ApiClient apiClient;
+
+ public DefaultApi() {
+ this(Configuration.getDefaultApiClient());
+ }
+
+ public DefaultApi(ApiClient apiClient) {
+ this.apiClient = apiClient;
+ }
+
+ public ApiClient getApiClient() {
+ return apiClient;
+ }
+
+ public void setApiClient(ApiClient apiClient) {
+ this.apiClient = apiClient;
+ }
+
+ /**
+ *
+ *
+ * @return FooGetDefaultResponse
+ * @throws ApiException if fails to make API call
+ */
+ public FooGetDefaultResponse fooGet() throws ApiException {
+ return this.fooGet(Collections.emptyMap());
+ }
+
+
+ /**
+ *
+ *
+ * @param additionalHeaders additionalHeaders for this call
+ * @return FooGetDefaultResponse
+ * @throws ApiException if fails to make API call
+ */
+ public FooGetDefaultResponse fooGet(Map additionalHeaders) throws ApiException {
+ Object localVarPostBody = null;
+
+ // create path and map variables
+ String localVarPath = "/foo";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+
+ localVarHeaderParams.putAll(additionalHeaders);
+
+
+
+ final String[] localVarAccepts = {
+ "application/json"
+ };
+ final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
+
+ final String[] localVarContentTypes = {
+
+ };
+ final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
+
+ String[] localVarAuthNames = new String[] { };
+
+ TypeReference localVarReturnType = new TypeReference() {};
+ return apiClient.invokeAPI(
+ localVarPath,
+ "GET",
+ localVarQueryParams,
+ localVarCollectionQueryParams,
+ localVarQueryStringJoiner.toString(),
+ localVarPostBody,
+ localVarHeaderParams,
+ localVarCookieParams,
+ localVarFormParams,
+ localVarAccept,
+ localVarContentType,
+ localVarAuthNames,
+ localVarReturnType
+ );
+ }
+
+}
diff --git a/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/api/FakeApi.java b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/api/FakeApi.java
new file mode 100644
index 00000000000..36d3d8ad6d1
--- /dev/null
+++ b/samples/client/petstore/java/apache-httpclient-generator-version/src/main/java/org/openapitools/client/api/FakeApi.java
@@ -0,0 +1,1811 @@
+/*
+ * OpenAPI Petstore
+ * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * 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.api;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+
+import org.openapitools.client.ApiException;
+import org.openapitools.client.ApiClient;
+import org.openapitools.client.Configuration;
+import org.openapitools.client.Pair;
+
+import java.math.BigDecimal;
+import org.openapitools.client.model.ChildWithNullable;
+import org.openapitools.client.model.Client;
+import org.openapitools.client.model.EnumClass;
+import org.openapitools.client.model.FakeBigDecimalMap200Response;
+import java.io.File;
+import org.openapitools.client.model.FileSchemaTestClass;
+import org.openapitools.client.model.HealthCheckResult;
+import java.time.LocalDate;
+import java.time.OffsetDateTime;
+import org.openapitools.client.model.OuterComposite;
+import org.openapitools.client.model.OuterObjectWithEnumProperty;
+import org.openapitools.client.model.Pet;
+import org.openapitools.client.model.TestInlineFreeformAdditionalPropertiesRequest;
+import org.openapitools.client.model.User;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringJoiner;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.4.0-SNAPSHOT")
+public class FakeApi {
+
+
+ private ApiClient apiClient;
+
+ public FakeApi() {
+ this(Configuration.getDefaultApiClient());
+ }
+
+ public FakeApi(ApiClient apiClient) {
+ this.apiClient = apiClient;
+ }
+
+ public ApiClient getApiClient() {
+ return apiClient;
+ }
+
+ public void setApiClient(ApiClient apiClient) {
+ this.apiClient = apiClient;
+ }
+
+ /**
+ *
+ * for Java apache and Java native, test toUrlQueryString for maps with BegDecimal keys
+ * @return FakeBigDecimalMap200Response
+ * @throws ApiException if fails to make API call
+ */
+ public FakeBigDecimalMap200Response fakeBigDecimalMap() throws ApiException {
+ return this.fakeBigDecimalMap(Collections.emptyMap());
+ }
+
+
+ /**
+ *
+ * for Java apache and Java native, test toUrlQueryString for maps with BegDecimal keys
+ * @param additionalHeaders additionalHeaders for this call
+ * @return FakeBigDecimalMap200Response
+ * @throws ApiException if fails to make API call
+ */
+ public FakeBigDecimalMap200Response fakeBigDecimalMap(Map additionalHeaders) throws ApiException {
+ Object localVarPostBody = null;
+
+ // create path and map variables
+ String localVarPath = "/fake/BigDecimalMap";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+
+ localVarHeaderParams.putAll(additionalHeaders);
+
+
+
+ final String[] localVarAccepts = {
+ "*/*"
+ };
+ final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
+
+ final String[] localVarContentTypes = {
+
+ };
+ final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
+
+ String[] localVarAuthNames = new String[] { };
+
+ TypeReference localVarReturnType = new TypeReference() {};
+ return apiClient.invokeAPI(
+ localVarPath,
+ "GET",
+ localVarQueryParams,
+ localVarCollectionQueryParams,
+ localVarQueryStringJoiner.toString(),
+ localVarPostBody,
+ localVarHeaderParams,
+ localVarCookieParams,
+ localVarFormParams,
+ localVarAccept,
+ localVarContentType,
+ localVarAuthNames,
+ localVarReturnType
+ );
+ }
+
+ /**
+ * Health check endpoint
+ *
+ * @return HealthCheckResult
+ * @throws ApiException if fails to make API call
+ */
+ public HealthCheckResult fakeHealthGet() throws ApiException {
+ return this.fakeHealthGet(Collections.emptyMap());
+ }
+
+
+ /**
+ * Health check endpoint
+ *
+ * @param additionalHeaders additionalHeaders for this call
+ * @return HealthCheckResult
+ * @throws ApiException if fails to make API call
+ */
+ public HealthCheckResult fakeHealthGet(Map additionalHeaders) throws ApiException {
+ Object localVarPostBody = null;
+
+ // create path and map variables
+ String localVarPath = "/fake/health";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+
+ localVarHeaderParams.putAll(additionalHeaders);
+
+
+
+ final String[] localVarAccepts = {
+ "application/json"
+ };
+ final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
+
+ final String[] localVarContentTypes = {
+
+ };
+ final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
+
+ String[] localVarAuthNames = new String[] { };
+
+ TypeReference localVarReturnType = new TypeReference() {};
+ return apiClient.invokeAPI(
+ localVarPath,
+ "GET",
+ localVarQueryParams,
+ localVarCollectionQueryParams,
+ localVarQueryStringJoiner.toString(),
+ localVarPostBody,
+ localVarHeaderParams,
+ localVarCookieParams,
+ localVarFormParams,
+ localVarAccept,
+ localVarContentType,
+ localVarAuthNames,
+ localVarReturnType
+ );
+ }
+
+ /**
+ * test http signature authentication
+ *
+ * @param pet Pet object that needs to be added to the store (required)
+ * @param query1 query parameter (optional)
+ * @param header1 header parameter (optional)
+ * @throws ApiException if fails to make API call
+ */
+ public void fakeHttpSignatureTest(Pet pet, String query1, String header1) throws ApiException {
+ this.fakeHttpSignatureTest(pet, query1, header1, Collections.emptyMap());
+ }
+
+
+ /**
+ * test http signature authentication
+ *
+ * @param pet Pet object that needs to be added to the store (required)
+ * @param query1 query parameter (optional)
+ * @param header1 header parameter (optional)
+ * @param additionalHeaders additionalHeaders for this call
+ * @throws ApiException if fails to make API call
+ */
+ public void fakeHttpSignatureTest(Pet pet, String query1, String header1, Map additionalHeaders) throws ApiException {
+ Object localVarPostBody = pet;
+
+ // verify the required parameter 'pet' is set
+ if (pet == null) {
+ throw new ApiException(400, "Missing the required parameter 'pet' when calling fakeHttpSignatureTest");
+ }
+
+ // create path and map variables
+ String localVarPath = "/fake/http-signature-test";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+ localVarQueryParams.addAll(apiClient.parameterToPair("query_1", query1));
+ if (header1 != null)
+ localVarHeaderParams.put("header_1", apiClient.parameterToString(header1));
+
+ localVarHeaderParams.putAll(additionalHeaders);
+
+
+
+ final String[] localVarAccepts = {
+
+ };
+ final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
+
+ final String[] localVarContentTypes = {
+ "application/json", "application/xml"
+ };
+ final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
+
+ String[] localVarAuthNames = new String[] { "http_signature_test" };
+
+ apiClient.invokeAPI(
+ localVarPath,
+ "GET",
+ localVarQueryParams,
+ localVarCollectionQueryParams,
+ localVarQueryStringJoiner.toString(),
+ localVarPostBody,
+ localVarHeaderParams,
+ localVarCookieParams,
+ localVarFormParams,
+ localVarAccept,
+ localVarContentType,
+ localVarAuthNames,
+ null
+ );
+ }
+
+ /**
+ *
+ * Test serialization of outer boolean types
+ * @param body Input boolean as post body (optional)
+ * @return Boolean
+ * @throws ApiException if fails to make API call
+ */
+ public Boolean fakeOuterBooleanSerialize(Boolean body) throws ApiException {
+ return this.fakeOuterBooleanSerialize(body, Collections.emptyMap());
+ }
+
+
+ /**
+ *
+ * Test serialization of outer boolean types
+ * @param body Input boolean as post body (optional)
+ * @param additionalHeaders additionalHeaders for this call
+ * @return Boolean
+ * @throws ApiException if fails to make API call
+ */
+ public Boolean fakeOuterBooleanSerialize(Boolean body, Map additionalHeaders) throws ApiException {
+ Object localVarPostBody = body;
+
+ // create path and map variables
+ String localVarPath = "/fake/outer/boolean";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+
+ localVarHeaderParams.putAll(additionalHeaders);
+
+
+
+ final String[] localVarAccepts = {
+ "*/*"
+ };
+ final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
+
+ final String[] localVarContentTypes = {
+ "application/json"
+ };
+ final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
+
+ String[] localVarAuthNames = new String[] { };
+
+ TypeReference localVarReturnType = new TypeReference() {};
+ return apiClient.invokeAPI(
+ localVarPath,
+ "POST",
+ localVarQueryParams,
+ localVarCollectionQueryParams,
+ localVarQueryStringJoiner.toString(),
+ localVarPostBody,
+ localVarHeaderParams,
+ localVarCookieParams,
+ localVarFormParams,
+ localVarAccept,
+ localVarContentType,
+ localVarAuthNames,
+ localVarReturnType
+ );
+ }
+
+ /**
+ *
+ * Test serialization of object with outer number type
+ * @param outerComposite Input composite as post body (optional)
+ * @return OuterComposite
+ * @throws ApiException if fails to make API call
+ */
+ public OuterComposite fakeOuterCompositeSerialize(OuterComposite outerComposite) throws ApiException {
+ return this.fakeOuterCompositeSerialize(outerComposite, Collections.emptyMap());
+ }
+
+
+ /**
+ *
+ * Test serialization of object with outer number type
+ * @param outerComposite Input composite as post body (optional)
+ * @param additionalHeaders additionalHeaders for this call
+ * @return OuterComposite
+ * @throws ApiException if fails to make API call
+ */
+ public OuterComposite fakeOuterCompositeSerialize(OuterComposite outerComposite, Map additionalHeaders) throws ApiException {
+ Object localVarPostBody = outerComposite;
+
+ // create path and map variables
+ String localVarPath = "/fake/outer/composite";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+
+ localVarHeaderParams.putAll(additionalHeaders);
+
+
+
+ final String[] localVarAccepts = {
+ "*/*"
+ };
+ final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
+
+ final String[] localVarContentTypes = {
+ "application/json"
+ };
+ final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
+
+ String[] localVarAuthNames = new String[] { };
+
+ TypeReference localVarReturnType = new TypeReference() {};
+ return apiClient.invokeAPI(
+ localVarPath,
+ "POST",
+ localVarQueryParams,
+ localVarCollectionQueryParams,
+ localVarQueryStringJoiner.toString(),
+ localVarPostBody,
+ localVarHeaderParams,
+ localVarCookieParams,
+ localVarFormParams,
+ localVarAccept,
+ localVarContentType,
+ localVarAuthNames,
+ localVarReturnType
+ );
+ }
+
+ /**
+ *
+ * Test serialization of outer number types
+ * @param body Input number as post body (optional)
+ * @return BigDecimal
+ * @throws ApiException if fails to make API call
+ */
+ public BigDecimal fakeOuterNumberSerialize(BigDecimal body) throws ApiException {
+ return this.fakeOuterNumberSerialize(body, Collections.emptyMap());
+ }
+
+
+ /**
+ *
+ * Test serialization of outer number types
+ * @param body Input number as post body (optional)
+ * @param additionalHeaders additionalHeaders for this call
+ * @return BigDecimal
+ * @throws ApiException if fails to make API call
+ */
+ public BigDecimal fakeOuterNumberSerialize(BigDecimal body, Map additionalHeaders) throws ApiException {
+ Object localVarPostBody = body;
+
+ // create path and map variables
+ String localVarPath = "/fake/outer/number";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+
+ localVarHeaderParams.putAll(additionalHeaders);
+
+
+
+ final String[] localVarAccepts = {
+ "*/*"
+ };
+ final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
+
+ final String[] localVarContentTypes = {
+ "application/json"
+ };
+ final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
+
+ String[] localVarAuthNames = new String[] { };
+
+ TypeReference localVarReturnType = new TypeReference() {};
+ return apiClient.invokeAPI(
+ localVarPath,
+ "POST",
+ localVarQueryParams,
+ localVarCollectionQueryParams,
+ localVarQueryStringJoiner.toString(),
+ localVarPostBody,
+ localVarHeaderParams,
+ localVarCookieParams,
+ localVarFormParams,
+ localVarAccept,
+ localVarContentType,
+ localVarAuthNames,
+ localVarReturnType
+ );
+ }
+
+ /**
+ *
+ * Test serialization of outer string types
+ * @param body Input string as post body (optional)
+ * @return String
+ * @throws ApiException if fails to make API call
+ */
+ public String fakeOuterStringSerialize(String body) throws ApiException {
+ return this.fakeOuterStringSerialize(body, Collections.emptyMap());
+ }
+
+
+ /**
+ *
+ * Test serialization of outer string types
+ * @param body Input string as post body (optional)
+ * @param additionalHeaders additionalHeaders for this call
+ * @return String
+ * @throws ApiException if fails to make API call
+ */
+ public String fakeOuterStringSerialize(String body, Map additionalHeaders) throws ApiException {
+ Object localVarPostBody = body;
+
+ // create path and map variables
+ String localVarPath = "/fake/outer/string";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap