diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/ApiClient.mustache new file mode 100644 index 00000000000..35a1cf24242 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/ApiClient.mustache @@ -0,0 +1,533 @@ +package {{invokerPackage}}; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.filter.LoggingFilter; +import org.glassfish.jersey.media.multipart.FormDataBodyPart; +import org.glassfish.jersey.media.multipart.FormDataMultiPart; +import org.glassfish.jersey.media.multipart.MultiPart; +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.glassfish.jersey.media.multipart.file.FileDataBodyPart; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Map.Entry; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Date; +import java.util.TimeZone; + +import java.net.URLEncoder; + +import java.io.IOException; +import java.io.File; +import java.io.UnsupportedEncodingException; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.text.ParseException; + +import {{invokerPackage}}.auth.Authentication; +import {{invokerPackage}}.auth.HttpBasicAuth; +import {{invokerPackage}}.auth.ApiKeyAuth; +import {{invokerPackage}}.auth.OAuth; + +public class ApiClient { + private Map hostMap = new HashMap(); + private Map defaultHeaderMap = new HashMap(); + private boolean debugging = false; + private String basePath = "{{basePath}}"; + private JSON json = new JSON(); + + private Map authentications; + + private DateFormat dateFormat; + + public ApiClient() { + // Use ISO 8601 format for date and datetime. + // See https://en.wikipedia.org/wiki/ISO_8601 + this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + + // Use UTC as the default time zone. + this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + // Set default User-Agent. + setUserAgent("Java-Swagger"); + + // Setup authentications (key: authentication name, value: authentication). + authentications = new HashMap();{{#authMethods}}{{#isBasic}} + authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}} + authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}} + authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}} + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + } + + public String getBasePath() { + return basePath; + } + + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Get authentications (key: authentication name, value: 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); + } + + /** + * Helper method to set username for the first HTTP basic authentication. + */ + public void setUsername(String username) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setUsername(username); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set password for the first HTTP basic authentication. + */ + public void setPassword(String password) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setPassword(password); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set API key value for the first API key authentication. + */ + public void setApiKey(String apiKey) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKey(apiKey); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set API key prefix for the first API key authentication. + */ + public void setApiKeyPrefix(String apiKeyPrefix) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param key The header's key + * @param value The header's value + */ + public ApiClient addDefaultHeader(String key, String value) { + defaultHeaderMap.put(key, value); + return this; + } + + /** + * Check that whether debugging is enabled for this API client. + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Enable/disable debugging for this API client. + * + * @param debugging To enable (true) or disable (false) debugging + */ + public ApiClient setDebugging(boolean debugging) { + this.debugging = debugging; + return this; + } + + /** + * Get the date format used to parse/format date parameters. + */ + public DateFormat getDateFormat() { + return dateFormat; + } + + /** + * Set the date format used to parse/format date parameters. + */ + public ApiClient getDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + return this; + } + + /** + * Parse the given string into Date object. + */ + 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. + */ + public String formatDate(Date date) { + return dateFormat.format(date); + } + + /** + * Format the given parameter object into string. + */ + 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); + } + } + + /* + Format to {@code Pair} objects. + */ + public List parameterToPairs(String collectionFormat, String name, Object value){ + List params = new ArrayList(); + + // preconditions + if (name == null || name.isEmpty() || value == null) return params; + + Collection valueCollection = null; + if (value instanceof Collection) { + valueCollection = (Collection) value; + } else { + params.add(new Pair(name, parameterToString(value))); + return params; + } + + if (valueCollection.isEmpty()){ + return params; + } + + // get the collection format + collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv + + // create the params based on the collection format + if (collectionFormat.equals("multi")) { + for (Object item : valueCollection) { + params.add(new Pair(name, parameterToString(item))); + } + + return params; + } + + String delimiter = ","; + + if (collectionFormat.equals("csv")) { + delimiter = ","; + } else if (collectionFormat.equals("ssv")) { + delimiter = " "; + } else if (collectionFormat.equals("tsv")) { + delimiter = "\t"; + } else if (collectionFormat.equals("pipes")) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : valueCollection) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + + params.add(new Pair(name, sb.substring(1))); + + return params; + } + + /** + * 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; + if (StringUtil.containsIgnoreCase(accepts, "application/json")) return "application/json"; + 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, + * JSON will be used. + */ + public String selectHeaderContentType(String[] contentTypes) { + if (contentTypes.length == 0) return "application/json"; + if (StringUtil.containsIgnoreCase(contentTypes, "application/json")) return "application/json"; + return contentTypes[0]; + } + + /** + * Escape the given string to be used as URL query value. + */ + public String escapeString(String str) { + try { + return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); + } catch (UnsupportedEncodingException e) { + return str; + } + } + + /** + * Serialize the given Java object into string entity according the given + * Content-Type (only JSON is supported for now). + */ + public Entity serialize(Object obj, String contentType) throws ApiException { + if (contentType.startsWith("application/json")) { + return Entity.json(json.serialize(obj)); + } else { + throw new ApiException(400, "can not serialize object into Content-Type: " + contentType); + } + } + + /** + * Deserialize response body to Java object according to the Content-Type. + */ + public T deserialize(Response response, TypeRef returnType) throws ApiException { + String contentType = null; + List contentTypes = response.getHeaders().get("Content-Type"); + if (contentTypes != null && !contentTypes.isEmpty()) + contentType = String.valueOf(contentTypes.get(0)); + if (contentType == null) + throw new ApiException(500, "missing Content-Type in response"); + + String body; + if (response.hasEntity()) + body = (String) response.readEntity(String.class); + else + body = ""; + + if (contentType.startsWith("application/json")) { + return json.deserialize(body, returnType); + } else { + throw new ApiException(500, "can not deserialize Content-Type: " + contentType); + } + } + + /** + * Invoke API by sending HTTP request with the given options. + * + * @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 body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param accept The request's Accept header + * @param contentType The request's Content-Type header + * @param authNames The authentications to apply + * @param returnType The return type into which to deserialize the response + * @return The response body in type of string + */ + public T invokeAPI(String path, String method, List queryParams, Object body, Map headerParams, Map formParams, String accept, String contentType, String[] authNames, TypeRef returnType) throws ApiException { + updateParamsForAuth(authNames, queryParams, headerParams); + + final ClientConfig clientConfig = new ClientConfig(); + clientConfig.register(MultiPartFeature.class); + if (debugging) { + clientConfig.register(LoggingFilter.class); + } + Client client = ClientBuilder.newClient(clientConfig); + + WebTarget target = client.target(this.basePath).path(path); + + if (queryParams != null) { + for (Pair queryParam : queryParams) { + if (queryParam.getValue() != null) { + target = target.queryParam(queryParam.getName(), queryParam.getValue()); + } + } + } + + Invocation.Builder invocationBuilder = target.request(contentType).accept(accept); + + for (String key : headerParams.keySet()) { + String value = headerParams.get(key); + if (value != null) { + invocationBuilder = invocationBuilder.header(key, value); + } + } + + for (String key : defaultHeaderMap.keySet()) { + if (!headerParams.containsKey(key)) { + String value = defaultHeaderMap.get(key); + if (value != null) { + invocationBuilder = invocationBuilder.header(key, value); + } + } + } + + Entity formEntity = null; + + if (contentType.startsWith("multipart/form-data")) { + MultiPart multipart = new MultiPart(); + for (Entry param: formParams.entrySet()) { + if (param.getValue() instanceof File) { + File file = (File) param.getValue(); + + FormDataMultiPart mp = new FormDataMultiPart(); + mp.bodyPart(new FormDataBodyPart(param.getKey(), file.getName())); + multipart.bodyPart(mp, MediaType.MULTIPART_FORM_DATA_TYPE); + + multipart.bodyPart(new FileDataBodyPart(param.getKey(), file, MediaType.APPLICATION_OCTET_STREAM_TYPE)); + } else { + FormDataMultiPart mp = new FormDataMultiPart(); + mp.bodyPart(new FormDataBodyPart(param.getKey(), parameterToString(param.getValue()))); + multipart.bodyPart(mp, MediaType.MULTIPART_FORM_DATA_TYPE); + } + } + formEntity = Entity.entity(multipart, MediaType.MULTIPART_FORM_DATA_TYPE); + } else if (contentType.startsWith("application/x-www-form-urlencoded")) { + Form form = new Form(); + for (Entry param: formParams.entrySet()) { + form.param(param.getKey(), parameterToString(param.getValue())); + } + formEntity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE); + } + + Response response = null; + + if ("GET".equals(method)) { + response = invocationBuilder.get(); + } else if ("POST".equals(method)) { + if (formEntity != null) { + response = invocationBuilder.post(formEntity); + } else if (body == null) { + response = invocationBuilder.post(null); + } else { + response = invocationBuilder.post(serialize(body, contentType)); + } + } else if ("PUT".equals(method)) { + if (formEntity != null) { + response = invocationBuilder.put(formEntity); + } else if (body == null) { + response = invocationBuilder.put(null); + } else { + response = invocationBuilder.put(serialize(body, contentType)); + } + } else if ("DELETE".equals(method)) { + response = invocationBuilder.delete(); + } else { + throw new ApiException(500, "unknown method type " + method); + } + + if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) { + return null; + } else if (response.getStatusInfo().getFamily().equals(Status.Family.SUCCESSFUL)) { + if (returnType == null) + return null; + else + return deserialize(response, returnType); + } else { + String message = "error"; + String respBody = null; + if (response.hasEntity()) { + try { + respBody = String.valueOf(response.readEntity(String.class)); + message = respBody; + } catch (RuntimeException e) { + // e.printStackTrace(); + } + } + Map> responseHeaders = new HashMap>(); + for (String key: response.getHeaders().keySet()) { + List values = response.getHeaders().get(key); + List headers = new ArrayList(); + for (Object o : values) { + headers.add(String.valueOf(o)); + } + responseHeaders.put(key, headers); + } + throw new ApiException( + response.getStatus(), + message, + responseHeaders, + respBody); + } + } + + /** + * Update query and header parameters based on authentication settings. + * + * @param authNames The authentications to apply + */ + private void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) { + for (String authName : authNames) { + Authentication auth = authentications.get(authName); + if (auth == null) throw new RuntimeException("Authentication undefined: " + authName); + auth.applyToParams(queryParams, headerParams); + } + } +} diff --git a/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/pom.mustache b/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/pom.mustache new file mode 100644 index 00000000000..e2d0f73d408 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Java/libraries/jersey2/pom.mustache @@ -0,0 +1,171 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + + scm:git:git@github.com:swagger-api/swagger-mustache.git + scm:git:git@github.com:swagger-api/swagger-codegen.git + https://github.com/swagger-api/swagger-codegen + + + 2.2.0 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + + + io.swagger + swagger-annotations + ${swagger-annotations-version} + + + + + org.glassfish.jersey.core + jersey-client + ${jersey-version} + + + org.glassfish.jersey.media + jersey-media-multipart + ${jersey-version} + + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + 2.1.5 + + + joda-time + joda-time + ${jodatime-version} + + + + + junit + junit + ${junit-version} + test + + + + 1.5.0 + 2.6 + 2.4.2 + 2.3 + 1.0.0 + 4.8.1 + +