#8792 [Java] [jaxrs-cxf] "useAbstractionForFiles" config option for jaxrs-cxf (#14316)

* [REQ] Add equals and hashcode to java-cxf pojo #12519

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* [Java] Use abstraction for files for jaxrs-cxf #8792

* fix sample

* fix sample

---------

Co-authored-by: FWermelskirchen <fwermelskirchen@eitco.de>
This commit is contained in:
DevFlorian 2023-01-28 04:37:08 +01:00 committed by GitHub
parent ac5134acf3
commit 6a2d8d23da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 132 additions and 5 deletions

View File

@ -65,6 +65,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/gen/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|useAbstractionForFiles|Use alternative types instead of java.io.File to allow passing bytes without a file on disk.| |false|
|useBeanValidation|Use BeanValidation API annotations| |false|
|useGenericResponse|Use generic response| |false|
|useGzipFeatureForTests|Use Gzip Feature for tests| |false|

View File

@ -78,6 +78,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testDataFile|JSON file to contain generated test data| |null|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|a title describing the application| |OpenAPI Server|
|useAbstractionForFiles|Use alternative types instead of java.io.File to allow passing bytes without a file on disk.| |false|
|useAnnotatedBasePath|Use @Path annotations for basePath| |false|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useBeanValidationFeature|Use BeanValidation Feature| |false|

View File

@ -73,6 +73,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|sourceFolder|source folder for generated code| |src/gen/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|a title describing the application| |OpenAPI Server|
|useAbstractionForFiles|Use alternative types instead of java.io.File to allow passing bytes without a file on disk.| |false|
|useAnnotatedBasePath|Use @Path annotations for basePath| |false|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useBeanValidationFeature|Use BeanValidation Feature| |false|

View File

@ -43,6 +43,8 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
*/
protected static final String JAXRS_TEMPLATE_DIRECTORY_NAME = "JavaJaxRS";
public static final String USE_ABSTRACTION_FOR_FILES = "useAbstractionForFiles";
protected boolean useBeanValidation = false;
protected boolean useGenericResponse = false;
@ -53,6 +55,8 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
private boolean useJackson = false;
protected boolean useAbstractionForFiles = false;
public JavaCXFClientCodegen() {
super();
@ -90,6 +94,7 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newBoolean(USE_GZIP_FEATURE_FOR_TESTS, "Use Gzip Feature for tests"));
cliOptions.add(CliOption.newBoolean(USE_LOGGING_FEATURE_FOR_TESTS, "Use Logging Feature for tests"));
cliOptions.add(CliOption.newBoolean(USE_GENERIC_RESPONSE, "Use generic response"));
cliOptions.add(CliOption.newBoolean(USE_ABSTRACTION_FOR_FILES, "Use alternative types instead of java.io.File to allow passing bytes without a file on disk."));
}
@Override
@ -116,6 +121,10 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
useJackson = convertPropertyToBooleanAndWriteBack(JACKSON);
}
if (additionalProperties.containsKey(USE_ABSTRACTION_FOR_FILES)) {
this.setUseAbstractionForFiles(convertPropertyToBooleanAndWriteBack(USE_ABSTRACTION_FOR_FILES));
}
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")
@ -218,4 +227,8 @@ public class JavaCXFClientCodegen extends AbstractJavaCodegen
public boolean isUseJackson() {
return useJackson;
}
public void setUseAbstractionForFiles(boolean useAbstractionForFiles) {
this.useAbstractionForFiles = useAbstractionForFiles;
}
}

View File

