Skip to content

Commit

Permalink
[Java] Retrofit2 Play! Framework 2.6.x support (OpenAPITools#901)
Browse files Browse the repository at this point in the history
* added play framework 2.6 support

* generated petstore sample

* generated petstore sample #2

* generated petstore sample #3

* Revert "generated petstore sample #3"

* generated petstore sample #4

* fixed circleci configs

* one more time samples regen
  • Loading branch information
lukoyanov authored and wing328 committed Aug 28, 2018
1 parent 7758e75 commit d461c21
Show file tree
Hide file tree
Showing 131 changed files with 10,842 additions and 41 deletions.
1 change: 1 addition & 0 deletions CI/pom.xml.circleci
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,7 @@
<module>samples/client/petstore/java/retrofit2</module>
<module>samples/client/petstore/java/retrofit2rx</module>
<module>samples/client/petstore/java/retrofit2-play25</module>
<module>samples/client/petstore/java/retrofit2-play26</module>
<module>samples/client/petstore/jaxrs-cxf-client</module>
<module>samples/client/petstore/java/resttemplate</module>
<module>samples/client/petstore/java/resttemplate-withXml</module>
Expand Down
1 change: 1 addition & 0 deletions bin/java-petstore-retrofit2-play26.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"useBeanValidation":"true","enableBuilderSupport":"true","library":"retrofit2","usePlayWS":"true","playVersion":"play26"}
35 changes: 35 additions & 0 deletions bin/java-petstore-retrofit2-play26.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/sh

SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"

while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done

if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi

executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"

if [ ! -f "$executable" ]
then
mvn -B clean package
fi

# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate --artifact-id petstore-java-client-retrofit2-play26 -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-retrofit2-play26.json -o samples/client/petstore/java/retrofit2-play26 -DhideGenerationTimestamp=true $@"

echo "Removing files and folders under samples/client/petstore/java/retrofit2-play26/src/main"
rm -rf samples/client/petstore/java/retrofit2-play26/src/main
find samples/client/petstore/java/retrofit2-play26 -maxdepth 1 -type f ! -name "README.md" -exec rm {} +
java $JAVA_OPTS -jar $executable $ags
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@

package org.openapitools.codegen.languages;

import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static java.util.Collections.sort;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
Expand All @@ -43,12 +39,14 @@
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static java.util.Collections.sort;

public class JavaClientCodegen extends AbstractJavaCodegen
implements BeanValidationFeatures, PerformBeanValidationFeatures,
GzipFeatures {
Expand All @@ -67,6 +65,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen

public static final String PLAY_24 = "play24";
public static final String PLAY_25 = "play25";
public static final String PLAY_26 = "play26";

public static final String FEIGN = "feign";
public static final String GOOGLE_API_CLIENT = "google-api-client";
Expand Down Expand Up @@ -333,7 +332,9 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("play24/Play24CallFactory.mustache", invokerFolder, "Play24CallFactory.java"));
supportingFiles.add(new SupportingFile("play24/Play24CallAdapterFactory.mustache", invokerFolder,
"Play24CallAdapterFactory.java"));
} else {
}

