Skip to content

Commit

Permalink
Adds support for returning response in jaxrs-spec interfaces (#7442)
Browse files Browse the repository at this point in the history
* Issue 7440 Added support for returning response in jaxrs-spec interfaces.

* Issue-7386 Updates samples for jaxrs-spec interfaces introduced in issue 7386.
  • Loading branch information
jarlesat authored and wing328 committed Jan 28, 2018
1 parent 6cd40e0 commit 88c5112
Show file tree
Hide file tree
Showing 52 changed files with 6,036 additions and 2 deletions.
35 changes: 35 additions & 0 deletions bin/jaxrs-spec-petstore-server-interface-returning-response.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 -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l jaxrs-spec -o samples/server/petstore/jaxrs-spec-interface-response
-DhideGenerationTimestamp=true
-DserializableModel=true
-DinterfaceOnly=true
-DreturnResponse=true"

java $JAVA_OPTS -jar $executable $ags
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen
{

public static final String INTERFACE_ONLY = "interfaceOnly";
public static final String RETURN_RESPONSE = "returnResponse";
public static final String GENERATE_POM = "generatePom";

private boolean interfaceOnly = false;
private boolean returnResponse = false;
private boolean generatePom = true;

public JavaJAXRSSpecServerCodegen()
Expand Down Expand Up @@ -75,6 +77,7 @@ public JavaJAXRSSpecServerCodegen()
cliOptions.add(library);
cliOptions.add(CliOption.newBoolean(GENERATE_POM, "Whether to generate pom.xml if the file does not already exist.").defaultValue(String.valueOf(generatePom)));
cliOptions.add(CliOption.newBoolean(INTERFACE_ONLY, "Whether to generate only API interface stubs without the server files.").defaultValue(String.valueOf(interfaceOnly)));
cliOptions.add(CliOption.newBoolean(RETURN_RESPONSE, "Whether generate API interface should return javax.ws.rs.core.Response instead of a deserialized entity. Only useful if interfaceOnly is true.").defaultValue(String.valueOf(returnResponse)));
}

@Override
Expand All @@ -89,6 +92,12 @@ public void processOpts()
additionalProperties.remove(INTERFACE_ONLY);
}
}
if (additionalProperties.containsKey(RETURN_RESPONSE)) {
returnResponse = Boolean.valueOf(additionalProperties.get(RETURN_RESPONSE).toString());
if (!returnResponse) {
additionalProperties.remove(RETURN_RESPONSE);
}
}
if (interfaceOnly) {
// Change default artifactId if genereating interfaces only, before command line options are applied in base class.
artifactId = "swagger-jaxrs-client";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
}{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}"{{#hasMore}}, {{/hasMore}}{{/vendorExtensions.x-tags}} })
@ApiResponses(value = { {{#responses}}
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}){{#hasMore}},{{/hasMore}}{{/responses}} })
{{>returnTypeInterface}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/allParams}});
{{#returnResponse}}Response{{/returnResponse}}{{^returnResponse}}{{>returnTypeInterface}}{{/returnResponse}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/allParams}});
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
{{/hasMore}}{{/authMethods}}
}{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}"{{#hasMore}}, {{/hasMore}}{{/vendorExtensions.x-tags}} })
@ApiResponses(value = { {{#responses}}
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{#hasMore}},{{/hasMore}}{{/responses}} })
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{#hasMore}},{{/hasMore}}{{/responses}}
})
public Response {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/allParams}}) {
return Response.ok().entity("magic!").build();
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ public void verify_that_generatePom_exists_as_a_parameter_with_default_true() {
Assert.fail("Missing " + JavaJAXRSSpecServerCodegen.GENERATE_POM);
}

@Test
public void verify_that_returnResponse_is_removed_from_additional_properties_if_false() {
generator.additionalProperties().put(JavaJAXRSSpecServerCodegen.RETURN_RESPONSE, Boolean.FALSE.toString());
generator.processOpts();
Assert.assertFalse(generator.additionalProperties().containsKey(JavaJAXRSSpecServerCodegen.RETURN_RESPONSE));
}

@Test
public void verify_that_returnResponse_is_preserved_in_additional_properties_if_true() {
generator.additionalProperties().put(JavaJAXRSSpecServerCodegen.RETURN_RESPONSE, Boolean.TRUE.toString());
generator.processOpts();
Assert.assertTrue(generator.additionalProperties().containsKey(JavaJAXRSSpecServerCodegen.RETURN_RESPONSE));
}

@Test
public void verify_that_interfaceOnly_exists_as_a_parameter_with_default_false() {
for (CliOption option : generator.cliOptions()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Swagger Codegen Ignore
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen

# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.

# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
#ApiClient.cs

# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux

# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux

# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.4.0-SNAPSHOT
48 changes: 48 additions & 0 deletions samples/server/petstore/jaxrs-spec-interface-response/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs-client</artifactId>
<packaging>jar</packaging>
<name>swagger-jaxrs-client</name>
<version>1.0.0</version>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<scope>provided</scope>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<!-- Bean Validation API support -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<junit-version>4.8.1</junit-version>
</properties>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.swagger.api;

import io.swagger.model.Client;

import javax.ws.rs.*;
import javax.ws.rs.core.Response;

import io.swagger.annotations.*;

import java.util.Map;
import java.util.List;
import javax.validation.constraints.*;
import javax.validation.Valid;

@Path("/another-fake")
@Api(description = "the another-fake API")
public interface AnotherFakeApi {

@PATCH
@Path("/dummy")
@Consumes({ "application/json" })
@Produces({ "application/json" })
@ApiOperation(value = "To test special tags", notes = "To test special tags", tags={ "$another-fake?" })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Client.class) })
Response testSpecialTags(@Valid Client body);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package io.swagger.api;

import java.math.BigDecimal;
import io.swagger.model.Client;
import java.util.Date;
import org.joda.time.LocalDate;
import io.swagger.model.OuterComposite;

import javax.ws.rs.*;
import javax.ws.rs.core.Response;

import io.swagger.annotations.*;

import java.util.Map;
import java.util.List;
import javax.validation.constraints.*;
import javax.validation.Valid;

@Path("/fake")
@Api(description = "the fake API")
public interface FakeApi {

@POST
@Path("/outer/boolean")
@ApiOperation(value = "", notes = "Test serialization of outer boolean types", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Output boolean", response = Boolean.class) })
Response fakeOuterBooleanSerialize(@Valid Boolean body);

@POST
@Path("/outer/composite")
@ApiOperation(value = "", notes = "Test serialization of object with outer number type", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Output composite", response = OuterComposite.class) })
Response fakeOuterCompositeSerialize(@Valid OuterComposite body);

@POST
@Path("/outer/number")
@ApiOperation(value = "", notes = "Test serialization of outer number types", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Output number", response = BigDecimal.class) })
Response fakeOuterNumberSerialize(@Valid BigDecimal body);

@POST
@Path("/outer/string")
@ApiOperation(value = "", notes = "Test serialization of outer string types", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Output string", response = String.class) })
Response fakeOuterStringSerialize(@Valid String body);

@PATCH
@Consumes({ "application/json" })
@Produces({ "application/json" })
@ApiOperation(value = "To test \"client\" model", notes = "To test \"client\" model", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Client.class) })
Response testClientModel(@Valid Client body);

@POST
@Consumes({ "application/xml; charset=utf-8", "application/json; charset=utf-8" })
@Produces({ "application/xml; charset=utf-8", "application/json; charset=utf-8" })
@ApiOperation(value = "Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 ", notes = "Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 ", authorizations = {
@Authorization(value = "http_basic_test")
}, tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid username supplied", response = Void.class),
@ApiResponse(code = 404, message = "User not found", response = Void.class) })
Response testEndpointParameters(@FormParam(value = "number") BigDecimal number,@FormParam(value = "double") Double _double,@FormParam(value = "pattern_without_delimiter") String patternWithoutDelimiter,@FormParam(value = "byte") byte[] _byte,@FormParam(value = "integer") Integer integer,@FormParam(value = "int32") Integer int32,@FormParam(value = "int64") Long int64,@FormParam(value = "float") Float _float,@FormParam(value = "string") String string,@FormParam(value = "binary") byte[] binary,@FormParam(value = "date") LocalDate date,@FormParam(value = "dateTime") Date dateTime,@FormParam(value = "password") String password,@FormParam(value = "callback") String paramCallback);

@GET
@Consumes({ "*/*" })
@Produces({ "*/*" })
@ApiOperation(value = "To test enum parameters", notes = "To test enum parameters", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 400, message = "Invalid request", response = Void.class),
@ApiResponse(code = 404, message = "Not found", response = Void.class) })
Response testEnumParameters(@FormParam(value = "enum_form_string_array") List<String> enumFormStringArray,@FormParam(value = "enum_form_string") String enumFormString,@HeaderParam("enum_header_string_array") @ApiParam("Header parameter enum test (string array)") List<String> enumHeaderStringArray,@HeaderParam("enum_header_string") @DefaultValue("-efg") @ApiParam("Header parameter enum test (string)") String enumHeaderString,@QueryParam("enum_query_string_array") @ApiParam("Query parameter enum test (string array)") List<String> enumQueryStringArray,@QueryParam("enum_query_string") @DefaultValue("-efg") @ApiParam("Query parameter enum test (string)") String enumQueryString,@QueryParam("enum_query_integer") @ApiParam("Query parameter enum test (double)") Integer enumQueryInteger,@FormParam(value = "enum_query_double") Double enumQueryDouble);

@POST
@Path("/inline-additionalProperties")
@Consumes({ "application/json" })
@ApiOperation(value = "test inline additionalProperties", notes = "", tags={ "fake", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Void.class) })
Response testInlineAdditionalProperties(@Valid Object param);

@GET
@Path("/jsonFormData")
@Consumes({ "application/json" })
@ApiOperation(value = "test json serialization of form data", notes = "", tags={ "fake" })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Void.class) })
Response testJsonFormData(@FormParam(value = "param") String param,@FormParam(value = "param2") String param2);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.swagger.api;

import io.swagger.model.Client;

import javax.ws.rs.*;
import javax.ws.rs.core.Response;

import io.swagger.annotations.*;

import java.util.Map;
import java.util.List;
import javax.validation.constraints.*;
import javax.validation.Valid;

@Path("/fake_classname_test")
@Api(description = "the fake_classname_test API")
public interface FakeClassnameTestApi {

@PATCH
@Consumes({ "application/json" })
@Produces({ "application/json" })
@ApiOperation(value = "To test class name in snake case", notes = "", authorizations = {
@Authorization(value = "api_key_query")
}, tags={ "fake_classname_tags 123#$%^" })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation", response = Client.class) })
Response testClassname(@Valid Client body);
}
Loading

0 comments on commit 88c5112

Please sign in to comment.