@ -36,6 +36,8 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
implements CXFServerFeatures, GzipTestFeatures, LoggingTestFeatures, UseGenericResponseFeatures {
private final Logger LOGGER = LoggerFactory.getLogger(JavaCXFServerCodegen.class);
public static final String USE_ABSTRACTION_FOR_FILES = "useAbstractionForFiles";
protected boolean addConsumesProducesJson = true;
protected boolean generateSpringApplication = false;
@ -70,6 +72,8 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
protected boolean useGenericResponse = false;
protected boolean useAbstractionForFiles = false;
public JavaCXFServerCodegen() {
super();
@ -126,6 +130,7 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
cliOptions.add(CliOption.newBoolean(GENERATE_NON_SPRING_APPLICATION, "Generate non-Spring application"));
cliOptions.add(CliOption.newBoolean(USE_GENERIC_RESPONSE, "Use generic response"));
cliOptions.add(CliOption.newBoolean(USE_ABSTRACTION_FOR_FILES, "Use alternative types instead of java.io.File to allow passing bytes without a file on disk."));
}
@ -184,6 +189,10 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
this.setGenerateNonSpringApplication(generateNonSpringApplication);
}
if (additionalProperties.containsKey(USE_ABSTRACTION_FOR_FILES)) {
this.setUseAbstractionForFiles(convertPropertyToBooleanAndWriteBack(USE_ABSTRACTION_FOR_FILES));
}
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
supportingFiles.add(new SupportingFile("server/pom.mustache", "", "pom.xml")
@ -332,6 +341,10 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen
this.useGenericResponse = useGenericResponse;
}
public void setUseAbstractionForFiles(boolean useAbstractionForFiles) {
this.useAbstractionForFiles = useAbstractionForFiles;
}
@Override
protected void updateModelForObject(CodegenModel m, Schema schema) {
/**

View File

@ -69,7 +69,7 @@ public interface {{classname}} {
})
{{/implicitHeadersParams.0}}
@ApiResponses(value = { {{#responses}}
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{^vendorExtensions.x-java-is-response-void}}, response = {{{baseType}}}.class{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}{{/vendorExtensions.x-java-is-response-void}}){{^-last}},{{/-last}}{{/responses}} })
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{^vendorExtensions.x-java-is-response-void}}, response = {{#isFile}}{{#useAbstractionForFiles}}InputStream{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{baseType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{baseType}}}{{/isFile}}.class{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}{{/vendorExtensions.x-java-is-response-void}}){{^-last}},{{/-last}}{{/responses}} })
public {{>returnTypes}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}}, {{/-last}}{{/allParams}});
{{/operation}}
}

View File

@ -113,7 +113,7 @@ public class {{classname}}Test {
@Test
public void {{operationId}}Test() {
{{#allParams}}
{{^isFile}}{{{dataType}}} {{paramName}} = null;{{/isFile}}{{#isFile}}org.apache.cxf.jaxrs.ext.multipart.Attachment {{paramName}} = null;{{/isFile}}
{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<InputStream>{{/collectionFormat}}{{^collectionFormat}}InputStream{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}} {{paramName}} = null;{{/isFile}}{{^isFile}}{{{dataType}}} {{paramName}} = null;{{/isFile}}
{{/allParams}}
//{{^vendorExtensions.x-java-is-response-void}}{{>returnTypes}} response = {{/vendorExtensions.x-java-is-response-void}}api.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
{{^vendorExtensions.x-java-is-response-void}}//assertNotNull(response);{{/vendorExtensions.x-java-is-response-void}}

View File

@ -1 +1 @@
{{#isBodyParam}}{{#useBeanValidation}}@Valid {{#required}}{{^isNullable}}@NotNull {{/isNullable}}{{/required}}{{/useBeanValidation}}{{{dataType}}} {{paramName}}{{/isBodyParam}}
{{#isBodyParam}}{{#useBeanValidation}}@Valid {{#required}}{{^isNullable}}@NotNull {{/isNullable}}{{/required}}{{/useBeanValidation}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<InputStream>{{/collectionFormat}}{{^collectionFormat}}InputStream{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{/isBodyParam}}

View File

@ -1 +1 @@
{{#isBodyParam}}{{{dataType}}} {{paramName}}{{/isBodyParam}}
{{#isBodyParam}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<InputStream>{{/collectionFormat}}{{^collectionFormat}}InputStream{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{/isBodyParam}}

View File

@ -1,4 +1,4 @@
{{#useGenericResponse}}Response{{/useGenericResponse}}{{! non-generic response:
}}{{^useGenericResponse}}{{!
}}{{{returnType}}}{{!
}}{{#isResponseFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<InputStream>{{/collectionFormat}}{{^collectionFormat}}InputStream{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}}{{!
}}{{/useGenericResponse}}

View File

@ -23,6 +23,7 @@ import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import org.openapitools.codegen.*;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.languages.AbstractJavaCodegen;
import org.openapitools.codegen.languages.JavaCXFClientCodegen;
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
@ -34,10 +35,18 @@ import org.openapitools.codegen.model.OperationsMap;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.openapitools.codegen.TestUtils.validateJavaSourceFiles;
public class JavaCXFClientCodegenTest {
@Test
@ -299,4 +308,41 @@ public class JavaCXFClientCodegenTest {
Assert.assertEquals(codegen.additionalProperties().get(AbstractJavaCodegen.JACKSON), Boolean.TRUE);
Assert.assertTrue(codegen.isUseJackson());
}
@Test
public void testUseAbstractionForFiles() throws Exception {
Map<String, Object> properties = new HashMap<>();
properties.put(CodegenConstants.API_PACKAGE, "xyz.abcdef.api");
properties.put(CodegenConstants.MODEL_PACKAGE, "xyz.abcdef.api");
properties.put(JavaCXFClientCodegen.USE_ABSTRACTION_FOR_FILES, true);
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("jaxrs-cxf-client")
.setAdditionalProperties(properties)
.setInputSpec("src/test/resources/3_0/issue8792.yaml")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
validateJavaSourceFiles(files);
Path defaultApi = Paths.get(output + "/src/gen/java/xyz/abcdef/api/DefaultApi.java");
TestUtils.assertFileContains(defaultApi,
//get file
"@ApiResponse(code = 200, message = \"File content\", response = InputStream.class)",
"public InputStream filesIdGet(@PathParam(\"id\") String id);",
//upload
"public FilesUploadPost200Response filesUploadPost(InputStream body);"
);
}
}

View File

@ -0,0 +1,52 @@
openapi: 3.0.0
info:
title: test useAbstractionForFiles for jaxrs-cxf
version: 0.0.1
servers:
- url: "http://localhost"
paths:
/files/{id}:
get:
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
200:
description: File content
content:
application/octet-stream:
schema:
type: string
format: binary
500:
description: error message
content:
application/json:
schema:
type: object
properties:
errormsg:
type: string
/files/upload:
post:
requestBody:
required: true
description: The file content to upload
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
200:
description: id
content:
application/json:
schema:
type: object
properties:
id:
type: string