Skip to content

Commit 6debf74

Browse files
viclovskywing328
authored andcommitted
[NEW API CLIENT] Rest-assured (#7492)
* 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
1 parent c69925b commit 6debf74

File tree

119 files changed

+12368
-35
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+12368
-35
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
## Overview
2525
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:
2626

27-
- **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)
27+
- **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)
2828
- **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)
2929
- **API documentation generators**: **HTML**, **Confluence Wiki**
3030
- **Configuration files**: [**Apache2**](https://httpd.apache.org/)
@@ -530,6 +530,7 @@ CONFIG OPTIONS
530530
retrofit - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1 (Retrofit 1.9.0)
531531
retrofit2 - HTTP client: OkHttp 2.5.0. JSON processing: Gson 2.4 (Retrofit 2.0.0-beta2)
532532
google-api-client - HTTP client: google-api-client 1.23.0. JSON processing: Jackson 2.8.9
533+
rest-assured - HTTP client: rest-assured : 3.0.6. JSON processing: Gson 2.6.1. Only for Java8
533534
```
534535

535536
Your config file for Java can look like

bin/java-petstore-all.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
./bin/java-petstore-resttemplate-withxml.sh
1818
./bin/java-petstore-resteasy.sh
1919
./bin/java-petstore-google-api-client.sh
20+
./bin/java-petstore-rest-assured.sh
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"library": "rest-assured",
3+
"artifactId": "swagger-petstore-rest-assured"
4+
}

bin/java-petstore-rest-assured.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/sh
2+
3+
SCRIPT="$0"
4+
5+
while [ -h "$SCRIPT" ] ; do
6+
ls=`ls -ld "$SCRIPT"`
7+
link=`expr "$ls" : '.*-> \(.*\)$'`
8+
if expr "$link" : '/.*' > /dev/null; then
9+
SCRIPT="$link"
10+
else
11+
SCRIPT=`dirname "$SCRIPT"`/"$link"
12+
fi
13+
done
14+
15+
if [ ! -d "${APP_DIR}" ]; then
16+
APP_DIR=`dirname "$SCRIPT"`/..
17+
APP_DIR=`cd "${APP_DIR}"; pwd`
18+
fi
19+
20+
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
21+
22+
if [ ! -f "$executable" ]
23+
then
24+
mvn clean package
25+
fi
26+
27+
# if you've executed sbt assembly previously it will use that instead.
28+
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
29+
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"
30+
31+
echo "Removing files and folders under samples/client/petstore/java/rest-assured/src/main"
32+
rm -rf samples/client/petstore/java/rest-assured/src/main
33+
find samples/client/petstore/java/rest-assured -maxdepth 1 -type f ! -name "README.md" -exec rm {} +
34+
java $JAVA_OPTS -jar $executable $ags
35+

modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
3939

4040
public static final String RETROFIT_1 = "retrofit";
4141
public static final String RETROFIT_2 = "retrofit2";
42+
public static final String REST_ASSURED = "rest-assured";
4243

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

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

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

203-
if (!("feign".equals(getLibrary()) || "resttemplate".equals(getLibrary()) || usesAnyRetrofitLibrary() || "google-api-client".equals(getLibrary()))) {
205+
if (!("feign".equals(getLibrary()) || "resttemplate".equals(getLibrary()) || usesAnyRetrofitLibrary() || "google-api-client".equals(getLibrary()) || REST_ASSURED.equals(getLibrary()))) {
204206
supportingFiles.add(new SupportingFile("apiException.mustache", invokerFolder, "ApiException.java"));
205207
supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java"));
206208
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
@@ -246,6 +248,13 @@ public void processOpts() {
246248
supportingFiles.remove(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
247249
} else if ("google-api-client".equals(getLibrary())) {
248250
additionalProperties.put("jackson", "true");
251+
252+
} else if (REST_ASSURED.equals(getLibrary())) {
253+
additionalProperties.put("gson", "true");
254+
apiTemplateFiles.put("api.mustache", ".java");
255+
supportingFiles.add(new SupportingFile("ResponseSpecBuilders.mustache", invokerFolder, "ResponseSpecBuilders.java"));
256+
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
257+
supportingFiles.add(new SupportingFile("GsonObjectMapper.mustache", invokerFolder, "GsonObjectMapper.java"));
249258
} else {
250259
LOGGER.error("Unknown library option (-l/--library): " + getLibrary());
251260
}
Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import org.threeten.bp.format.DateTimeFormatter;
2626
{{/threetenbp}}
2727

2828
import {{modelPackage}}.*;
29-
import okio.ByteString;
3029

3130
import java.io.IOException;
3231
import java.io.StringReader;
@@ -56,7 +55,6 @@ public class JSON {
5655
private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
5756
private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
5857
{{/jsr310}}
59-
private ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter();
6058

6159
public static GsonBuilder createGson() {
6260
GsonFireBuilder fireBuilder = new GsonFireBuilder()
@@ -107,7 +105,6 @@ public class JSON {
107105
.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
108106
.registerTypeAdapter(LocalDate.class, localDateTypeAdapter)
109107
{{/jsr310}}
110-
.registerTypeAdapter(byte[].class, byteArrayAdapter)
111108
.create();
112109
}
113110

@@ -174,34 +171,6 @@ public class JSON {
174171
}
175172
}
176173

177-
/**
178-
* Gson TypeAdapter for Byte Array type
179-
*/
180-
public class ByteArrayAdapter extends TypeAdapter<byte[]> {
181-
182-
@Override
183-
public void write(JsonWriter out, byte[] value) throws IOException {
184-
if (value == null) {
185-
out.nullValue();
186-
} else {
187-
out.value(ByteString.of(value).base64());
188-
}
189-
}
190-
191-
@Override
192-
public byte[] read(JsonReader in) throws IOException {
193-
switch (in.peek()) {
194-
case NULL:
195-
in.nextNull();
196-
return null;
197-
default:
198-
String bytesAsBase64 = in.nextString();
199-
ByteString byteString = ByteString.decodeBase64(bytesAsBase64);
200-
return byteString.toByteArray();
201-
}
202-
}
203-
}
204-
205174
{{#joda}}
206175
/**
207176
* Gson TypeAdapter for Joda DateTime type
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{{>licenseInfo}}
2+
3+
package {{invokerPackage}};
4+
5+
import {{apiPackage}}.*;
6+
7+
{{#imports}}import {{import}};
8+
{{/imports}}
9+
10+
{{^fullJavaUtil}}
11+
import java.util.ArrayList;
12+
import java.util.HashMap;
13+
import java.util.List;
14+
import java.util.Map;
15+
import io.restassured.RestAssured;
16+
import io.restassured.builder.RequestSpecBuilder;
17+
import io.restassured.builder.ResponseSpecBuilder;
18+
import io.restassured.response.Response;
19+
import java.util.function.Consumer;
20+
import java.util.function.Function;
21+
import java.util.function.Supplier;
22+
{{/fullJavaUtil}}
23+
24+
public class ApiClient {
25+
26+
private final Config config;
27+
28+
private ApiClient(Config config) {
29+
this.config = config;
30+
}
31+
32+
public static ApiClient api(Config config) {
33+
return new ApiClient(config);
34+
}
35+
36+
{{#apiInfo}}
37+
{{#apis}}
38+
public {{classname}} {{classVarName}}() {
39+
return {{classname}}.{{classVarName}}(config.baseReqSpec.get());
40+
}
41+
{{/apis}}
42+
{{/apiInfo}}
43+
44+
public static class Config {
45+
private Supplier<RequestSpecBuilder> baseReqSpec;
46+
47+
/**
48+
* Use common specification for all operations
49+
*/
50+
public Config reqSpecSupplier(Supplier<RequestSpecBuilder> supplier) {
51+
this.baseReqSpec = supplier;
52+
return this;
53+
}
54+
55+
public static Config apiConfig() {
56+
return new Config();
57+
}
58+
}
59+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{{>licenseInfo}}
2+
3+
package {{invokerPackage}};
4+
5+
import io.restassured.mapper.ObjectMapper;
6+
import io.restassured.mapper.ObjectMapperDeserializationContext;
7+
import io.restassured.mapper.ObjectMapperSerializationContext;
8+
9+
public class GsonObjectMapper implements ObjectMapper {
10+
11+
private JSON json;
12+
13+
private GsonObjectMapper() {
14+
this.json = new JSON();
15+
}
16+
17+
public static GsonObjectMapper gson() {
18+
return new GsonObjectMapper();
19+
}
20+
21+
@Override
22+
public Object deserialize(ObjectMapperDeserializationContext context) {
23+
return json.deserialize(context.getDataToDeserialize().asString(), context.getType());
24+
}
25+
26+
@Override
27+
public Object serialize(ObjectMapperSerializationContext context) {
28+
return json.serialize(context.getObjectToSerialize());
29+
}
30+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# {{artifactId}}
2+
3+
## Requirements
4+
5+
Building the API client library requires [Maven](https://maven.apache.org/) to be installed.
6+
7+
## Installation & Usage
8+
9+
To install the API client library to your local Maven repository, simply execute:
10+
11+
```shell
12+
mvn install
13+
```
14+
15+
To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
16+
17+
```shell
18+
mvn deploy
19+
```
20+
21+
Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information.
22+
23+
After the client library is installed/deployed, you can use it in your Maven project by adding the following to your *pom.xml*:
24+
25+
```xml
26+
<dependency>
27+
<groupId>{{groupId}}</groupId>
28+
<artifactId>{{artifactId}}</artifactId>
29+
<version>{{artifactVersion}}</version>
30+
<scope>compile</scope>
31+
</dependency>
32+
33+
```
34+
35+
## Recommendation
36+
37+
It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues.
38+
39+
## Author
40+
41+
{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
42+
{{/hasMore}}{{/apis}}{{/apiInfo}}
43+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{{>licenseInfo}}
2+
3+
package {{invokerPackage}};
4+
5+
import io.restassured.builder.ResponseSpecBuilder;
6+
import io.restassured.response.Response;
7+
import io.restassured.specification.ResponseSpecification;
8+
9+
import java.util.function.Function;
10+
11+
public class ResponseSpecBuilders {
12+
13+
private ResponseSpecBuilders() {
14+
}
15+
16+
public static Function<Response, Response> validatedWith(ResponseSpecification respSpec) {
17+
return response -> response.then().spec(respSpec).extract().response();
18+
}
19+
20+
public static Function<Response, Response> validatedWith(ResponseSpecBuilder respSpec) {
21+
return validatedWith(respSpec.build());
22+
}
23+
24+
/**
25+
* @param code expected status code
26+
* @return ResponseSpecBuilder
27+
*/
28+
public static ResponseSpecBuilder shouldBeCode(int code) {
29+
return new ResponseSpecBuilder().expectStatusCode(code);
30+
}
31+
}

0 commit comments

Comments
 (0)