Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/samples-jaxrs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ jobs:
- samples/server/petstore/jaxrs-spec-swagger-annotations
- samples/server/petstore/jaxrs-spec-swagger-v3-annotations-jakarta
- samples/server/petstore/jaxrs-spec-swagger-v3-annotations
- samples/server/petstore/jaxrs-spec/quarkus-security
steps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v5
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/samples-jdk17.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ on:
- samples/server/petstore/java-helidon-server/v3/mp/**
- samples/server/petstore/java-helidon-server/v3/se/**
- samples/server/petstore/jaxrs-spec-sealed/**
- samples/server/petstore/jaxrs-spec/quarkus-security/**
pull_request:
paths:
# clients
Expand All @@ -46,6 +47,7 @@ on:
- samples/server/petstore/java-helidon-server/v3/mp/**
- samples/server/petstore/java-helidon-server/v3/se/**
- samples/server/petstore/jaxrs-spec-sealed/**
- samples/server/petstore/jaxrs-spec/quarkus-security/**
jobs:
build:
name: Build with JDK17
Expand Down Expand Up @@ -75,6 +77,7 @@ jobs:
- samples/server/petstore/java-helidon-server/v3/mp/
- samples/server/petstore/java-helidon-server/v3/se
- samples/server/petstore/jaxrs-spec-sealed
- samples/server/petstore/jaxrs-spec/quarkus-security
steps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,13 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
additionalProperties.put("hasResponseStatusAnnotations", true);
}
}

// The quarkus templates bind file form parameters to org.jboss.resteasy.reactive types, so the
// corresponding imports must only be emitted for API files that actually declare such a parameter.
// Always set explicitly so Mustache does not fall through to the global additionalProperties value.
objs.put("hasFileFormParams", objs.getOperations().getOperation().stream()
.flatMap(op -> op.formParams.stream())
.anyMatch(p -> p.isFile));
return objs;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ import java.util.concurrent.CompletableFuture;
{{/useMutiny}}
{{/supportAsync}}

{{#useJakartaEe}}
{{#hasFileFormParams}}
import org.jboss.resteasy.reactive.RestForm;
import org.jboss.resteasy.reactive.multipart.FileUpload;

{{/hasFileFormParams}}
{{/useJakartaEe}}
import java.io.InputStream;
import java.util.Map;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{{#isFormParam}}
{{#isDeprecated}}@Deprecated {{/isDeprecated}}{{^isFile}}@FormParam(value = "{{baseName}}") {{{dataType}}} {{paramName}}{{/isFile}}{{#isFile}}{{#useJakartaEe}}{{^isArray}}@RestForm(value = "{{baseName}}") FileUpload {{paramName}}{{/isArray}}{{#isArray}}@RestForm(value = "{{baseName}}") List<FileUpload> {{paramName}}{{/isArray}}{{/useJakartaEe}}{{^useJakartaEe}}@FormParam(value = "{{baseName}}") InputStream {{paramName}}InputStream{{/useJakartaEe}}{{/isFile}}{{/isFormParam}}
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,30 @@
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<maven.compiler.parameters>true</maven.compiler.parameters>
{{#useJakartaEe}}
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
{{/useJakartaEe}}
{{^useJakartaEe}}
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
{{/useJakartaEe}}
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
{{#useJakartaEe}}
<quarkus-plugin.version>3.0.1.Final</quarkus-plugin.version>
<quarkus.platform.version>3.0.1.Final</quarkus.platform.version>
<quarkus-plugin.version>3.27.4.1</quarkus-plugin.version>
<quarkus.platform.version>3.27.4.1</quarkus.platform.version>
{{/useJakartaEe}}
{{^useJakartaEe}}
<quarkus-plugin.version>1.13.7.Final</quarkus-plugin.version>
<quarkus.platform.version>1.13.7.Final</quarkus.platform.version>
{{/useJakartaEe}}
{{#useJakartaEe}}
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
{{/useJakartaEe}}
{{^useJakartaEe}}
<quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
{{/useJakartaEe}}
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
<surefire-plugin.version>2.22.1</surefire-plugin.version>
{{#useJakartaEe}}
Expand Down Expand Up @@ -66,10 +77,25 @@
</dependencies>
</dependencyManagement>
<dependencies>
{{#useJakartaEe}}
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest</artifactId>
</dependency>
{{#useBeanValidation}}
<!-- quarkus-rest does not pull in bean validation transitively, unlike quarkus-resteasy -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
{{/useBeanValidation}}
{{/useJakartaEe}}
{{^useJakartaEe}}
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
{{/useJakartaEe}}
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2424,4 +2424,68 @@ public void generatesEmailAnnotationOnQueryParameterWhenBeanValidationEnabled()
assertFileContains(api, "import javax.validation.constraints.*;");
assertFileContains(api, "@QueryParam(\"email\")", "@Email", "String email");
}

/**
* On Quarkus REST a file form parameter is bound to the RESTEasy Reactive multipart type.
* {@code InputStream} is not a supported multipart type there.
*/
@Test
public void testQuarkusJakartaBindsFileFormParamToFileUpload() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');

