();
+ // 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
+ */
+ @Deprecated
+ public int getStatusCode()
+ {
+ return lastStatusCode.get();
+ }
+
+ /**
+ * Gets the response headers of the previous request
+ *
+ * @return Response headers
+ */
+ @Deprecated
+ public Map> getResponseHeaders()
+ {
+ return lastResponseHeaders.get();
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Set the User-Agent header's value (by adding to the default header map).
+ *
+ * @param userAgent
+ * User agent
+ * @return API client
+ */
+ public final 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 final 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 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
+ */
+ protected 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
+ */
+ protected 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( ClassicHttpResponse 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
+ String content = EntityUtils.toString(entity);
+
+ if( "".equals(content) ) { // returns null for empty body
+ return null;
+ }
+
+ return objectMapper.readValue(content, valueType);
+ } else if( mimeType.toLowerCase().startsWith("text/") ) {
+ // convert input stream to string
+ return (T) EntityUtils.toString(entity);
+ } else {
+ Map> responseHeaders = transformResponseHeaders(response.getHeaders());
+ throw new ApiException(
+ "Deserialization for content type '" + mimeType + "' not supported for type '" + valueType + "'",
+ response.getCode(),
+ responseHeaders,
+ EntityUtils.toString(entity));
+ }
+ }
+
+ protected File downloadFileFromResponse( ClassicHttpResponse 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();
+ }
+
+ /**
+ * Returns the URL of the client as defined by the server (if exists) or the base path.
+ *
+ * @return The URL for the client.
+ */
+ public String getBaseURL()
+ {
+ String baseURL;
+ if( serverIndex != null ) {
+ if( serverIndex < 0 || serverIndex >= servers.size() ) {
+ throw new ArrayIndexOutOfBoundsException(
+ String
+ .format(
+ Locale.ROOT,
+ "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;
+ }
+ return baseURL;
+ }
+
+ /**
+ * Build full URL by concatenating base URL, 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
+ */
+ protected
+ String
+ buildUrl( String path, List queryParams, List collectionQueryParams, String urlQueryDeepObject )
+ {
+ String baseURL = getBaseURL();
+
+ 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;
+ }
+
+ /**
+ * Creates an HttpClientResponseHandler for processing HTTP responses. Wraps checked exceptions (ParseException,
+ * ApiException) as IOException since the handler interface only allows IOException to be thrown.
+ *
+ * @param
+ * Type
+ * @param returnType
+ * Return type
+ * @return HttpClientResponseHandler instance
+ */
+ protected HttpClientResponseHandler createResponseHandler( TypeReference returnType )
+ {
+ return response -> {
+ try {
+ return processResponse(response, returnType);
+ }
+ catch( ParseException | ApiException e ) {
+ // Wrap exceptions as IOException since handler can only throw IOException
+ throw new IOException("Failed to process response: " + e.getMessage(), e);
+ }
+ };
+ }
+
+ protected T processResponse( ClassicHttpResponse response, TypeReference returnType )
+ throws ApiException,
+ IOException,
+ ParseException
+ {
+ int statusCode = response.getCode();
+ lastStatusCode.set(statusCode);
+ if( statusCode == HttpStatus.SC_NO_CONTENT ) {
+ return null;
+ }
+
+ Map> responseHeaders = transformResponseHeaders(response.getHeaders());
+ lastResponseHeaders.set(responseHeaders);
+
+ 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 {
+ HttpClientResponseHandler responseHandler = createResponseHandler(returnType);
+ return httpClient.execute(builder.build(), context, responseHandler);
+ }
+ catch( IOException 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
+ */
+ protected 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/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/ApiException.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/ApiException.java
new file mode 100644
index 000000000..b8ab4534c
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/ApiException.java
@@ -0,0 +1,129 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache;
+
+import java.util.List;
+import java.util.Map;
+
+public class ApiException extends Exception
+{
+ private static final long serialVersionUID = 1L;
+
+ private int code = 0;
+ private transient 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/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/BaseApi.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/BaseApi.java
new file mode 100644
index 000000000..7203f9e7f
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/BaseApi.java
@@ -0,0 +1,181 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache;
+
+import java.util.Collections;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+
+public abstract class BaseApi
+{
+
+ protected ApiClient apiClient;
+
+ public BaseApi()
+ {
+ this(Configuration.getDefaultApiClient());
+ }
+
+ public BaseApi( ApiClient apiClient )
+ {
+ this.apiClient = apiClient;
+ }
+
+ public ApiClient getApiClient()
+ {
+ return apiClient;
+ }
+
+ public void setApiClient( ApiClient apiClient )
+ {
+ this.apiClient = apiClient;
+ }
+
+ /**
+ * Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
+ *
+ * @param url
+ * The URL for the request, either full URL or only the path.
+ * @param method
+ * The HTTP method for the request.
+ * @throws ApiException
+ * if fails to make API call.
+ */
+ public void invokeAPI( String url, String method )
+ throws ApiException
+ {
+ invokeAPI(url, method, null, null, Collections.emptyMap());
+ }
+
+ /**
+ * Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
+ *
+ * @param url
+ * The URL for the request, either full URL or only the path.
+ * @param method
+ * The HTTP method for the request.
+ * @param additionalHeaders
+ * Additional headers for the request.
+ * @throws ApiException
+ * if fails to make API call.
+ */
+ public void invokeAPI( String url, String method, Map additionalHeaders )
+ throws ApiException
+ {
+ invokeAPI(url, method, null, null, additionalHeaders);
+ }
+
+ /**
+ * Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
+ *
+ * @param url
+ * The URL for the request, either full URL or only the path.
+ * @param method
+ * The HTTP method for the request.
+ * @param request
+ * The request object.
+ * @throws ApiException
+ * if fails to make API call.
+ */
+ public void invokeAPI( String url, String method, Object request )
+ throws ApiException
+ {
+ invokeAPI(url, method, request, null, Collections.emptyMap());
+ }
+
+ /**
+ * Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
+ *
+ * @param url
+ * The URL for the request, either full URL or only the path.
+ * @param method
+ * The HTTP method for the request.
+ * @param request
+ * The request object.
+ * @param additionalHeaders
+ * Additional headers for the request.
+ * @throws ApiException
+ * if fails to make API call.
+ */
+ public void invokeAPI( String url, String method, Object request, Map additionalHeaders )
+ throws ApiException
+ {
+ invokeAPI(url, method, request, null, additionalHeaders);
+ }
+
+ /**
+ * Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
+ *
+ * @param url
+ * The URL for the request, either full URL or only the path.
+ * @param method
+ * The HTTP method for the request.
+ * @param returnType
+ * The return type.
+ * @return The API response in the specified type.
+ * @throws ApiException
+ * if fails to make API call.
+ */
+ public T invokeAPI( String url, String method, TypeReference returnType )
+ throws ApiException
+ {
+ return invokeAPI(url, method, null, returnType, Collections.emptyMap());
+ }
+
+ /**
+ * Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
+ *
+ * @param url
+ * The URL for the request, either full URL or only the path.
+ * @param method
+ * The HTTP method for the request.
+ * @param request
+ * The request object.
+ * @param returnType
+ * The return type.
+ * @return The API response in the specified type.
+ * @throws ApiException
+ * if fails to make API call.
+ */
+ public T invokeAPI( String url, String method, Object request, TypeReference returnType )
+ throws ApiException
+ {
+ return invokeAPI(url, method, request, returnType, Collections.emptyMap());
+ }
+
+ /**
+ * Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
+ *
+ * @param url
+ * The URL for the request, either full URL or only the path.
+ * @param method
+ * The HTTP method for the request.
+ * @param request
+ * The request object.
+ * @param returnType
+ * The return type.
+ * @param additionalHeaders
+ * Additional headers for the request.
+ * @return The API response in the specified type.
+ * @throws ApiException
+ * if fails to make API call.
+ */
+ public abstract T invokeAPI(
+ String url,
+ String method,
+ Object request,
+ TypeReference returnType,
+ Map additionalHeaders )
+ throws ApiException;
+}
diff --git a/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/Configuration.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/Configuration.java
new file mode 100644
index 000000000..8978044d7
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/Configuration.java
@@ -0,0 +1,67 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache;
+
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
+
+public class Configuration
+{
+ public static final String VERSION = "0.0.1";
+
+ private static final AtomicReference defaultApiClient = new AtomicReference<>();
+ private static volatile Supplier apiClientFactory = ApiClient::new;
+
+ /**
+ * 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()
+ {
+ ApiClient client = defaultApiClient.get();
+ if( client == null ) {
+ client = defaultApiClient.updateAndGet(val -> {
+ if( val != null ) { // changed by another thread
+ return val;
+ }
+ return apiClientFactory.get();
+ });
+ }
+ return client;
+ }
+
+ /**
+ * 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.set(apiClient);
+ }
+
+ /**
+ * set the callback used to create new ApiClient objects
+ */
+ public static void setApiClientFactory( Supplier factory )
+ {
+ apiClientFactory = Objects.requireNonNull(factory);
+ }
+
+ private Configuration()
+ {
+ }
+}
diff --git a/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/Pair.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/Pair.java
new file mode 100644
index 000000000..c7e9a9711
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/Pair.java
@@ -0,0 +1,40 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache;
+
+public class Pair
+{
+ private final String name;
+ private final String value;
+
+ public Pair( String name, String value )
+ {
+ this.name = isValidString(name) ? name : "";
+ this.value = isValidString(value) ? value : "";
+ }
+
+ public String getName()
+ {
+ return this.name;
+ }
+
+ public String getValue()
+ {
+ return this.value;
+ }
+
+ private static boolean isValidString( String arg )
+ {
+ return arg != null;
+ }
+}
diff --git a/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/RFC3339DateFormat.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/RFC3339DateFormat.java
new file mode 100644
index 000000000..8d841d0bd
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/RFC3339DateFormat.java
@@ -0,0 +1,61 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache;
+
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import com.fasterxml.jackson.databind.util.StdDateFormat;
+
+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();
+ }
+}
diff --git a/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/RFC3339InstantDeserializer.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/RFC3339InstantDeserializer.java
new file mode 100644
index 000000000..ae5560a88
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/RFC3339InstantDeserializer.java
@@ -0,0 +1,108 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeFeature;
+import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer;
+
+public class RFC3339InstantDeserializer extends InstantDeserializer
+{
+ private static final long serialVersionUID = 1L;
+ private final static boolean DEFAULT_NORMALIZE_ZONE_ID =
+ JavaTimeFeature.NORMALIZE_DESERIALIZED_ZONE_ID.enabledByDefault();
+ private final static boolean DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS =
+ JavaTimeFeature.ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS.enabledByDefault();
+
+ public static final RFC3339InstantDeserializer INSTANT =
+ new RFC3339InstantDeserializer<>(
+ Instant.class,
+ DateTimeFormatter.ISO_INSTANT,
+ Instant::from,
+ a -> Instant.ofEpochMilli(a.value),
+ a -> Instant.ofEpochSecond(a.integer, a.fraction),
+ null,
+ true, // yes, replace zero offset with Z
+ DEFAULT_NORMALIZE_ZONE_ID,
+ DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS);
+
+ public static final RFC3339InstantDeserializer OFFSET_DATE_TIME =
+ new RFC3339InstantDeserializer<>(
+ OffsetDateTime.class,
+ DateTimeFormatter.ISO_OFFSET_DATE_TIME,
+ OffsetDateTime::from,
+ a -> OffsetDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId),
+ a -> OffsetDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId),
+ (
+ d,
+ z ) -> (d.isEqual(OffsetDateTime.MIN) || d.isEqual(OffsetDateTime.MAX)
+ ? d
+ : d.withOffsetSameInstant(z.getRules().getOffset(d.toLocalDateTime()))),
+ true, // yes, replace zero offset with Z
+ DEFAULT_NORMALIZE_ZONE_ID,
+ DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS);
+
+ public static final RFC3339InstantDeserializer ZONED_DATE_TIME =
+ new RFC3339InstantDeserializer<>(
+ ZonedDateTime.class,
+ DateTimeFormatter.ISO_ZONED_DATE_TIME,
+ ZonedDateTime::from,
+ a -> ZonedDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId),
+ a -> ZonedDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId),
+ ZonedDateTime::withZoneSameInstant,
+ false, // keep zero offset and Z separate since zones explicitly supported
+ DEFAULT_NORMALIZE_ZONE_ID,
+ DEFAULT_ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS);
+
+ protected RFC3339InstantDeserializer(
+ Class supportedType,
+ DateTimeFormatter formatter,
+ Function parsedToValue,
+ Function fromMilliseconds,
+ Function fromNanoseconds,
+ BiFunction adjust,
+ boolean replaceZeroOffsetAsZ,
+ boolean normalizeZoneId,
+ boolean readNumericStringsAsTimestamp )
+ {
+ super(
+ supportedType,
+ formatter,
+ parsedToValue,
+ fromMilliseconds,
+ fromNanoseconds,
+ adjust,
+ replaceZeroOffsetAsZ,
+ normalizeZoneId,
+ readNumericStringsAsTimestamp);
+ }
+
+ @Override
+ protected T _fromString( JsonParser p, DeserializationContext ctxt, String string0 )
+ throws IOException
+ {
+ return super._fromString(p, ctxt, string0.replace(' ', 'T'));
+ }
+}
diff --git a/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/RFC3339JavaTimeModule.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/RFC3339JavaTimeModule.java
new file mode 100644
index 000000000..ce882de8c
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/RFC3339JavaTimeModule.java
@@ -0,0 +1,40 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache;
+
+import java.time.Instant;
+import java.time.OffsetDateTime;
+import java.time.ZonedDateTime;
+
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+public class RFC3339JavaTimeModule extends SimpleModule
+{
+ private static final long serialVersionUID = 1L;
+
+ public RFC3339JavaTimeModule()
+ {
+ super("RFC3339JavaTimeModule");
+ }
+
+ @Override
+ public void setupModule( SetupContext context )
+ {
+ super.setupModule(context);
+
+ addDeserializer(Instant.class, RFC3339InstantDeserializer.INSTANT);
+ addDeserializer(OffsetDateTime.class, RFC3339InstantDeserializer.OFFSET_DATE_TIME);
+ addDeserializer(ZonedDateTime.class, RFC3339InstantDeserializer.ZONED_DATE_TIME);
+ }
+
+}
diff --git a/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/ServerConfiguration.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/ServerConfiguration.java
new file mode 100644
index 000000000..3c91ed3b8
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/ServerConfiguration.java
@@ -0,0 +1,80 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache;
+
+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/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/ServerVariable.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/ServerVariable.java
new file mode 100644
index 000000000..e2e4a3d06
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/ServerVariable.java
@@ -0,0 +1,40 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache;
+
+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/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/StringUtil.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/StringUtil.java
new file mode 100644
index 000000000..8fe49ac89
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/StringUtil.java
@@ -0,0 +1,91 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+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/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/auth/ApiKeyAuth.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/auth/ApiKeyAuth.java
new file mode 100644
index 000000000..87f4fe832
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/auth/ApiKeyAuth.java
@@ -0,0 +1,86 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache.auth;
+
+import java.util.List;
+import java.util.Map;
+
+import com.sap.cloud.sdk.services.openapi.apache.Pair;
+
+public class ApiKeyAuth implements Authentication
+{
+ private final String location;
+ private final String paramName;
+
+ private String apiKey;
+ private String apiKeyPrefix;
+
+ public ApiKeyAuth( String location, String paramName )
+ {
+ this.location = location;
+ this.paramName = paramName;
+ }
+
+ public String getLocation()
+ {
+ return location;
+ }
+
+ public String getParamName()
+ {
+ return paramName;
+ }
+
+ public String getApiKey()
+ {
+ return apiKey;
+ }
+
+ public void setApiKey( String apiKey )
+ {
+ this.apiKey = apiKey;
+ }
+
+ public String getApiKeyPrefix()
+ {
+ return apiKeyPrefix;
+ }
+
+ public void setApiKeyPrefix( String apiKeyPrefix )
+ {
+ this.apiKeyPrefix = apiKeyPrefix;
+ }
+
+ @Override
+ public
+ void
+ applyToParams( List queryParams, Map headerParams, Map cookieParams )
+ {
+ if( apiKey == null ) {
+ return;
+ }
+ String value;
+ if( apiKeyPrefix != null ) {
+ value = apiKeyPrefix + " " + apiKey;
+ } else {
+ value = apiKey;
+ }
+ if( "query".equals(location) ) {
+ queryParams.add(new Pair(paramName, value));
+ } else if( "header".equals(location) ) {
+ headerParams.put(paramName, value);
+ } else if( "cookie".equals(location) ) {
+ cookieParams.put(paramName, value);
+ }
+ }
+}
diff --git a/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/auth/Authentication.java b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/auth/Authentication.java
new file mode 100644
index 000000000..92d1e48b2
--- /dev/null
+++ b/datamodel/openapi/openapi-core/src/main/java/com/sap/cloud/sdk/services/openapi/apache/auth/Authentication.java
@@ -0,0 +1,33 @@
+/*
+ * Prompt Registry API
+ * Prompt Storage service for Design time & Runtime prompt templates.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package com.sap.cloud.sdk.services.openapi.apache.auth;
+
+import java.util.List;
+import java.util.Map;
+
+import com.sap.cloud.sdk.services.openapi.apache.Pair;
+
+public interface Authentication
+{
+ /**
+ * Apply authentication settings to header and query params.
+ *
+ * @param queryParams
+ * List of query parameters
+ * @param headerParams
+ * Map of header parameters
+ * @param cookieParams
+ * Map of cookie parameters
+ */
+ void applyToParams( List queryParams, Map headerParams, Map