forked from loafle/openapi-generator-original
* add apex petstore samples, shell scripts, batch files * add wording "beta" to Apex help
395 lines
14 KiB
OpenEdge ABL
395 lines
14 KiB
OpenEdge ABL
public class Swagger {
|
|
private static final String HEADER_CONTENT_TYPE = 'Content-Type';
|
|
private static final String HEADER_ACCEPT = 'Accept';
|
|
private static final String HEADER_ACCEPT_DELIMITER = ',';
|
|
private static final Map<String, String> DELIMITERS = new Map<String, String> {
|
|
'csv' => ',',
|
|
'ssv' => ' ',
|
|
'tsv' => '\t',
|
|
'pipes' => '|'
|
|
};
|
|
|
|
public class Param {
|
|
private String name, value;
|
|
|
|
public Param(String name, String value) {
|
|
this.name = name;
|
|
this.value = value;
|
|
}
|
|
|
|
public override String toString() {
|
|
return EncodingUtil.urlEncode(name, 'UTF-8') + '='
|
|
+ EncodingUtil.urlEncode(value, 'UTF-8');
|
|
}
|
|
}
|
|
|
|
public interface Authentication {
|
|
void apply(Map<String, Object> headers, List<Param> query);
|
|
}
|
|
|
|
public interface MappedProperties {
|
|
Map<String, String> getPropertyMappings();
|
|
}
|
|
|
|
public abstract class ApiKeyAuth implements Authentication {
|
|
protected final String paramName;
|
|
protected String key = '';
|
|
|
|
public void setApiKey(String key) {
|
|
this.key = key;
|
|
}
|
|
|
|
@TestVisible
|
|
private String getApiKey() {
|
|
return key;
|
|
}
|
|
}
|
|
|
|
public class ApiKeyQueryAuth extends ApiKeyAuth {
|
|
public ApiKeyQueryAuth(String paramName) {
|
|
this.paramName = paramName;
|
|
}
|
|
|
|
public void apply(Map<String, Object> headers, List<Param> query) {
|
|
query.add(new Param(paramName, key));
|
|
}
|
|
}
|
|
|
|
public class ApiKeyHeaderAuth extends ApiKeyAuth {
|
|
public ApiKeyHeaderAuth(String paramName) {
|
|
this.paramName = paramName;
|
|
}
|
|
|
|
public void apply(Map<String, Object> headers, List<Param> query) {
|
|
headers.put(paramName, key);
|
|
}
|
|
}
|
|
|
|
public class HttpBasicAuth implements Authentication {
|
|
private String username = '';
|
|
private String password = '';
|
|
|
|
public void setUsername(String username) {
|
|
this.username = username;
|
|
}
|
|
|
|
public void setPassword(String password) {
|
|
this.password = password;
|
|
}
|
|
|
|
public void setCredentials(String username, String password) {
|
|
setUsername(username);
|
|
setPassword(password);
|
|
}
|
|
|
|
@TestVisible
|
|
private String getHeaderValue() {
|
|
return 'Basic ' + EncodingUtil.base64Encode(Blob.valueOf(username + ':' + password));
|
|
}
|
|
|
|
public void apply(Map<String, Object> headers, List<Param> query) {
|
|
headers.put('Authorization', getHeaderValue());
|
|
}
|
|
}
|
|
|
|
public class OAuth2 implements Authentication {
|
|
private String accessToken = '';
|
|
|
|
public void setAccessToken(String accessToken) {
|
|
this.accessToken = accessToken;
|
|
}
|
|
|
|
@TestVisible
|
|
private String getHeaderValue() {
|
|
return 'Bearer ' + accessToken;
|
|
}
|
|
|
|
public void apply(Map<String, Object> headers, List<Param> query) {
|
|
headers.put('Authorization', getHeaderValue());
|
|
}
|
|
}
|
|
|
|
public class ApiException extends Exception {
|
|
private final Integer code;
|
|
private final String status;
|
|
private final Map<String, String> headers;
|
|
private final String body;
|
|
|
|
public ApiException(Integer code, String status, Map<String, String> headers, String body) {
|
|
this('API returned HTTP ' + code + ': ' + status);
|
|
this.code = code;
|
|
this.status = status;
|
|
this.headers = headers;
|
|
this.body = body;
|
|
}
|
|
|
|
public Integer getStatusCode() {
|
|
return code;
|
|
}
|
|
|
|
public String getStatus() {
|
|
return status;
|
|
}
|
|
|
|
public Map<String, String> getHeaders() {
|
|
return headers;
|
|
}
|
|
|
|
public String getBody() {
|
|
return body;
|
|
}
|
|
}
|
|
|
|
public virtual class ApiClient {
|
|
protected String preferredContentType = 'application/json';
|
|
protected String preferredAccept = 'application/json';
|
|
protected final String basePath;
|
|
|
|
@TestVisible
|
|
protected final Map<String, Authentication> authentications = new Map<String, Authentication>();
|
|
|
|
public virtual Authentication getAuthentication(String authName) {
|
|
return authentications.get(authName);
|
|
}
|
|
|
|
public virtual void setUsername(String username) {
|
|
for (Authentication auth : authentications.values()) {
|
|
if (auth instanceof HttpBasicAuth) {
|
|
((HttpBasicAuth) auth).setUsername(username);
|
|
return;
|
|
}
|
|
}
|
|
throw new NoSuchElementException('No HTTP basic authentication configured!');
|
|
}
|
|
|
|
public virtual void setPassword(String password) {
|
|
for (Authentication auth : authentications.values()) {
|
|
if (auth instanceof HttpBasicAuth) {
|
|
((HttpBasicAuth) auth).setPassword(password);
|
|
return;
|
|
}
|
|
}
|
|
throw new NoSuchElementException('No HTTP basic authentication configured!');
|
|
}
|
|
|
|
public virtual void setCredentials(String username, String password) {
|
|
for (Authentication auth : authentications.values()) {
|
|
if (auth instanceof HttpBasicAuth) {
|
|
((HttpBasicAuth) auth).setCredentials(username, password);
|
|
return;
|
|
}
|
|
}
|
|
throw new NoSuchElementException('No HTTP basic authentication configured!');
|
|
}
|
|
|
|
public virtual void setApiKey(String apiKey) {
|
|
for (Authentication auth : authentications.values()) {
|
|
if (auth instanceof ApiKeyAuth) {
|
|
((ApiKeyAuth) auth).setApiKey(apiKey);
|
|
return;
|
|
}
|
|
}
|
|
throw new NoSuchElementException('No API key authentication configured!');
|
|
}
|
|
|
|
public virtual void setAccessToken(String accessToken) {
|
|
for (Authentication auth : authentications.values()) {
|
|
if (auth instanceof OAuth2) {
|
|
((OAuth2) auth).setAccessToken(accessToken);
|
|
return;
|
|
}
|
|
}
|
|
throw new NoSuchElementException('No OAuth2 authentication configured!');
|
|
}
|
|
|
|
public List<Param> makeParams(String name, List<Object> values) {
|
|
List<Param> pairs = new List<Param>();
|
|
for (Object value : new List<Object>(values)) {
|
|
pairs.add(new Param(name, String.valueOf(value)));
|
|
}
|
|
return pairs;
|
|
}
|
|
|
|
public List<Param> makeParam(String name, List<Object> values, String format) {
|
|
List<Param> pairs = new List<Param>();
|
|
if (values != null) {
|
|
String delimiter = DELIMITERS.get(format);
|
|
pairs.add(new Param(name, String.join(values, delimiter)));
|
|
}
|
|
return pairs;
|
|
}
|
|
|
|
public List<Param> makeParam(String name, Object value) {
|
|
List<Param> pairs = new List<Param>();
|
|
if (value != null) {
|
|
pairs.add(new Param(name, String.valueOf(value)));
|
|
}
|
|
return pairs;
|
|
}
|
|
|
|
public virtual void assertNotNull(Object required, String parameterName) {
|
|
if (required == null) {
|
|
Exception e = new NullPointerException();
|
|
e.setMessage('Argument cannot be null: ' + parameterName);
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
public virtual Object invoke(
|
|
String method, String path, Object body, List<Param> query, List<Param> form,
|
|
Map<String, Object> pathParams, Map<String, Object> headers, List<String> accepts,
|
|
List<String> contentTypes, List<String> authMethods, Type returnType) {
|
|
|
|
HttpResponse res = getResponse(method, path, body, query, form, pathParams, headers,
|
|
accepts, contentTypes, authMethods);
|
|
|
|
Integer code = res.getStatusCode();
|
|
Boolean isFailure = code / 100 != 2;
|
|
if (isFailure) {
|
|
throw new ApiException(code, res.getStatus(), getHeaders(res), res.getBody());
|
|
} else if (returnType != null) {
|
|
return toReturnValue(res.getBody(), returnType, res.getHeader('Content-Type'));
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual Map<String, String> getHeaders(HttpResponse res) {
|
|
Map<String, String> headers = new Map<String, String>();
|
|
List<String> headerKeys = res.getHeaderKeys();
|
|
for (String headerKey : headerKeys) {
|
|
headers.put(headerKey, res.getHeader(headerKey));
|
|
}
|
|
return headers;
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual Object toReturnValue(String body, Type returnType, String contentType) {
|
|
if (contentType == 'application/json') {
|
|
Object o = returnType.newInstance();
|
|
if (o instanceof MappedProperties) {
|
|
Map<String, String> propertyMappings = ((MappedProperties) o).getPropertyMappings();
|
|
for (String baseName : propertyMappings.keySet()) {
|
|
body = body.replaceAll('"' + baseName + '"\\s*:',
|
|
'"' + propertyMappings.get(baseName) + '":');
|
|
}
|
|
}
|
|
JsonParser parser = Json.createParser(body);
|
|
parser.nextToken();
|
|
return parser.readValueAs(returnType);
|
|
}
|
|
return body;
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual HttpResponse getResponse(
|
|
String method, String path, Object body, List<Param> query, List<Param> form,
|
|
Map<String, Object> pathParams, Map<String, Object> headers, List<String> accepts,
|
|
List<String> contentTypes, List<String> authMethods) {
|
|
|
|
HttpRequest req = new HttpRequest();
|
|
applyAuthentication(authMethods, headers, query);
|
|
req.setMethod(method);
|
|
req.setEndpoint(toEndpoint(path, pathParams, query));
|
|
String contentType = setContentTypeHeader(contentTypes, headers);
|
|
setAcceptHeader(accepts, headers);
|
|
setHeaders(req, headers);
|
|
|
|
if (method != 'GET') {
|
|
req.setBody(toBody(contentType, body, form));
|
|
}
|
|
|
|
return new Http().send(req);
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual void setHeaders(HttpRequest req, Map<String, Object> headers) {
|
|
for (String headerName : headers.keySet()) {
|
|
req.setHeader(headerName, String.valueOf(headers.get(headerName)));
|
|
}
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual String toBody(String contentType, Object body, List<Param> form) {
|
|
if (contentType.contains('application/x-www-form-urlencoded')) {
|
|
return paramsToString(form);
|
|
} else if (contentType.contains('application/json')) {
|
|
return Json.serialize(body);
|
|
}
|
|
return String.valueOf(body);
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual String setContentTypeHeader(List<String> contentTypes,
|
|
Map<String, Object> headers) {
|
|
if (contentTypes.isEmpty()) {
|
|
headers.put(HEADER_CONTENT_TYPE, preferredContentType);
|
|
return preferredContentType;
|
|
}
|
|
for (String contentType : contentTypes) {
|
|
if (preferredContentType == contentType) {
|
|
headers.put(HEADER_CONTENT_TYPE, contentType);
|
|
return contentType;
|
|
}
|
|
}
|
|
String contentType = contentTypes.get(0);
|
|
headers.put(HEADER_CONTENT_TYPE, contentType);
|
|
return contentType;
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual void setAcceptHeader(List<String> accepts, Map<String, Object> headers) {
|
|
for (String accept : accepts) {
|
|
if (preferredAccept == accept) {
|
|
headers.put(HEADER_ACCEPT, accept);
|
|
return;
|
|
}
|
|
}
|
|
if (!accepts.isEmpty()) {
|
|
headers.put(HEADER_ACCEPT, String.join(accepts, HEADER_ACCEPT_DELIMITER));
|
|
}
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual void applyAuthentication(List<String> names, Map<String, Object> headers,
|
|
List<Param> query) {
|
|
for (Authentication auth : getAuthMethods(names)) {
|
|
auth.apply(headers, query);
|
|
}
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual List<Authentication> getAuthMethods(List<String> names) {
|
|
List<Authentication> authMethods = new List<Authentication>();
|
|
for (String name : names) {
|
|
authMethods.add(authentications.get(name));
|
|
}
|
|
return authMethods;
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual String toPath(String path, Map<String, Object> params) {
|
|
String formatted = path;
|
|
for (String key : params.keySet()) {
|
|
formatted = formatted.replace('{' + key + '}', String.valueOf(params.get(key)));
|
|
}
|
|
return formatted;
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual String toEndpoint(String path, Map<String, Object> params,
|
|
List<Param> queryParams) {
|
|
String query = '?' + paramsToString(queryParams);
|
|
return basePath + toPath(path, params) + query.removeEnd('?');
|
|
}
|
|
|
|
@TestVisible
|
|
protected virtual String paramsToString(List<Param> params) {
|
|
String s = '';
|
|
for (Param p : params) {
|
|
s += '&' + p;
|
|
}
|
|
return s.removeStart('&');
|
|
}
|
|
}
|
|
} |