final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("jaxrs-spec")
.setLibrary(QUARKUS_LIBRARY)
.setAdditionalProperties(Map.of(USE_JAKARTA_EE, "true"))
.setInputSpec("src/test/resources/3_0/form-multipart-binary-array.yaml")
.setOutputDir(outputPath);

DefaultGenerator generator = new DefaultGenerator(false);
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
validateJavaSourceFiles(files);

Path api = Paths.get(outputPath + "/src/gen/java/org/openapitools/api/MultipartSingleApi.java");
assertFileContains(api, "import org.jboss.resteasy.reactive.RestForm;");
assertFileContains(api, "import org.jboss.resteasy.reactive.multipart.FileUpload;");
assertFileContains(api, "@RestForm(value = \"file\") FileUpload _file");
// an array of binary properties keeps its array dimension: several files may share one
// part name, which FileUpload supports and a scalar binding cannot express
assertFileContains(Paths.get(outputPath + "/src/gen/java/org/openapitools/api/MultipartArrayApi.java"),
"@RestForm(value = \"files\") List<FileUpload> files");
// the project targets Quarkus REST rather than RESTEasy Classic
assertFileContains(Paths.get(outputPath + "/pom.xml"), "<artifactId>quarkus-rest</artifactId>");
}

/**
* The javax path is pinned to Quarkus 1.13.7, which predates Quarkus REST, so it keeps
* RESTEasy Classic and its {@code InputStream} binding.
*/
@Test
public void testQuarkusJavaxKeepsResteasyClassicFileBinding() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');

final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("jaxrs-spec")
.setLibrary(QUARKUS_LIBRARY)
.setInputSpec("src/test/resources/3_0/form-multipart-binary-array.yaml")
.setOutputDir(outputPath);

DefaultGenerator generator = new DefaultGenerator(false);
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
validateJavaSourceFiles(files);

Path api = Paths.get(outputPath + "/src/gen/java/org/openapitools/api/MultipartSingleApi.java");
assertFileContains(api, "@FormParam(value = \"file\") InputStream _fileInputStream");
assertFileNotContains(api, "import org.jboss.resteasy.reactive.multipart.FileUpload;");
// An array stays scalar here on purpose. @FormParam is a string-based annotation: injecting
// List<T> requires T to be constructible from a String, so List<InputStream> is rejected at
// deployment with RESTEASY003875. RESTEasy Classic has no portable multi-file binding.
assertFileNotContains(Paths.get(outputPath + "/src/gen/java/org/openapitools/api/MultipartArrayApi.java"),
"List<InputStream>");
assertFileContains(Paths.get(outputPath + "/pom.xml"), "<artifactId>quarkus-resteasy</artifactId>");
}
}
17 changes: 11 additions & 6 deletions samples/server/petstore/jaxrs-spec/quarkus-security/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<maven.compiler.parameters>true</maven.compiler.parameters>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus-plugin.version>3.0.1.Final</quarkus-plugin.version>
<quarkus.platform.version>3.0.1.Final</quarkus.platform.version>
<quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
<quarkus-plugin.version>3.27.4.1</quarkus-plugin.version>
<quarkus.platform.version>3.27.4.1</quarkus.platform.version>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
<surefire-plugin.version>2.22.1</surefire-plugin.version>
<jakarta.ws.rs-version>3.1.0</jakarta.ws.rs-version>
Expand All @@ -38,7 +38,12 @@
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
<artifactId>quarkus-rest</artifactId>
</dependency>
<!-- quarkus-rest does not pull in bean validation transitively, unlike quarkus-resteasy -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
Expand Down
Loading