if (PLAY_25.equals(playVersion)) {
additionalProperties.put(PLAY_25, true);
apiTemplateFiles.put("play25/api.mustache", ".java");

Expand All @@ -344,6 +345,17 @@ public void processOpts() {
additionalProperties.put("java8", "true");
}

if (PLAY_26.equals(playVersion)) {
additionalProperties.put(PLAY_26, true);
apiTemplateFiles.put("play26/api.mustache", ".java");

supportingFiles.add(new SupportingFile("play26/ApiClient.mustache", invokerFolder, "ApiClient.java"));
supportingFiles.add(new SupportingFile("play26/Play26CallFactory.mustache", invokerFolder, "Play26CallFactory.java"));
supportingFiles.add(new SupportingFile("play26/Play26CallAdapterFactory.mustache", invokerFolder,
"Play26CallAdapterFactory.java"));
additionalProperties.put("java8", "true");
}

supportingFiles.add(new SupportingFile("play-common/auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ ext {
jackson_version = "2.7.8"
play_version = "2.5.14"
{{/play25}}
{{#play26}}
jackson_version = "2.8.10"
play_version = "2.6.7"
{{/play26}}
{{/usePlayWS}}
swagger_annotations_version = "1.5.17"
junit_version = "4.12"
Expand Down Expand Up @@ -171,7 +175,13 @@ dependencies {
compile "org.threeten:threetenbp:$threetenbp_version"
{{/threetenbp}}
{{#usePlayWS}}
{{#play26}}
compile "com.typesafe.play:play-ahc-ws_2.12:$play_version"
compile "javax.validation:validation-api:1.1.0.Final"
{{/play26}}
{{^play26}}
compile "com.typesafe.play:play-java-ws_2.11:$play_version"
{{/play26}}
compile "com.squareup.retrofit2:converter-jackson:$retrofit_version"
compile "com.fasterxml.jackson.core:jackson-core:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ lazy val root = (project in file(".")).
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.7.8" % "compile",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.7.8" % "compile",
{{/play25}}
{{#play26}}
"com.typesafe.play" % "play-ahc-ws_2.12" % "2.6.7" % "compile",
"javax.validation" % "validation-api" % "1.1.0.Final" % "compile",
"com.fasterxml.jackson.core" % "jackson-core" % "2.8.10" % "compile",
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.10" % "compile",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.10" % "compile",
{{/play26}}
"com.squareup.retrofit2" % "converter-jackson" % "2.3.0" % "compile",
{{/usePlayWS}}
{{#useRxJava}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
package {{invokerPackage}};

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;

import play.libs.Json;
import play.libs.ws.WSClient;

import {{invokerPackage}}.Play26CallAdapterFactory;
import {{invokerPackage}}.Play26CallFactory;

import okhttp3.Interceptor;
import okhttp3.ResponseBody;
import {{invokerPackage}}.auth.ApiKeyAuth;
import {{invokerPackage}}.auth.Authentication;

/**
* API client
*/
public class ApiClient {
/** Underlying HTTP-client */
private WSClient wsClient;
/** Creates HTTP call instances */
private Play26CallFactory callFactory;
/** Create {@link java.util.concurrent.CompletionStage} instances from HTTP calls */
private Play26CallAdapterFactory callAdapterFactory;

/** Supported auths */
private Map<String, Authentication> authentications;

/** API base path */
private String basePath = "{{{basePath}}}";

/** Default ObjectMapper */
private ObjectMapper defaultMapper;

public ApiClient(WSClient wsClient) {
this();
this.wsClient = wsClient;
}

public ApiClient() {
// 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);
}

/**
* Creates a retrofit2 client for given API interface
*/
public <S> S createService(Class<S> serviceClass) {
if(!basePath.endsWith("/")) {
basePath = basePath + "/";
}

Map<String, String> extraHeaders = new HashMap<>();
List<Pair> extraQueryParams = new ArrayList<>();

for (String authName : authentications.keySet()) {
Authentication auth = authentications.get(authName);
if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);
auth.applyToParams(extraQueryParams, extraHeaders);
}

if (callFactory == null) {
callFactory = new Play26CallFactory(wsClient, extraHeaders, extraQueryParams);
}
if (callAdapterFactory == null) {
callAdapterFactory = new Play26CallAdapterFactory();
}
if (defaultMapper == null) {
defaultMapper = Json.mapper();
}

return new Retrofit.Builder()
.baseUrl(basePath)
.addConverterFactory(new FileConverter())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(JacksonConverterFactory.create(defaultMapper))
.callFactory(callFactory)
.addCallAdapterFactory(callAdapterFactory)
.build()
.create(serviceClass);
}

/**
* Helper method to set API base path
*/
public ApiClient setBasePath(String basePath) {
this.basePath = basePath;
return this;
}

/**
* Get authentications (key: authentication name, value: authentication).
*/
public Map<String, Authentication> 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 API key value for the first API key authentication.
*/
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.
*/
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 HTTP call instances factory
*/
public ApiClient setCallFactory(Play26CallFactory callFactory) {
this.callFactory = callFactory;
return this;
}

/**
* Helper method to set {@link java.util.concurrent.CompletionStage} instances factory
*/
public ApiClient setCallAdapterFactory(Play26CallAdapterFactory callAdapterFactory) {
this.callAdapterFactory = callAdapterFactory;
return this;
}

/**
* Helper method to set Jackson's {@link ObjectMapper}
*/
public ApiClient setObjectMapper(ObjectMapper mapper) {
this.defaultMapper = mapper;
return this;
}

static class FileConverter extends Converter.Factory {
@Override
public Converter<ResponseBody, File> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
if (!File.class.getTypeName().equals(type.getTypeName())) {
return null;
}

return new Converter<ResponseBody, File>() {
@Override
public File convert(ResponseBody value) throws IOException {
File file = File.createTempFile("retrofit-file", ".tmp");
Files.write(Paths.get(file.getPath()), value.bytes());
return file;
}
};
}
}

}
Loading

0 comments on commit d461c21

Please # to comment.