diff --git a/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CodegenConfig.java b/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CodegenConfig.java index 23d48776..2f22b1e2 100644 --- a/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CodegenConfig.java +++ b/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CodegenConfig.java @@ -56,7 +56,8 @@ public enum ConfigName { GENERATE_PART_FILENAME("generate-part-filename"), PART_FILENAME_VALUE("part-filename-value"), USE_FIELD_NAME_IN_PART_FILENAME("use-field-name-in-part-filename"), - ADDITIONAL_PROPERTIES_AS_ATTRIBUTE("additional-properties-as-attribute"); + ADDITIONAL_PROPERTIES_AS_ATTRIBUTE("additional-properties-as-attribute"), + ADDITIONAL_REQUEST_ARGS("additional-request-args"); private final String name; diff --git a/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CommonItemConfig.java b/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CommonItemConfig.java index 1ec1e375..a16fce6a 100644 --- a/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CommonItemConfig.java +++ b/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CommonItemConfig.java @@ -48,6 +48,12 @@ public class CommonItemConfig { @ConfigItem(name = "additional-api-type-annotations") public Optional additionalApiTypeAnnotations; + /** + * Add custom/additional HTTP Headers or other args to every request + */ + @ConfigItem(name = "additional-request-args") + public Optional additionalRequestArgs; + /** * Defines if the methods should return {@link jakarta.ws.rs.core.Response} or a model. Default is false. */ diff --git a/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/codegen/OpenApiGeneratorCodeGenBase.java b/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/codegen/OpenApiGeneratorCodeGenBase.java index ff8dcd6d..62c754c7 100644 --- a/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/codegen/OpenApiGeneratorCodeGenBase.java +++ b/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/codegen/OpenApiGeneratorCodeGenBase.java @@ -205,6 +205,9 @@ protected void generate(final Config config, final Path openApiFilePath, final P getValues(config, openApiFilePath, CodegenConfig.ConfigName.ADDITIONAL_API_TYPE_ANNOTATIONS, String.class) .ifPresent(generator::withAdditionalApiTypeAnnotationsConfig); + getValues(config, openApiFilePath, CodegenConfig.ConfigName.ADDITIONAL_REQUEST_ARGS, String.class) + .ifPresent(generator::withAdditionalRequestArgs); + getConfigKeyValue(config, openApiFilePath) .ifPresentOrElse(generator::withConfigKey, () -> generator.withConfigKey(getSanitizedFileName(openApiFilePath))); diff --git a/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapper.java b/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapper.java index 052bb8e1..bc116e37 100644 --- a/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapper.java +++ b/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapper.java @@ -179,6 +179,13 @@ public OpenApiClientGeneratorWrapper withAdditionalApiTypeAnnotationsConfig(fina return this; } + public OpenApiClientGeneratorWrapper withAdditionalRequestArgs(final String additionalRequestArgs) { + if (additionalRequestArgs != null) { + this.configurator.addAdditionalProperty("additionalRequestArgs", additionalRequestArgs.split(";")); + } + return this; + } + public void withTemplateDir(Path templateDir) { this.configurator.addAdditionalProperty("templateDir", templateDir.toString()); } diff --git a/deployment/src/main/resources/templates/libraries/microprofile/api.qute b/deployment/src/main/resources/templates/libraries/microprofile/api.qute index 59585914..0f9e7758 100644 --- a/deployment/src/main/resources/templates/libraries/microprofile/api.qute +++ b/deployment/src/main/resources/templates/libraries/microprofile/api.qute @@ -92,6 +92,11 @@ public interface {classname} { {/if} {/if} {/if} + {#if additionalRequestArgs} + {#for arg in additionalRequestArgs}{! + !}{arg}{#if arg_hasNext}, {/if}{/for}{! + !}{#if op.hasFormParams || op.allParams},{/if} + {/if} {#if op.hasFormParams} {#if is-resteasy-reactive} @jakarta.ws.rs.BeanParam {op.operationIdCamelCase}MultipartForm multipartForm{#if op.hasPathParams},{/if}{! diff --git a/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapperTest.java b/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapperTest.java index 9e523d5c..b2d47462 100644 --- a/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapperTest.java +++ b/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapperTest.java @@ -536,6 +536,60 @@ private void verifyApiAdditionalAnnotations(File file) { } } + @Test + void verifyAdditionalRequestArgs() throws URISyntaxException { + List generatedFiles = createGeneratorWrapper("petstore-openapi.json") + .withEnabledSecurityGeneration(false) + .withAdditionalRequestArgs( + "@HeaderParam(\"jaxrs-style-header\") String headerValue;@HeaderParam(\"x-correlation-id\") String correlationId;@PathParam(\"stream\") String stream") + .generate("org.additionalHTTPHeaders"); + assertFalse(generatedFiles.isEmpty()); + + generatedFiles.stream() + .filter(file -> file.getPath() + .matches(".*api.*Api.java")) + .forEach(this::verifyApiAdditionalHTTPHeaders); + } + + private void verifyApiAdditionalHTTPHeaders(File file) { + try { + CompilationUnit compilationUnit = StaticJavaParser.parse(file); + compilationUnit.findAll(MethodDeclaration.class) + .forEach(c -> { + assertParameter(c.getParameterByName("correlationId"), + "String", + Map.of("HeaderParam", + "\"x-correlation-id\"")); + assertParameter(c.getParameterByName("headerValue"), + "String", + Map.of("HeaderParam", + "\"jaxrs-style-header\"")); + assertParameter(c.getParameterByName("stream"), + "String", + Map.of("PathParam", + "\"stream\"")); + }); + } catch (FileNotFoundException e) { + throw new RuntimeException(e.getMessage()); + } + } + + private void assertParameter(Optional optionalParameter, + String type, + Map annotations) { + assertThat(optionalParameter).isPresent(); + var parameter = optionalParameter.orElseThrow(); + assertThat(parameter.getTypeAsString()).isEqualTo(type); + annotations.forEach((annotationName, annotationValue) -> { + var parameterAnnotation = parameter.getAnnotationByName(annotationName); + assertThat(parameterAnnotation).isPresent(); + assertThat(parameterAnnotation.get() + .asSingleMemberAnnotationExpr() + .getMemberValue() + .toString()).hasToString(annotationValue); + }); + } + @Test void verifyAPINormalization() throws Exception { final List generatedFiles = this.createGeneratorWrapper("open-api-normalizer.json") diff --git a/docs/modules/ROOT/pages/includes/additional-request-args.adoc b/docs/modules/ROOT/pages/includes/additional-request-args.adoc new file mode 100644 index 00000000..5fc9f88b --- /dev/null +++ b/docs/modules/ROOT/pages/includes/additional-request-args.adoc @@ -0,0 +1,17 @@ +To add custom request specific parameters you can use the `additional-request-args` property. + +Should work with: + +* @PathParam +* @QueryParam +* @CookieParam +* @FormParam +* @MatrixParam + +To use `additional-request-args` as attribute, add the following entry to your properties file. In this example, our spec file is in `src/main/openapi/petstore.json`: + +---- +quarkus.openapi-generator.codegen.spec.petstore_json.additional-request-args=@CookieParam("cookie") String cookie;@HeaderParam("x-correlation-id") String correlationId +---- + +This configuration is applied to every generated method. \ No newline at end of file diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc index eaad1d84..d99648ff 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/modules/ROOT/pages/index.adoc @@ -163,6 +163,12 @@ include::./includes/template-customization.adoc[leveloffset=+1, opts=optional] include::./includes/additional-properties-as-attribute.adoc[leveloffset=+1, opts=optional] +[[additional-request-args]] +== Add Additional Request Arguments to each API Method + +include::./includes/additional-request-args.adoc[leveloffset=+1, opts=optional] + + == Known Limitations These are the known limitations of this pre-release version: