From ce7b1b0df47e918e5ef7aefc0b824fee26bc03a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwydion=20Mart=C3=ADn?= <118427625+gwydionmv@users.noreply.github.com> Date: Fri, 2 Dec 2022 15:01:27 +0100 Subject: [PATCH] Change base directory + add include property (#179) * Change base directory + add include property * Changes from PR * Changes from PR * Changes from PR * Generalize baseModuleDirectory path * format code * Make shouldRun throw an exception when the path is invalid * Revert "Make shouldRun throw an exception when the path is invalid" This reverts commit c08313937067b535f4ccd982d0188b25270910b5. Co-authored-by: Gwydion Martin --- README.md | 25 +- .../generator/deployment/CodegenConfig.java | 3 + .../codegen/OpenApiGeneratorCodeGenBase.java | 39 ++- .../OpenApiClientGeneratorWrapperTest.java | 6 +- .../openapi-definitions/simple-openapi.yaml | 274 ++++++++++++++++++ integration-tests/change-directory/pom.xml | 96 ++++++ .../src/main/resources/application.properties | 2 + .../src/test/java/it/ChangeDirectoryTest.java | 24 ++ integration-tests/{ignore => exclude}/pom.xml | 8 +- .../src/main/openapi/exclude-openapi.yaml} | 8 +- .../src/main/openapi/openapi.yaml} | 0 .../src/main/resources/application.properties | 1 + .../openapi/generator/it/ExcludeTest.java | 21 ++ .../src/main/resources/application.properties | 1 - .../openapi/generator/it/IgnoreTest.java | 24 -- integration-tests/include/pom.xml | 90 ++++++ .../src/main/openapi/ignore-openapi.yaml} | 2 +- .../src/main/openapi/include-openapi.yaml | 274 ++++++++++++++++++ .../src/main/resources/application.properties | 1 + .../openapi/generator/it/IncludeTest.java | 21 ++ integration-tests/pom.xml | 4 +- 21 files changed, 877 insertions(+), 47 deletions(-) create mode 100644 integration-tests/change-directory/openapi-definitions/simple-openapi.yaml create mode 100644 integration-tests/change-directory/pom.xml create mode 100644 integration-tests/change-directory/src/main/resources/application.properties create mode 100644 integration-tests/change-directory/src/test/java/it/ChangeDirectoryTest.java rename integration-tests/{ignore => exclude}/pom.xml (95%) rename integration-tests/{ignore/src/main/openapi/ignored-openapi-2.yaml => exclude/src/main/openapi/exclude-openapi.yaml} (64%) rename integration-tests/{ignore/src/main/openapi/simple-openapi.yaml => exclude/src/main/openapi/openapi.yaml} (100%) create mode 100644 integration-tests/exclude/src/main/resources/application.properties create mode 100644 integration-tests/exclude/src/test/java/io/quarkiverse/openapi/generator/it/ExcludeTest.java delete mode 100644 integration-tests/ignore/src/main/resources/application.properties delete mode 100644 integration-tests/ignore/src/test/java/io/quarkiverse/openapi/generator/it/IgnoreTest.java create mode 100644 integration-tests/include/pom.xml rename integration-tests/{ignore/src/main/openapi/ignored-openapi.yaml => include/src/main/openapi/ignore-openapi.yaml} (91%) create mode 100644 integration-tests/include/src/main/openapi/include-openapi.yaml create mode 100644 integration-tests/include/src/main/resources/application.properties create mode 100644 integration-tests/include/src/test/java/io/quarkiverse/openapi/generator/it/IncludeTest.java diff --git a/README.md b/README.md index 28ee1b73..f444ab63 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,16 @@ You probably already have this configuration if you created your application wit Now, create the directory `openapi` under your `src/main/` path and add the OpenAPI spec files there. We support JSON, YAML and YML extensions. +If you want to change the directory where OpenAPI files must be found, use the property `quarkus.openapi-generator.codegen.input-base-dir`. +IMPORTANT: it is relative to the project base directory. For example, if you have a project called `MyJavaProject` and decide to place them in `MyJavaProject/openapi-definitions`, use the following property: + +```properties +quarkus.openapi-generator.codegen.input-base-dir=openapi-definitions +``` + To fine tune the configuration for each spec file, add the following entry to your properties file. In this example, our spec file is in `src/main/openapi/petstore.json`: ```properties -quarkus.openapi-generator.codegen.spec.petstore_json.base-package=org.acme.openapi quarkus.openapi-generator.codegen.spec.petstore_json.additional-model-type-annotations=@org.test.Foo;@org.test.Bar ``` @@ -120,16 +126,25 @@ Since the most part of this extension work is in the `generate-code` execution p For more information, see the [Maven Logging Configuration](https://maven.apache.org/maven-logging.html) guide. -## Ignoring OpenAPI Specification Files +## Filtering OpenAPI Specification Files -To ignore code generation for specific OpenAPI specification files, you can set the `quarkus.openapi-generator.codegen.ignore` property. +By default, the extension will process every OpenAPI specification file in the given path. +To limit code generation to only a specific set of OpenAPI specification files, you can set the `quarkus.openapi-generator.codegen.include` property. +For instance, if you want to limit code generation for `include-openapi.yaml` and `include-openapi-2.yaml` files, you need to define the property like: -For instance, if you want to ignore code generation for `ignored-openapi.yaml` and `ignored-openapi-2.yaml` files, you need to define the `quarkus.openapi-generator.codegen.ignore` property like the following: +```properties +quarkus.openapi-generator.codegen.include=include-openapi.yaml,include-openapi-2.yaml +``` + +If you prefer to specify which files you want to skip, you can set the `quarkus.openapi-generator.codegen.exclude` property. +For instance, if you want to skip code generation for `exclude-openapi.yaml` and `exclude-openapi-2.yaml` files, you need to define the property like: ```properties -quarkus.openapi-generator.codegen.ignore=ignored-openapi.yaml,ignored-openapi-2.yaml +quarkus.openapi-generator.codegen.exclude=exclude-openapi.yaml,exclude-openapi-2.yaml ``` +IMPORTANT: `exclude` supersedes `include`, meaning that if a file is in both property it will NOT be analysed. + See the module [ignore](integration-tests/ignore) for an example of how to use this feature. ## Authentication Support 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 a43c2bec..32a2c3a3 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 @@ -18,6 +18,9 @@ public class CodegenConfig { public static final String API_PKG_SUFFIX = ".api"; public static final String MODEL_PKG_SUFFIX = ".model"; public static final String VERBOSE_PROPERTY_NAME = "quarkus." + CODEGEN_TIME_CONFIG_PREFIX + ".verbose"; + public static final String INPUT_BASE_DIR = "quarkus." + CODEGEN_TIME_CONFIG_PREFIX + ".input-base-dir"; + public static final String INCLUDE_FILES = "quarkus." + CODEGEN_TIME_CONFIG_PREFIX + ".include"; + public static final String EXCLUDE_FILES = "quarkus." + CODEGEN_TIME_CONFIG_PREFIX + ".exclude"; public static final String VALIDATE_SPEC_PROPERTY_NAME = "quarkus." + CODEGEN_TIME_CONFIG_PREFIX + ".validateSpec"; public static final String DEFAULT_SECURITY_SCHEME = "quarkus." + CODEGEN_TIME_CONFIG_PREFIX + ".default.security.scheme"; // package visibility for unit tests 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 8a67d8c4..2c280c8d 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 @@ -1,5 +1,8 @@ package io.quarkiverse.openapi.generator.deployment.codegen; +import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.EXCLUDE_FILES; +import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.INCLUDE_FILES; +import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.INPUT_BASE_DIR; import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.VALIDATE_SPEC_PROPERTY_NAME; import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.VERBOSE_PROPERTY_NAME; import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getAdditionalModelTypeAnnotationsPropertyName; @@ -19,6 +22,7 @@ import org.eclipse.microprofile.config.Config; import org.openapitools.codegen.config.GlobalSettings; +import io.quarkiverse.openapi.generator.OpenApiGeneratorException; import io.quarkiverse.openapi.generator.deployment.CodegenConfig; import io.quarkiverse.openapi.generator.deployment.circuitbreaker.CircuitBreakerConfigurationParser; import io.quarkiverse.openapi.generator.deployment.wrapper.OpenApiClientGeneratorWrapper; @@ -41,17 +45,37 @@ public abstract class OpenApiGeneratorCodeGenBase implements CodeGenProvider { private static final String DEFAULT_PACKAGE = "org.openapi.quarkus"; + /** + * The input base directory from + * + *
+     * src/main
+     *
+     * 
+     * directory.
+     * Ignored if INPUT_BASE_DIR is specified.
+     **/
     @Override
     public String inputDirectory() {
         return "openapi";
     }
 
+    @Override
+    public boolean shouldRun(Path sourceDir, Config config) {
+        String inputBaseDir = getInputBaseDirRelativeToModule(sourceDir, config);
+        if (inputBaseDir != null && !Files.isDirectory(Path.of(inputBaseDir))) {
+            throw new OpenApiGeneratorException(String.format("Invalid path on %s: %s", INPUT_BASE_DIR, inputBaseDir));
+        }
+        return inputBaseDir != null || Files.isDirectory(sourceDir);
+    }
+
     @Override
     public boolean trigger(CodeGenContext context) throws CodeGenException {
         final Path outDir = context.outDir();
-        final Path openApiDir = context.inputDir();
-        final List ignoredFiles = context.config()
-                .getOptionalValues("quarkus.openapi-generator.codegen.ignore", String.class).orElse(List.of());
+        String inputBaseDir = getInputBaseDirRelativeToModule(context.inputDir(), context.config());
+        final Path openApiDir = inputBaseDir != null ? Path.of(inputBaseDir) : context.inputDir();
+        final List filesToInclude = context.config().getOptionalValues(INCLUDE_FILES, String.class).orElse(List.of());
+        final List filesToExclude = context.config().getOptionalValues(EXCLUDE_FILES, String.class).orElse(List.of());
 
         if (Files.isDirectory(openApiDir)) {
             try (Stream openApiFilesPaths = Files.walk(openApiDir)) {
@@ -59,7 +83,9 @@ public boolean trigger(CodeGenContext context) throws CodeGenException {
                         .filter(Files::isRegularFile)
                         .filter(path -> {
                             String fileName = path.getFileName().toString();
-                            return fileName.endsWith(inputExtension()) && !ignoredFiles.contains(fileName);
+                            return fileName.endsWith(inputExtension())
+                                    && !filesToExclude.contains(fileName)
+                                    && (filesToInclude.isEmpty() || filesToInclude.contains(fileName));
                         })
                         .forEach(openApiFilePath -> generate(context.config(), openApiFilePath, outDir));
             } catch (IOException e) {
@@ -112,4 +138,9 @@ private String getBasePackage(final Config config, final Path openApiFilePath) {
                 .getOptionalValue(getBasePackagePropertyName(openApiFilePath), String.class)
                 .orElse(String.format("%s.%s", DEFAULT_PACKAGE, getSanitizedFileName(openApiFilePath)));
     }
+
+    private String getInputBaseDirRelativeToModule(final Path sourceDir, final Config config) {
+        String baseModuleDirectory = sourceDir.toString().substring(0, sourceDir.toString().lastIndexOf("src"));
+        return config.getOptionalValue(INPUT_BASE_DIR, String.class).map(s -> baseModuleDirectory + s).orElse(null);
+    }
 }
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 e352aa90..b412e7d9 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
@@ -352,8 +352,8 @@ void shouldReplaceFileImportWithInputStream() throws URISyntaxException, FileNot
                 .stream()
                 .map(importDeclaration -> importDeclaration.getName().asString())
                 .collect(Collectors.toList());
-        assertThat(imports).contains("java.io.InputStream");
-        assertThat(imports).doesNotContain("java.io.File");
+        assertThat(imports).contains("java.io.InputStream")
+                .doesNotContain("java.io.File");
     }
 
     @Test
@@ -446,7 +446,7 @@ void verifyAdditionalModelTypeAnnotations() throws URISyntaxException {
 
         generatedFiles.stream()
                 .filter(file -> file.getPath().matches(".*/model/.*.java"))
-                .forEach(file -> verifyModelAdditionalAnnotations(file));
+                .forEach(this::verifyModelAdditionalAnnotations);
     }
 
     private void verifyModelAdditionalAnnotations(File file) {
diff --git a/integration-tests/change-directory/openapi-definitions/simple-openapi.yaml b/integration-tests/change-directory/openapi-definitions/simple-openapi.yaml
new file mode 100644
index 00000000..4a853fe0
--- /dev/null
+++ b/integration-tests/change-directory/openapi-definitions/simple-openapi.yaml
@@ -0,0 +1,274 @@
+---
+openapi: 3.0.3
+info:
+  title: greeting-flow API
+  version: "1.0"
+paths:
+  /:
+    post:
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              $ref: '#/components/schemas/CloudEvent'
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Response'
+  /hello:
+    get:
+      tags:
+        - Reactive Greeting Resource
+      operationId: hello
+      responses:
+        "200":
+          description: OK
+          content:
+            text/plain:
+              schema:
+                type: string
+  /messaging/topics:
+    get:
+      tags:
+        - Quarkus Topics Information Resource
+      responses:
+        "200":
+          description: OK
+components:
+  schemas:
+    CloudEvent:
+      type: object
+      properties:
+        specVersion:
+          $ref: '#/components/schemas/SpecVersion'
+        id:
+          type: string
+        type:
+          type: string
+        source:
+          format: uri
+          type: string
+        dataContentType:
+          type: string
+        dataSchema:
+          format: uri
+          type: string
+        subject:
+          type: string
+        time:
+          format: date-time
+          type: string
+        attributeNames:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        extensionNames:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        data:
+          $ref: '#/components/schemas/CloudEventData'
+    CloudEventData:
+      type: object
+    EntityTag:
+      type: object
+      properties:
+        value:
+          type: string
+        weak:
+          type: boolean
+    Family:
+      enum:
+        - INFORMATIONAL
+        - SUCCESSFUL
+        - REDIRECTION
+        - CLIENT_ERROR
+        - SERVER_ERROR
+        - OTHER
+      type: string
+    Link:
+      type: object
+      properties:
+        uri:
+          format: uri
+          type: string
+        uriBuilder:
+          $ref: '#/components/schemas/UriBuilder'
+        rel:
+          type: string
+        rels:
+          type: array
+          items:
+            type: string
+        title:
+          type: string
+        type:
+          type: string
+        params:
+          type: object
+          additionalProperties:
+            type: string
+    Locale:
+      type: object
+      properties:
+        language:
+          type: string
+        script:
+          type: string
+        country:
+          type: string
+        variant:
+          type: string
+        extensionKeys:
+          uniqueItems: true
+          type: array
+          items:
+            format: byte
+            type: string
+        unicodeLocaleAttributes:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        unicodeLocaleKeys:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        iSO3Language:
+          type: string
+        iSO3Country:
+          type: string
+        displayLanguage:
+          type: string
+        displayScript:
+          type: string
+        displayCountry:
+          type: string
+        displayVariant:
+          type: string
+        displayName:
+          type: string
+    MediaType:
+      type: object
+      properties:
+        type:
+          type: string
+        subtype:
+          type: string
+        parameters:
+          type: object
+          additionalProperties:
+            type: string
+        wildcardType:
+          type: boolean
+        wildcardSubtype:
+          type: boolean
+    MultivaluedMapStringObject:
+      type: object
+      additionalProperties:
+        type: array
+        items:
+          type: object
+    MultivaluedMapStringString:
+      type: object
+      additionalProperties:
+        type: array
+        items:
+          type: string
+    NewCookie:
+      type: object
+      properties:
+        name:
+          type: string
+        value:
+          type: string
+        version:
+          format: int32
+          type: integer
+        path:
+          type: string
+        domain:
+          type: string
+        comment:
+          type: string
+        maxAge:
+          format: int32
+          type: integer
+        expiry:
+          format: date
+          type: string
+        secure:
+          type: boolean
+        httpOnly:
+          type: boolean
+    Response:
+      type: object
+      properties:
+        status:
+          format: int32
+          type: integer
+        statusInfo:
+          $ref: '#/components/schemas/StatusType'
+        entity:
+          type: object
+        mediaType:
+          $ref: '#/components/schemas/MediaType'
+        language:
+          $ref: '#/components/schemas/Locale'
+        length:
+          format: int32
+          type: integer
+        allowedMethods:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        cookies:
+          type: object
+          additionalProperties:
+            $ref: '#/components/schemas/NewCookie'
+        entityTag:
+          $ref: '#/components/schemas/EntityTag'
+        date:
+          format: date
+          type: string
+        lastModified:
+          format: date
+          type: string
+        location:
+          format: uri
+          type: string
+        links:
+          uniqueItems: true
+          type: array
+          items:
+            $ref: '#/components/schemas/Link'
+        metadata:
+          $ref: '#/components/schemas/MultivaluedMapStringObject'
+        headers:
+          $ref: '#/components/schemas/MultivaluedMapStringObject'
+        stringHeaders:
+          $ref: '#/components/schemas/MultivaluedMapStringString'
+    SpecVersion:
+      enum:
+        - V03
+        - V1
+      type: string
+    StatusType:
+      type: object
+      properties:
+        statusCode:
+          format: int32
+          type: integer
+        family:
+          $ref: '#/components/schemas/Family'
+        reasonPhrase:
+          type: string
+    UriBuilder:
+      type: object
diff --git a/integration-tests/change-directory/pom.xml b/integration-tests/change-directory/pom.xml
new file mode 100644
index 00000000..ff749412
--- /dev/null
+++ b/integration-tests/change-directory/pom.xml
@@ -0,0 +1,96 @@
+
+
+    4.0.0
+    
+        quarkus-openapi-generator-integration-tests
+        io.quarkiverse.openapi.generator
+        1.0.0-SNAPSHOT
+    
+    quarkus-openapi-generator-it-change-directory
+    Quarkus - Openapi Generator - Integration Tests - Change directory
+
+    
+        
+            io.quarkiverse.openapi.generator
+            quarkus-openapi-generator
+        
+        
+            io.quarkus
+            quarkus-junit5
+            test
+        
+        
+            com.github.tomakehurst
+            wiremock-jre8
+            test
+        
+        
+            io.quarkiverse.openapi.generator
+            quarkus-openapi-generator-test-utils
+            test
+        
+    
+
+    
+        
+            
+                io.quarkus
+                quarkus-maven-plugin
+                true
+                
+                    
+                        
+                            build
+                            generate-code
+                            generate-code-tests
+                        
+                    
+                
+            
+        
+    
+    
+        
+            native-image
+            
+                
+                    native
+                
+            
+            
+                
+                    
+                        maven-surefire-plugin
+                        
+                            ${native.surefire.skip}
+                        
+                    
+                    
+                        maven-failsafe-plugin
+                        
+                            
+                                
+                                    integration-test
+                                    verify
+                                
+                                
+                                    
+                                        ${project.build.directory}/${project.build.finalName}-runner
+                                        org.jboss.logmanager.LogManager
+                                        ${maven.home}
+                                    
+                                
+                            
+                        
+                    
+                
+            
+            
+                native
+            
+        
+    
+
+
diff --git a/integration-tests/change-directory/src/main/resources/application.properties b/integration-tests/change-directory/src/main/resources/application.properties
new file mode 100644
index 00000000..bae71fb0
--- /dev/null
+++ b/integration-tests/change-directory/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+quarkus.openapi-generator.codegen.input-base-dir=openapi-definitions
+quarkus.openapi-generator.codegen.spec.simple_openapi_yaml.base-package=org.simple.openapi
diff --git a/integration-tests/change-directory/src/test/java/it/ChangeDirectoryTest.java b/integration-tests/change-directory/src/test/java/it/ChangeDirectoryTest.java
new file mode 100644
index 00000000..379df914
--- /dev/null
+++ b/integration-tests/change-directory/src/test/java/it/ChangeDirectoryTest.java
@@ -0,0 +1,24 @@
+package it;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import javax.inject.Inject;
+
+import org.eclipse.microprofile.rest.client.inject.RestClient;
+import org.junit.jupiter.api.Test;
+import org.simple.openapi.api.ReactiveGreetingResourceApi;
+
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+class ChangeDirectoryTest {
+
+    @RestClient
+    @Inject
+    ReactiveGreetingResourceApi api;
+
+    @Test
+    void apiIsBeingGenerated() {
+        assertThat(api).isNotNull();
+    }
+}
diff --git a/integration-tests/ignore/pom.xml b/integration-tests/exclude/pom.xml
similarity index 95%
rename from integration-tests/ignore/pom.xml
rename to integration-tests/exclude/pom.xml
index 295c4ead..a2e49548 100644
--- a/integration-tests/ignore/pom.xml
+++ b/integration-tests/exclude/pom.xml
@@ -7,9 +7,9 @@
     
     4.0.0
 
-    quarkus-openapi-generator-it-ignore
-    Quarkus - Openapi Generator - Integration Tests - Ignore
-    Example project with OpenAPI documents that should be ignored
+    quarkus-openapi-generator-it-exclude
+    Quarkus - Openapi Generator - Integration Tests - Exclude
+    Example project with OpenAPI documents that should be excluded
 
     
         
@@ -87,4 +87,4 @@
         
     
 
-
\ No newline at end of file
+
diff --git a/integration-tests/ignore/src/main/openapi/ignored-openapi-2.yaml b/integration-tests/exclude/src/main/openapi/exclude-openapi.yaml
similarity index 64%
rename from integration-tests/ignore/src/main/openapi/ignored-openapi-2.yaml
rename to integration-tests/exclude/src/main/openapi/exclude-openapi.yaml
index 792920dd..1eb04430 100644
--- a/integration-tests/ignore/src/main/openapi/ignored-openapi-2.yaml
+++ b/integration-tests/exclude/src/main/openapi/exclude-openapi.yaml
@@ -4,15 +4,15 @@ info:
   title: greeting-flow API
   version: "1.0"
 paths:
-  /hello_ignored_2:
+  /hello_excluded:
     get:
       tags:
-        - Ignored OpenAPI Resource 2
-      operationId: hello_ignored_2
+        - Excluded OpenAPI Resource
+      operationId: hello_excluded
       responses:
         "200":
           description: OK
           content:
             text/plain:
               schema:
-                type: string
\ No newline at end of file
+                type: string
diff --git a/integration-tests/ignore/src/main/openapi/simple-openapi.yaml b/integration-tests/exclude/src/main/openapi/openapi.yaml
similarity index 100%
rename from integration-tests/ignore/src/main/openapi/simple-openapi.yaml
rename to integration-tests/exclude/src/main/openapi/openapi.yaml
diff --git a/integration-tests/exclude/src/main/resources/application.properties b/integration-tests/exclude/src/main/resources/application.properties
new file mode 100644
index 00000000..a5f55c31
--- /dev/null
+++ b/integration-tests/exclude/src/main/resources/application.properties
@@ -0,0 +1 @@
+quarkus.openapi-generator.codegen.exclude=exclude-openapi.yaml
diff --git a/integration-tests/exclude/src/test/java/io/quarkiverse/openapi/generator/it/ExcludeTest.java b/integration-tests/exclude/src/test/java/io/quarkiverse/openapi/generator/it/ExcludeTest.java
new file mode 100644
index 00000000..daebb1be
--- /dev/null
+++ b/integration-tests/exclude/src/test/java/io/quarkiverse/openapi/generator/it/ExcludeTest.java
@@ -0,0 +1,21 @@
+package io.quarkiverse.openapi.generator.it;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+class ExcludeTest {
+
+    @Test
+    void onlyNonExcludedClassesAreGenerated() throws ClassNotFoundException {
+        assertThat(Class.forName("org.openapi.quarkus.openapi_yaml.api.SimpleOpenApiResourceApi"))
+                .isNotNull();
+
+        assertThatCode(() -> Class.forName("org.openapi.quarkus.exclude_openapi_yaml.api.ExcludedOpenApiResourceApi"))
+                .isInstanceOf(ClassNotFoundException.class);
+    }
+}
diff --git a/integration-tests/ignore/src/main/resources/application.properties b/integration-tests/ignore/src/main/resources/application.properties
deleted file mode 100644
index 81cb00aa..00000000
--- a/integration-tests/ignore/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-quarkus.openapi-generator.codegen.ignore=ignored-openapi.yaml,ignored-openapi-2.yaml
\ No newline at end of file
diff --git a/integration-tests/ignore/src/test/java/io/quarkiverse/openapi/generator/it/IgnoreTest.java b/integration-tests/ignore/src/test/java/io/quarkiverse/openapi/generator/it/IgnoreTest.java
deleted file mode 100644
index 7c29d937..00000000
--- a/integration-tests/ignore/src/test/java/io/quarkiverse/openapi/generator/it/IgnoreTest.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package io.quarkiverse.openapi.generator.it;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-
-import org.junit.jupiter.api.Test;
-
-import io.quarkus.test.junit.QuarkusTest;
-
-@QuarkusTest
-class IgnoreTest {
-
-    @Test
-    void onlyNonIgnoredClassesAreGenerated() throws ClassNotFoundException {
-        assertThat(Class.forName("org.openapi.quarkus.simple_openapi_yaml.api.SimpleOpenApiResourceApi"))
-                .isNotNull();
-
-        assertThatCode(() -> Class.forName("org.openapi.quarkus.ignored_openapi_yaml.api.IgnoredOpenApiResourceApi"))
-                .isInstanceOf(ClassNotFoundException.class);
-
-        assertThatCode(() -> Class.forName("org.openapi.quarkus.ignored_openapi_2_yaml.api.IgnoredOpenApiResource2Api"))
-                .isInstanceOf(ClassNotFoundException.class);
-    }
-}
diff --git a/integration-tests/include/pom.xml b/integration-tests/include/pom.xml
new file mode 100644
index 00000000..1f43169d
--- /dev/null
+++ b/integration-tests/include/pom.xml
@@ -0,0 +1,90 @@
+
+
+    
+        quarkus-openapi-generator-integration-tests
+        io.quarkiverse.openapi.generator
+        1.0.0-SNAPSHOT
+    
+    4.0.0
+
+    quarkus-openapi-generator-it-include
+    Quarkus - Openapi Generator - Integration Tests - Include
+    Example project with OpenAPI documents that should be included
+
+    
+        
+            io.quarkiverse.openapi.generator
+            quarkus-openapi-generator
+        
+        
+            org.assertj
+            assertj-core
+            test
+        
+        
+            io.quarkus
+            quarkus-junit5
+            test
+        
+    
+    
+        
+            
+                io.quarkus
+                quarkus-maven-plugin
+                true
+                
+                    
+                        
+                            build
+                            generate-code
+                            generate-code-tests
+                        
+                    
+                
+            
+        
+    
+    
+        
+            native-image
+            
+                
+                    native
+                
+            
+            
+                
+                    
+                        maven-surefire-plugin
+                        
+                            ${native.surefire.skip}
+                        
+                    
+                    
+                        maven-failsafe-plugin
+                        
+                            
+                                
+                                    integration-test
+                                    verify
+                                
+                                
+                                    
+                                        ${project.build.directory}/${project.build.finalName}-runner
+                                        org.jboss.logmanager.LogManager
+                                        ${maven.home}
+                                    
+                                
+                            
+                        
+                    
+                
+            
+            
+                native
+            
+        
+    
+
+
diff --git a/integration-tests/ignore/src/main/openapi/ignored-openapi.yaml b/integration-tests/include/src/main/openapi/ignore-openapi.yaml
similarity index 91%
rename from integration-tests/ignore/src/main/openapi/ignored-openapi.yaml
rename to integration-tests/include/src/main/openapi/ignore-openapi.yaml
index 6219a3a3..379cc72d 100644
--- a/integration-tests/ignore/src/main/openapi/ignored-openapi.yaml
+++ b/integration-tests/include/src/main/openapi/ignore-openapi.yaml
@@ -15,4 +15,4 @@ paths:
           content:
             text/plain:
               schema:
-                type: string
\ No newline at end of file
+                type: string
diff --git a/integration-tests/include/src/main/openapi/include-openapi.yaml b/integration-tests/include/src/main/openapi/include-openapi.yaml
new file mode 100644
index 00000000..0741d286
--- /dev/null
+++ b/integration-tests/include/src/main/openapi/include-openapi.yaml
@@ -0,0 +1,274 @@
+---
+openapi: 3.0.3
+info:
+  title: greeting-flow API
+  version: "1.0"
+paths:
+  /:
+    post:
+      requestBody:
+        content:
+          '*/*':
+            schema:
+              $ref: '#/components/schemas/CloudEvent'
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Response'
+  /hello:
+    get:
+      tags:
+        - Simple OpenAPI Resource
+      operationId: hello
+      responses:
+        "200":
+          description: OK
+          content:
+            text/plain:
+              schema:
+                type: string
+  /messaging/topics:
+    get:
+      tags:
+        - Quarkus Topics Information Resource
+      responses:
+        "200":
+          description: OK
+components:
+  schemas:
+    CloudEvent:
+      type: object
+      properties:
+        specVersion:
+          $ref: '#/components/schemas/SpecVersion'
+        id:
+          type: string
+        type:
+          type: string
+        source:
+          format: uri
+          type: string
+        dataContentType:
+          type: string
+        dataSchema:
+          format: uri
+          type: string
+        subject:
+          type: string
+        time:
+          format: date-time
+          type: string
+        attributeNames:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        extensionNames:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        data:
+          $ref: '#/components/schemas/CloudEventData'
+    CloudEventData:
+      type: object
+    EntityTag:
+      type: object
+      properties:
+        value:
+          type: string
+        weak:
+          type: boolean
+    Family:
+      enum:
+        - INFORMATIONAL
+        - SUCCESSFUL
+        - REDIRECTION
+        - CLIENT_ERROR
+        - SERVER_ERROR
+        - OTHER
+      type: string
+    Link:
+      type: object
+      properties:
+        uri:
+          format: uri
+          type: string
+        uriBuilder:
+          $ref: '#/components/schemas/UriBuilder'
+        rel:
+          type: string
+        rels:
+          type: array
+          items:
+            type: string
+        title:
+          type: string
+        type:
+          type: string
+        params:
+          type: object
+          additionalProperties:
+            type: string
+    Locale:
+      type: object
+      properties:
+        language:
+          type: string
+        script:
+          type: string
+        country:
+          type: string
+        variant:
+          type: string
+        extensionKeys:
+          uniqueItems: true
+          type: array
+          items:
+            format: byte
+            type: string
+        unicodeLocaleAttributes:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        unicodeLocaleKeys:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        iSO3Language:
+          type: string
+        iSO3Country:
+          type: string
+        displayLanguage:
+          type: string
+        displayScript:
+          type: string
+        displayCountry:
+          type: string
+        displayVariant:
+          type: string
+        displayName:
+          type: string
+    MediaType:
+      type: object
+      properties:
+        type:
+          type: string
+        subtype:
+          type: string
+        parameters:
+          type: object
+          additionalProperties:
+            type: string
+        wildcardType:
+          type: boolean
+        wildcardSubtype:
+          type: boolean
+    MultivaluedMapStringObject:
+      type: object
+      additionalProperties:
+        type: array
+        items:
+          type: object
+    MultivaluedMapStringString:
+      type: object
+      additionalProperties:
+        type: array
+        items:
+          type: string
+    NewCookie:
+      type: object
+      properties:
+        name:
+          type: string
+        value:
+          type: string
+        version:
+          format: int32
+          type: integer
+        path:
+          type: string
+        domain:
+          type: string
+        comment:
+          type: string
+        maxAge:
+          format: int32
+          type: integer
+        expiry:
+          format: date
+          type: string
+        secure:
+          type: boolean
+        httpOnly:
+          type: boolean
+    Response:
+      type: object
+      properties:
+        status:
+          format: int32
+          type: integer
+        statusInfo:
+          $ref: '#/components/schemas/StatusType'
+        entity:
+          type: object
+        mediaType:
+          $ref: '#/components/schemas/MediaType'
+        language:
+          $ref: '#/components/schemas/Locale'
+        length:
+          format: int32
+          type: integer
+        allowedMethods:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+        cookies:
+          type: object
+          additionalProperties:
+            $ref: '#/components/schemas/NewCookie'
+        entityTag:
+          $ref: '#/components/schemas/EntityTag'
+        date:
+          format: date
+          type: string
+        lastModified:
+          format: date
+          type: string
+        location:
+          format: uri
+          type: string
+        links:
+          uniqueItems: true
+          type: array
+          items:
+            $ref: '#/components/schemas/Link'
+        metadata:
+          $ref: '#/components/schemas/MultivaluedMapStringObject'
+        headers:
+          $ref: '#/components/schemas/MultivaluedMapStringObject'
+        stringHeaders:
+          $ref: '#/components/schemas/MultivaluedMapStringString'
+    SpecVersion:
+      enum:
+        - V03
+        - V1
+      type: string
+    StatusType:
+      type: object
+      properties:
+        statusCode:
+          format: int32
+          type: integer
+        family:
+          $ref: '#/components/schemas/Family'
+        reasonPhrase:
+          type: string
+    UriBuilder:
+      type: object
diff --git a/integration-tests/include/src/main/resources/application.properties b/integration-tests/include/src/main/resources/application.properties
new file mode 100644
index 00000000..0d10e852
--- /dev/null
+++ b/integration-tests/include/src/main/resources/application.properties
@@ -0,0 +1 @@
+quarkus.openapi-generator.codegen.include=include-openapi.yaml
diff --git a/integration-tests/include/src/test/java/io/quarkiverse/openapi/generator/it/IncludeTest.java b/integration-tests/include/src/test/java/io/quarkiverse/openapi/generator/it/IncludeTest.java
new file mode 100644
index 00000000..6b2d2471
--- /dev/null
+++ b/integration-tests/include/src/test/java/io/quarkiverse/openapi/generator/it/IncludeTest.java
@@ -0,0 +1,21 @@
+package io.quarkiverse.openapi.generator.it;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+class IncludeTest {
+
+    @Test
+    void onlyIncludedClassesAreGenerated() throws ClassNotFoundException {
+        assertThat(Class.forName("org.openapi.quarkus.include_openapi_yaml.api.SimpleOpenApiResourceApi"))
+                .isNotNull();
+
+        assertThatCode(() -> Class.forName("org.openapi.quarkus.exclude_openapi_yaml.api.IgnoredOpenApiResourceApi"))
+                .isInstanceOf(ClassNotFoundException.class);
+    }
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 043fc1a4..9d633894 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -19,7 +19,9 @@
     circuit-breaker
     register-provider
     security
-    ignore
+    include
+    exclude
+    change-directory