Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OASFilter provided by extension not working #14098

Closed
FranckDemeyer opened this issue Jan 4, 2021 · 13 comments · Fixed by #14171
Closed

OASFilter provided by extension not working #14098

FranckDemeyer opened this issue Jan 4, 2021 · 13 comments · Fixed by #14171

Comments

@FranckDemeyer
Copy link

I recently create an extension which provide openapi specification, but my base application doesn't extract it, it's the same with health openapi extension.

class HubBasicsProcessor {

    private static final String FEATURE = "hub-basics";

    static class OpenAPIIncluded implements BooleanSupplier {
        HubBasicsConfig config;
        @Override public boolean getAsBoolean() {
            return config.openapiIncluded;
        }
    }

    @BuildStep
    FeatureBuildItem feature() {
        return new FeatureBuildItem(FEATURE);
    }
...
    @BuildStep(onlyIf = OpenAPIIncluded.class)
    void includeOpenAPIEndpoint(BuildProducer<AddToOpenAPIDefinitionBuildItem> openAPIProducer,
                                Capabilities capabilities,
                                HubBasicConfigurationBuildItem config) {
        if(capabilities.isPresent(Capability.SMALLRYE_OPENAPI)) {
            OASFilter filter = new HubBasicsOpenAPIFilter(
                config.getMonitorBasPath() + "/ping",
                config.getSettingsBasePath() + "/logger");
            openAPIProducer.produce(new AddToOpenAPIDefinitionBuildItem(filter));
        }
    }
}
@ghost ghost added the triage/needs-triage label Jan 4, 2021
@FranckDemeyer
Copy link
Author

After testing other options, it seems to depend on the mp.openapi.scan.disable option.
In previous versions, when mp.openapi.scan.disable was set to true, the openapi documentation provided by extensions was included, which is no longer the case.

to reproduce:

  • create a new quarkus project with openapi and smallrye health extensions
  • create a new OASFilter with basic informations
  • set mp.openapi.scan.disable to true (application.properties)
  • set mp.openapi.filter to the fully qualified name of the OASFilter (application.properties)
  • set quarkus.health.openapi.included to true
  • launch in quarkus:dev
  • open swagger-ui (or directly get openapi file)

Only basic documentation provided by application's OASFilter is displayed, smallrye-health documentation is not.

expected:

The documentation provided by application AND smallrye-health are displayed.

Thx

env:

  • Fedora 28
  • maven 3.6.3
  • java 11.0.8 (GraalVM)
  • GraalVM CE 20.2.0

@gsmet
Copy link
Member

gsmet commented Jan 5, 2021

/cc @phillip-kruger

@phillip-kruger
Copy link
Member

Hi @FranckDemeyer - what we version of Quarkus are you using ? If not latest, can you check with latest ?

@FranckDemeyer
Copy link
Author

Hi @phillip-kruger I initially start the project with version 1.9.2 and migrate to 1.10.5.

@phillip-kruger
Copy link
Member

OK thanks I'll look at this, there was an issue a while back that there can only be one filter, but that was fixed. I'll double check and get back to you.

@FranckDemeyer
Copy link
Author

Thanks

@phillip-kruger
Copy link
Member

Hi @FranckDemeyer - I am trying to re-create the issue using my example app, but it's working fine for me (if I understand the issue correctly). I have disabled scanning (although it's working with both scanning on or off) and I have 2 extensions (logging-ui and health) that provide endpoints for the openapi schema and I have my own filter (MyOwnObject), and all three is being included. see this branch in my example: https://github.com/phillip-kruger/openapi-example/tree/multiple-filters

Screenshot_20210107_130758

@FranckDemeyer
Copy link
Author

FranckDemeyer commented Jan 7, 2021

Hi @phillip-kruger, maybe I done something wrong, but at this point I can't see where I made a mistake, my code look (at my eyes) similar to yours.
I can't let you access the repository, instead I'll send you code snippets.

hub-basics is a extension I create myself (such as logging-ui in your example)

