Skip to content

Commit

Permalink
[NEW API CLIENT] Rest-assured (#7492)
Browse files Browse the repository at this point in the history
* Rest-assured http client has been added

ApiClient has been added

@deprecated has been added for operation

{{{returnType}}} has been fixed

build.gradle.mustache, build.sbt.mustache, api_doc_mustache has been added

Samples has been added for rest-assured

Useless supporting files has been removed for rest-assured

Sample has been added for rest-assured

* Tests has been added

* Doc and tests has been fixed, JSON.mustache moved to common
  • Loading branch information
viclovsky authored and wing328 committed Jan 28, 2018
1 parent c69925b commit 6debf74
Show file tree
Hide file tree
Showing 119 changed files with 12,368 additions and 35 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
## Overview
This is the swagger codegen project, which allows generation of API client libraries (SDK generation), server stubs and documentation automatically given an [OpenAPI Spec](https://github.com/OAI/OpenAPI-Specification). Currently, the following languages/frameworks are supported:

- **API clients**: **ActionScript**, **Ada**, **Apex**, **Bash**, **C#** (.net 2.0, 3.5 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java), **Kotlin**, **Lua**, **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (Angular1.x, Angular2.x, Fetch, jQuery, Node)
- **API clients**: **ActionScript**, **Ada**, **Apex**, **Bash**, **C#** (.net 2.0, 3.5 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured), **Kotlin**, **Lua**, **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (Angular1.x, Angular2.x, Fetch, jQuery, Node)
- **Server stubs**: **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed), **Erlang**, **Go**, **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples)), **Kotlin**, **PHP** (Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** (rust-server), **Scala** ([Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), Scalatra)
- **API documentation generators**: **HTML**, **Confluence Wiki**
- **Configuration files**: [**Apache2**](https://httpd.apache.org/)
Expand Down Expand Up @@ -530,6 +530,7 @@ CONFIG OPTIONS
retrofit - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1 (Retrofit 1.9.0)
retrofit2 - HTTP client: OkHttp 2.5.0. JSON processing: Gson 2.4 (Retrofit 2.0.0-beta2)
google-api-client - HTTP client: google-api-client 1.23.0. JSON processing: Jackson 2.8.9
rest-assured - HTTP client: rest-assured : 3.0.6. JSON processing: Gson 2.6.1. Only for Java8
```

Your config file for Java can look like
Expand Down
1 change: 1 addition & 0 deletions bin/java-petstore-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
./bin/java-petstore-resttemplate-withxml.sh
./bin/java-petstore-resteasy.sh
./bin/java-petstore-google-api-client.sh
./bin/java-petstore-rest-assured.sh
4 changes: 4 additions & 0 deletions bin/java-petstore-rest-assured.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"library": "rest-assured",
"artifactId": "swagger-petstore-rest-assured"
}
35 changes: 35 additions & 0 deletions bin/java-petstore-rest-assured.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/sh

SCRIPT="$0"

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/swagger-codegen-cli/target/swagger-codegen-cli.jar"

if [ ! -f "$executable" ]
then
mvn 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 -t modules/swagger-codegen/src/main/resources/Java/libraries/rest-assured -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l java -c bin/java-petstore-rest-assured.json -o samples/client/petstore/java/rest-assured -DhideGenerationTimestamp=true"

echo "Removing files and folders under samples/client/petstore/java/rest-assured/src/main"
rm -rf samples/client/petstore/java/rest-assured/src/main
find samples/client/petstore/java/rest-assured -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 @@ -39,6 +39,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen

public static final String RETROFIT_1 = "retrofit";
public static final String RETROFIT_2 = "retrofit2";
public static final String REST_ASSURED = "rest-assured";

protected String gradleWrapperPackage = "gradle.wrapper";
protected boolean useRxJava = false;
Expand Down Expand Up @@ -83,6 +84,7 @@ public JavaClientCodegen() {
supportedLibraries.put("resteasy", "HTTP client: Resteasy client 3.1.3.Final. JSON processing: Jackson 2.8.9");
supportedLibraries.put("vertx", "HTTP client: VertX client 3.2.4. JSON processing: Jackson 2.8.9");
supportedLibraries.put("google-api-client", "HTTP client: Google API client 1.23.0. JSON processing: Jackson 2.8.9");
supportedLibraries.put("rest-assured", "HTTP client: rest-assured : 3.0.6. JSON processing: Gson 2.6.1. Only for Java8");

CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
libraryOption.setEnum(supportedLibraries);
Expand Down Expand Up @@ -169,12 +171,12 @@ public void processOpts() {
writeOptional(outputFolder, new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java"));
if(!"resttemplate".equals(getLibrary())) {
if(!("resttemplate".equals(getLibrary()) || REST_ASSURED.equals(getLibrary()))) {
supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java"));
}

// google-api-client doesn't use the Swagger auth, because it uses Google Credential directly (HttpRequestInitializer)
if (!"google-api-client".equals(getLibrary())) {
if (!("google-api-client".equals(getLibrary()) || REST_ASSURED.equals(getLibrary()))) {
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
Expand All @@ -200,7 +202,7 @@ public void processOpts() {
apiDocTemplateFiles.remove("api_doc.mustache");
}

if (!("feign".equals(getLibrary()) || "resttemplate".equals(getLibrary()) || usesAnyRetrofitLibrary() || "google-api-client".equals(getLibrary()))) {
if (!("feign".equals(getLibrary()) || "resttemplate".equals(getLibrary()) || usesAnyRetrofitLibrary() || "google-api-client".equals(getLibrary()) || REST_ASSURED.equals(getLibrary()))) {
supportingFiles.add(new SupportingFile("apiException.mustache", invokerFolder, "ApiException.java"));
supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java"));
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
Expand Down Expand Up @@ -246,6 +248,13 @@ public void processOpts() {
supportingFiles.remove(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
} else if ("google-api-client".equals(getLibrary())) {
additionalProperties.put("jackson", "true");

} else if (REST_ASSURED.equals(getLibrary())) {
additionalProperties.put("gson", "true");
apiTemplateFiles.put("api.mustache", ".java");
supportingFiles.add(new SupportingFile("ResponseSpecBuilders.mustache", invokerFolder, "ResponseSpecBuilders.java"));
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
supportingFiles.add(new SupportingFile("GsonObjectMapper.mustache", invokerFolder, "GsonObjectMapper.java"));
} else {
LOGGER.error("Unknown library option (-l/--library): " + getLibrary());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import org.threeten.bp.format.DateTimeFormatter;
{{/threetenbp}}

import {{modelPackage}}.*;
import okio.ByteString;

import java.io.IOException;
import java.io.StringReader;
Expand Down Expand Up @@ -56,7 +55,6 @@ public class JSON {
private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
{{/jsr310}}
private ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter();

public static GsonBuilder createGson() {
GsonFireBuilder fireBuilder = new GsonFireBuilder()
Expand Down Expand Up @@ -107,7 +105,6 @@ public class JSON {
.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
.registerTypeAdapter(LocalDate.class, localDateTypeAdapter)
{{/jsr310}}
.registerTypeAdapter(byte[].class, byteArrayAdapter)
.create();
}

Expand Down Expand Up @@ -174,34 +171,6 @@ public class JSON {
}
}

/**
* Gson TypeAdapter for Byte Array type
*/
public class ByteArrayAdapter extends TypeAdapter<byte[]> {
@Override
public void write(JsonWriter out, byte[] value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(ByteString.of(value).base64());
}
}

@Override
public byte[] read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String bytesAsBase64 = in.nextString();
ByteString byteString = ByteString.decodeBase64(bytesAsBase64);
return byteString.toByteArray();
}
}
}

{{#joda}}
/**
* Gson TypeAdapter for Joda DateTime type
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{{>licenseInfo}}

package {{invokerPackage}};

import {{apiPackage}}.*;

{{#imports}}import {{import}};
{{/imports}}

{{^fullJavaUtil}}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.response.Response;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
{{/fullJavaUtil}}

public class ApiClient {
private final Config config;
private ApiClient(Config config) {
this.config = config;
}

public static ApiClient api(Config config) {
return new ApiClient(config);
}

{{#apiInfo}}
{{#apis}}
public {{classname}} {{classVarName}}() {
return {{classname}}.{{classVarName}}(config.baseReqSpec.get());
}
{{/apis}}
{{/apiInfo}}

public static class Config {
private Supplier<RequestSpecBuilder> baseReqSpec;
/**
* Use common specification for all operations
*/
public Config reqSpecSupplier(Supplier<RequestSpecBuilder> supplier) {
this.baseReqSpec = supplier;
return this;
}

public static Config apiConfig() {
return new Config();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{{>licenseInfo}}

package {{invokerPackage}};

import io.restassured.mapper.ObjectMapper;
import io.restassured.mapper.ObjectMapperDeserializationContext;
import io.restassured.mapper.ObjectMapperSerializationContext;

public class GsonObjectMapper implements ObjectMapper {
private JSON json;
private GsonObjectMapper() {
this.json = new JSON();
}

public static GsonObjectMapper gson() {
return new GsonObjectMapper();
}

@Override
public Object deserialize(ObjectMapperDeserializationContext context) {
return json.deserialize(context.getDataToDeserialize().asString(), context.getType());
}

@Override
public Object serialize(ObjectMapperSerializationContext context) {
return json.serialize(context.getObjectToSerialize());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# {{artifactId}}

## Requirements

Building the API client library requires [Maven](https://maven.apache.org/) to be installed.

## Installation & Usage

To install the API client library to your local Maven repository, simply execute:

```shell
mvn install
```

To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:

```shell
mvn deploy
```

Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information.

After the client library is installed/deployed, you can use it in your Maven project by adding the following to your *pom.xml*:

```xml
<dependency>
<groupId>{{groupId}}</groupId>
<artifactId>{{artifactId}}</artifactId>
<version>{{artifactVersion}}</version>
<scope>compile</scope>
</dependency>

```

## Recommendation

It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues.

## Author

{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
{{/hasMore}}{{/apis}}{{/apiInfo}}

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{{>licenseInfo}}

package {{invokerPackage}};

import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.response.Response;
import io.restassured.specification.ResponseSpecification;

import java.util.function.Function;

public class ResponseSpecBuilders {
private ResponseSpecBuilders() {
}

public static Function<Response, Response> validatedWith(ResponseSpecification respSpec) {
return response -> response.then().spec(respSpec).extract().response();
}

public static Function<Response, Response> validatedWith(ResponseSpecBuilder respSpec) {
return validatedWith(respSpec.build());
}

/**
* @param code expected status code
* @return ResponseSpecBuilder
*/
public static ResponseSpecBuilder shouldBeCode(int code) {
return new ResponseSpecBuilder().expectStatusCode(code);
}
}

0 comments on commit 6debf74

Please sign in to comment.