Skip to content

Commit e25f8c5

Browse files
authored
Add support for @gzip in jaxrs-spec Quarkus templates (#13983)
* adjust templates for @gzip * add test * remove debug output
1 parent 5e50ff4 commit e25f8c5

6 files changed

Lines changed: 138 additions & 4 deletions

File tree

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaJAXRSSpecServerCodegen.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import java.io.File;
2626
import java.util.Map;
2727

28+
import static org.openapitools.codegen.languages.features.GzipFeatures.USE_GZIP_FEATURE;
29+
2830
public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
2931

3032
public static final String INTERFACE_ONLY = "interfaceOnly";
@@ -45,6 +47,8 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
4547
private boolean generatePom = true;
4648
private boolean generateBuilders = false;
4749
private boolean useSwaggerAnnotations = true;
50+
51+
protected boolean useGzipFeature = false;
4852
private boolean useJackson = false;
4953
private String openApiSpecFileLocation = "src/main/openapi/openapi.yaml";
5054

@@ -155,6 +159,7 @@ public void processOpts() {
155159
} else if(OPEN_LIBERTY_LIBRARY.equals(library)) {
156160
openApiSpecFileLocation = "src/main/webapp/META-INF/openapi.yaml";
157161
}
162+
158163
additionalProperties.put(OPEN_API_SPEC_FILE_LOCATION, openApiSpecFileLocation);
159164

160165
useJackson = convertPropertyToBoolean(JACKSON);
@@ -228,6 +233,13 @@ public void processOpts() {
228233
} else if(KUMULUZEE_LIBRARY.equals(library)) {
229234
supportingFiles.add(new SupportingFile("config.yaml.mustache", "src/main/resources", "config.yaml"));
230235
}
236+
237+
if (additionalProperties.containsKey(USE_GZIP_FEATURE)) {
238+
useGzipFeature = Boolean.parseBoolean(additionalProperties.get(USE_GZIP_FEATURE).toString());
239+
if (!useGzipFeature) {
240+
additionalProperties.remove(USE_GZIP_FEATURE);
241+
}
242+
}
231243
}
232244

233245
@Override
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package {{package}};
2+
3+
{{#imports}}import {{import}};
4+
{{/imports}}
5+
6+
import javax.ws.rs.*;
7+
import javax.ws.rs.core.Response;
8+
9+
{{#useGzipFeature}}
10+
import org.jboss.resteasy.annotations.GZIP;
11+
{{/useGzipFeature}}
12+
13+
{{#useSwaggerAnnotations}}
14+
import io.swagger.annotations.*;
15+
{{/useSwaggerAnnotations}}
16+
{{#supportAsync}}
17+
import java.util.concurrent.CompletionStage;
18+
import java.util.concurrent.CompletableFuture;
19+
{{/supportAsync}}
20+
21+
import java.io.InputStream;
22+
import java.util.Map;
23+
import java.util.List;
24+
{{#useBeanValidation}}import javax.validation.constraints.*;
25+
import javax.validation.Valid;{{/useBeanValidation}}
26+
27+
@Path("{{commonPath}}"){{#useSwaggerAnnotations}}
28+
@Api(description = "the {{{baseName}}} API"){{/useSwaggerAnnotations}}{{#hasConsumes}}
29+
@Consumes({ {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }){{/hasConsumes}}{{#hasProduces}}
30+
@Produces({ {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }){{/hasProduces}}
31+
{{>generatedAnnotation}}
32+
public {{#interfaceOnly}}interface{{/interfaceOnly}}{{^interfaceOnly}}class{{/interfaceOnly}} {{classname}} {
33+
{{#operations}}
34+
{{#operation}}
35+
36+
{{#interfaceOnly}}{{>apiInterface}}{{/interfaceOnly}}{{^interfaceOnly}}{{>apiMethod}}{{/interfaceOnly}}
37+
{{/operation}}
38+
}
39+
{{/operations}}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{{#useGzipFeature}}
2+
@GZIP
3+
{{/useGzipFeature}}
4+
@{{httpMethod}}{{#subresourceOperation}}
5+
@Path("{{{path}}}"){{/subresourceOperation}}{{#hasConsumes}}
6+
@Consumes({ {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }){{/hasConsumes}}{{#hasProduces}}
7+
@Produces({ {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }){{/hasProduces}}{{#useSwaggerAnnotations}}
8+
@ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}"{{#hasAuthMethods}}, authorizations = {
9+
{{#authMethods}}{{#isOAuth}}@Authorization(value = "{{name}}", scopes = {
10+
{{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}},
11+
{{/-last}}{{/scopes}} }){{^-last}},{{/-last}}{{/isOAuth}}
12+
{{^isOAuth}}@Authorization(value = "{{name}}"){{^-last}},{{/-last}}
13+
{{/isOAuth}}{{/authMethods}} }{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-tags}} })
14+
{{#implicitHeadersParams.0}}
15+
@io.swagger.annotations.ApiImplicitParams({
16+
{{#implicitHeadersParams}}
17+
@io.swagger.annotations.ApiImplicitParam(name = "{{{baseName}}}", value = "{{{description}}}", {{#required}}required = true,{{/required}} dataType = "{{{dataType}}}", paramType = "header"){{^-last}},{{/-last}}
18+
{{/implicitHeadersParams}}
19+
})
20+
{{/implicitHeadersParams.0}}
21+
@ApiResponses(value = { {{#responses}}
22+
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#returnContainer}}, responseContainer = "{{{.}}}"{{/returnContainer}}){{^-last}},{{/-last}}{{/responses}} }){{/useSwaggerAnnotations}}
23+
{{#supportAsync}}{{>returnAsyncTypeInterface}}{{/supportAsync}}{{^supportAsync}}{{#returnResponse}}Response{{/returnResponse}}{{^returnResponse}}{{>returnTypeInterface}}{{/returnResponse}}{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{{#useGzipFeature}}
2+
@GZIP
3+
{{/useGzipFeature}}
4+
@{{httpMethod}}{{#subresourceOperation}}
5+
@Path("{{{path}}}"){{/subresourceOperation}}{{#hasConsumes}}
6+
@Consumes({ {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }){{/hasConsumes}}{{#hasProduces}}
7+
@Produces({ {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }){{/hasProduces}}{{#useSwaggerAnnotations}}
8+
@ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}", response = {{{returnBaseType}}}.class{{#returnContainer}}, responseContainer = "{{{.}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = {
9+
{{#authMethods}}{{#isOAuth}}@Authorization(value = "{{name}}", scopes = {
10+
{{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}},
11+
{{/-last}}{{/scopes}} }){{^-last}},{{/-last}}{{/isOAuth}}
12+
{{^isOAuth}}@Authorization(value = "{{name}}"){{^-last}},{{/-last}}
13+
{{/isOAuth}}{{/authMethods}} }{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-tags}} })
14+
{{#implicitHeadersParams.0}}
15+
@io.swagger.annotations.ApiImplicitParams({
16+
{{#implicitHeadersParams}}
17+
@io.swagger.annotations.ApiImplicitParam(name = "{{{baseName}}}", value = "{{{description}}}", {{#required}}required = true,{{/required}} dataType = "{{{dataType}}}", paramType = "header"){{^-last}},{{/-last}}
18+
{{/implicitHeadersParams}}
19+
})
20+
{{/implicitHeadersParams.0}}
21+
@ApiResponses(value = { {{#responses}}
22+
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}}
23+
}){{/useSwaggerAnnotations}}
24+
public {{#supportAsync}}CompletionStage<{{/supportAsync}}Response{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
25+
return {{#supportAsync}}CompletableFuture.supplyAsync(() -> {{/supportAsync}}Response.ok().entity("magic!").build(){{#supportAsync}}){{/supportAsync}};
26+
}
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
# Configuration file
22
# key = value
33

4-
mp.openapi.scan.disable=true
4+
mp.openapi.scan.disable=true
5+
6+
{{#useGzipFeature}}
7+
quarkus.resteasy.gzip.enabled=true
8+
quarkus.resteasy.gzip.max-input=10M
9+
{{/useGzipFeature}}

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/jaxrs/JavaJAXRSSpecServerCodegenTest.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@
3030
import static org.openapitools.codegen.TestUtils.assertFileContains;
3131
import static org.openapitools.codegen.TestUtils.validateJavaSourceFiles;
3232
import static org.openapitools.codegen.languages.AbstractJavaJAXRSServerCodegen.USE_TAGS;
33-
import static org.openapitools.codegen.languages.JavaJAXRSSpecServerCodegen.INTERFACE_ONLY;
34-
import static org.openapitools.codegen.languages.JavaJAXRSSpecServerCodegen.RETURN_RESPONSE;
35-
import static org.openapitools.codegen.languages.JavaJAXRSSpecServerCodegen.SUPPORT_ASYNC;
33+
import static org.openapitools.codegen.languages.JavaJAXRSSpecServerCodegen.*;
34+
import static org.openapitools.codegen.languages.features.GzipFeatures.USE_GZIP_FEATURE;
3635
import static org.testng.Assert.assertTrue;
3736

3837
import com.google.common.collect.ImmutableMap;
@@ -725,4 +724,34 @@ public void arrayNullableDefaultValueTests() throws Exception {
725724
"\nprivate @Valid List<String> arrayThatIsNotNull = new ArrayList<>();\n");
726725

727726
}
727+
728+
@Test
729+
public void generateApiForQuarkusWithGzipFeature() throws Exception {
730+
final File output = Files.createTempDirectory("test").toFile();
731+
output.deleteOnExit();
732+
733+
final OpenAPI openAPI = new OpenAPIParser()
734+
.readLocation("src/test/resources/3_0/ping.yaml", null, new ParseOptions()).getOpenAPI();
735+
736+
codegen.setOutputDir(output.getAbsolutePath());
737+
codegen.setLibrary(QUARKUS_LIBRARY);
738+
codegen.additionalProperties().put(USE_GZIP_FEATURE, true);
739+
740+
final ClientOptInput input = new ClientOptInput()
741+
.openAPI(openAPI)
742+
.config(codegen); //Using JavaJAXRSSpecServerCodegen
743+
744+
final DefaultGenerator generator = new DefaultGenerator();
745+
final List<File> files = generator.opts(input).generate(); //When generating files
746+
747+
//Then the java files are compilable
748+
validateJavaSourceFiles(files);
749+
750+
//And the generated class contains CompletionStage<Response>
751+
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/PingApi.java");
752+
assertFileContains(output.toPath().resolve("src/gen/java/org/openapitools/api/PingApi.java"),
753+
"\nimport org.jboss.resteasy.annotations.GZIP\n",
754+
"@GZIP\n"
755+
);
756+
}
728757
}

0 commit comments

Comments
 (0)