first, here is my pom.xml :

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.docaposte.newton</groupId>
  <artifactId>rights</artifactId>
  <version>1.0.0</version>
  <properties>
    <commons-collections4.version>4.1</commons-collections4.version>
    <compiler-plugin.version>3.8.1</compiler-plugin.version>
    <jacoco.version>0.8.5</jacoco.version>
    <maven.compiler.parameters>true</maven.compiler.parameters>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <posc-logger.version>1.0.0-20201106</posc-logger.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <quarkus-plugin.version>1.10.5.Final</quarkus-plugin.version>
    <quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
    <quarkus.platform.version>1.10.5.Final</quarkus.platform.version>
    <surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
    <wiremock.version>2.27.2</wiremock.version>
    <hub-basics.version>1.0.0</hub-basics.version>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>${quarkus.platform.artifact-id}</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-jackson</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jsonb</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-rest-client</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-health</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-fault-tolerance</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-metrics</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-opentracing</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-container-image-docker</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-collections4</artifactId>
      <version>${commons-collections4.version}</version>
    </dependency>
    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
    </dependency>
    <dependency>
      <groupId>com.docapost.posc</groupId>
      <artifactId>posc-core-logger</artifactId>
      <version>${posc-logger.version}</version>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5-mockito</artifactId>
      <version>${quarkus-plugin.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.github.tomakehurst</groupId>
      <artifactId>wiremock-jre8</artifactId>
      <version>${wiremock.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.jacoco</groupId>
      <artifactId>org.jacoco.agent</artifactId>
      <version>${jacoco.version}</version>
      <classifier>runtime</classifier>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-openapi</artifactId>
    </dependency>
    <dependency>
      <groupId>com.docaposte.newton</groupId>
      <artifactId>hub-basics</artifactId>
      <version>${hub-basics.version}</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus-plugin.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>generate-code</goal>
              <goal>generate-code-tests</goal>
              <goal>build</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compiler-plugin.version}</version>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <executions>
          <execution>
            <id>integration-tests</id>
            <phase>integration-test</phase>
            <goals>
              <goal>test</goal>
            </goals>
            <configuration>
              <excludedGroups>!integration</excludedGroups>
              <groups>integration</groups>
              <systemPropertyVariables>
                <jacoco-agent.destfile>${project.build.directory}/jacoco-it.exec</jacoco-agent.destfile>
              </systemPropertyVariables>
            </configuration>
          </execution>
        </executions>
        <configuration>
          <excludedGroups>integration</excludedGroups>
          <systemPropertyVariables>
            <jacoco-agent.destfile>${project.build.directory}/jacoco-ut.exec</jacoco-agent.destfile>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
            <maven.home>${maven.home}</maven.home>
          </systemPropertyVariables>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>${jacoco.version}</version>
        <configuration>
          <excludes>
            <exclude>com/docaposte/newton/rights/openapi/**/*</exclude>
            <exclude>com/docaposte/newton/rights/health/**/*</exclude>
          </excludes>
        </configuration>
        <executions>
          <execution>
            <id>instrument-ut</id>
            <goals>
              <goal>instrument</goal>
            </goals>
          </execution>
          <execution>
            <id>restore-ut</id>
            <goals>
              <goal>restore-instrumented-classes</goal>
            </goals>
          </execution>
          <execution>
            <id>report-ut</id>
            <goals>
              <goal>report</goal>
            </goals>
            <configuration>
              <dataFile>${project.build.directory}/jacoco-ut.exec</dataFile>
              <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
            </configuration>
          </execution>
          <execution>
            <id>instrument-it</id>
            <phase>pre-integration-test</phase>
            <goals>
              <goal>instrument</goal>
            </goals>
          </execution>
          <execution>
            <id>restore-it</id>
            <phase>post-integration-test</phase>
            <goals>
              <goal>restore-instrumented-classes</goal>
            </goals>
          </execution>
          <execution>
            <id>report-it</id>
            <phase>post-integration-test</phase>
            <goals>
              <goal>report</goal>
            </goals>
            <configuration>
              <dataFile>${project.build.directory}/jacoco-it.exec</dataFile>
              <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
            </configuration>
          </execution>
          <execution>
            <id>merge-results</id>
            <phase>verify</phase>
            <goals>
              <goal>merge</goal>
            </goals>
            <configuration>
              <fileSets>
                <fileSet>
                  <directory>${project.build.directory}</directory>
                  <includes>
                    <include>*.exec</include>
                  </includes>
                </fileSet>
              </fileSets>
              <destFile>${project.build.directory}/jacoco.exec</destFile>
            </configuration>
          </execution>
          <execution>
            <id>post-merge-report</id>
            <phase>verify</phase>
            <goals>
              <goal>report</goal>
            </goals>
            <configuration>
              <dataFile>${project.build.directory}/jacoco.exec</dataFile>
              <outputDirectory>${project.reporting.outputDirectory}/jacoco</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${surefire-plugin.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
                <configuration>
                  <systemPropertyVariables>
                    <native.image.path>${project.build.directory}/${project.artifactId}-runner</native.image.path>
                    <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                    <maven.home>${maven.home}</maven.home>
                  </systemPropertyVariables>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      <properties>
        <quarkus.package.type>native</quarkus.package.type>
        <quarkus.package.output-name>${project.artifactId}</quarkus.package.output-name>
        <quarkus.native.additional-build-args>-H:ResourceConfigurationFiles=resources-config.json</quarkus.native.additional-build-args>
      </properties>
    </profile>
    <profile>
      <id>native-swagger</id>
      <activation>
        <property>
          <name>native-swagger</name>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${surefire-plugin.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
                <configuration>
                  <systemPropertyVariables>
                    <native.image.path>${project.build.directory}/${project.artifactId}-swagger-runner</native.image.path>
                    <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                    <maven.home>${maven.home}</maven.home>
                  </systemPropertyVariables>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      <properties>
        <quarkus.package.type>native</quarkus.package.type>
        <quarkus.package.output-name>${project.artifactId}-swagger</quarkus.package.output-name>
        <quarkus.swagger-ui.always-include>true</quarkus.swagger-ui.always-include>
        <quarkus.native.additional-build-args>-H:ResourceConfigurationFiles=resources-config.json</quarkus.native.additional-build-args>
      </properties>
    </profile>
  </profiles>
</project>

here a snippet of my application.properties:

mp.openapi.filter=com.docaposte.newton.rights.openapi.RightsOpenApiFilter
mp.openapi.scan.disable=true
quarkus.hub-basics.openapi.included=true
quarkus.health.openapi.included=true

and here a part of my OASFilter:

package com.docaposte.newton.rights.openapi;
...
@RegisterForReflection
public class RightsOpenApiFilter implements OASFilter {
...
  @Override
  public void filterOpenAPI(OpenAPI openAPI) {
    openAPI.setInfo(APPLICATION_INFO);
    if (Objects.isNull(openAPI.getComponents())) {
      openAPI.setComponents(new ComponentsImpl());
    }
    if (Objects.isNull(openAPI.getPaths())) {
      openAPI.setPaths(new PathsImpl());
    }
    openAPI.addTag(new TagImpl().name("Rights").description(getDescription("tags/rights.html")));
    openAPI.getComponents().addSchema("UUID", UUID_SCHEMA);
    openAPI.getComponents().addSchema("Href", HREF_SCHEMA);
    openAPI.getComponents().addSchema("RightsEnum", RIGHTS_ENUM_SCHEMA);

    // /rights
    openAPI.getPaths().addPathItem("/rights", createRightsPath());

  }
...
}

swagger-ui looks like :

Capture d’écran de 2021-01-07 14-14-48

when i set mp.openapi.scan.disable to false then swagger-ui looks like :

Capture d’écran de 2021-01-07 14-18-08

Which is the result I expect.

Thanks for your help.

@phillip-kruger
Copy link
Member

Ok I think I recreated the issue. If I remove all OpenAPI annotated code, that gets ignored anyway because of scan disable, I get this. I am investigating further.

@phillip-kruger
Copy link
Member

phillip-kruger commented Jan 7, 2021

@FranckDemeyer - as a workaround, can you try to add a file called openapi.yml in src/main/resources/META-INF and only include the version in that file:

---
openapi: 3.0.3

Let me know if that works, then at least you have a workaround until I provide a PR to fix this.

@FranckDemeyer
Copy link
Author

@phillip-kruger I still have a workaround, I use mp.openapi.scan.exclude.packages properties, specifying my app package 😁 , but I'll try and let you know

@FranckDemeyer
Copy link
Author

@phillip-kruger I confirm, it works with openapi.yml file.
Thx for the tips

@phillip-kruger
Copy link
Member

Thanks for letting me know @FranckDemeyer . I am working on a proper fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants