├── .all-contributorsrc ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── -issue-number---problem-description-.md │ ├── bug-report.yml │ └── feature-request.yml ├── dependabot.yml ├── project.yml └── workflows │ ├── build.yml │ ├── build_website.yml │ ├── codeql.yml │ ├── pr-backporting.yml │ ├── pre-release.yml │ ├── preview.yml │ ├── preview_teardown.yml │ ├── quarkus-snapshot.yaml │ ├── release-perform.yml │ ├── release-prepare.yml │ ├── snapshot_deploy.yml │ └── stale_issues.yml ├── .gitignore ├── .lgtm.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── client ├── deployment │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── io │ │ │ │ └── quarkiverse │ │ │ │ └── openapi │ │ │ │ └── generator │ │ │ │ └── deployment │ │ │ │ ├── AuthProviderBuildItem.java │ │ │ │ ├── CodegenConfig.java │ │ │ │ ├── CommonItemConfig.java │ │ │ │ ├── GeneratorProcessor.java │ │ │ │ ├── GlobalCodegenConfig.java │ │ │ │ ├── OpenApiGeneratorOptions.java │ │ │ │ ├── SpecItemConfig.java │ │ │ │ ├── circuitbreaker │ │ │ │ └── CircuitBreakerConfigurationParser.java │ │ │ │ ├── codegen │ │ │ │ ├── ClassCodegenConfigParser.java │ │ │ │ ├── OpenApiConfigValidator.java │ │ │ │ ├── OpenApiGeneratorCodeGen.java │ │ │ │ ├── OpenApiGeneratorCodeGenBase.java │ │ │ │ ├── OpenApiGeneratorOutputPaths.java │ │ │ │ ├── OpenApiGeneratorStreamCodeGen.java │ │ │ │ ├── OpenApiSpecInputProvider.java │ │ │ │ └── SpecInputModel.java │ │ │ │ ├── template │ │ │ │ ├── ExprEvaluator.java │ │ │ │ ├── OpenApiNamespaceResolver.java │ │ │ │ ├── QuteTemplatingEngineAdapter.java │ │ │ │ └── StrNamespaceResolver.java │ │ │ │ └── wrapper │ │ │ │ ├── OpenApiClassicClientGeneratorWrapper.java │ │ │ │ ├── OpenApiClientGeneratorWrapper.java │ │ │ │ ├── OpenApiReactiveClientGeneratorWrapper.java │ │ │ │ ├── QuarkusCodegenConfigurator.java │ │ │ │ └── QuarkusJavaClientCodegen.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── services │ │ │ │ ├── io.quarkus.deployment.CodeGenProvider │ │ │ │ ├── org.openapitools.codegen.CodegenConfig │ │ │ │ └── org.openapitools.codegen.api.TemplatingEngineAdapter │ │ │ ├── application.properties │ │ │ └── templates │ │ │ └── libraries │ │ │ └── microprofile │ │ │ ├── additionalEnumTypeAnnotations.qute │ │ │ ├── additionalEnumTypeUnexpectedMember.qute │ │ │ ├── additionalModelTypeAnnotations.qute │ │ │ ├── api.qute │ │ │ ├── auth │ │ │ ├── compositeAuthenticationProvider.qute │ │ │ └── headersFactory.qute │ │ │ ├── beanValidation.qute │ │ │ ├── beanValidationCore.qute │ │ │ ├── beanValidationHeaderParams.qute │ │ │ ├── beanValidationInlineCore.qute │ │ │ ├── bodyParams.qute │ │ │ ├── cookieParams.qute │ │ │ ├── enumClass.qute │ │ │ ├── enumOuterClass.qute │ │ │ ├── headerParams.qute │ │ │ ├── model.qute │ │ │ ├── multipartFormdataPojo.qute │ │ │ ├── operationJavaDoc.qute │ │ │ ├── pathParams.qute │ │ │ ├── pojo.qute │ │ │ ├── pojoAdditionalProperties.qute │ │ │ ├── pojoQueryParam.qute │ │ │ └── queryParams.qute │ │ └── test │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── deployment │ │ │ ├── CodegenConfigTest.java │ │ │ ├── MockConfigUtils.java │ │ │ ├── OpenApiConfigValidatorTest.java │ │ │ ├── assertions │ │ │ └── Assertions.java │ │ │ ├── authentication │ │ │ ├── OpenApiSpecProviderTest.java │ │ │ └── OperationTest.java │ │ │ ├── circuitbreaker │ │ │ └── CircuitBreakerConfigurationParserTest.java │ │ │ ├── template │ │ │ └── QuteTemplatingEngineAdapterTest.java │ │ │ └── wrapper │ │ │ ├── OpenApiClientGeneratorWrapperTest.java │ │ │ └── QuarkusJavaClientCodegenTest.java │ │ └── resources │ │ ├── circuitbreaker │ │ ├── application.properties │ │ ├── circuit_breaker_disabled_application.properties │ │ └── missing_circuit_breaker_enabled_application.properties │ │ ├── codegen │ │ └── application.properties │ │ ├── deprecated │ │ └── application.properties │ │ ├── openapi │ │ ├── datetime-regression.yml │ │ ├── deprecated.json │ │ ├── issue-1022.json │ │ ├── issue-28.yaml │ │ ├── issue-38.yaml │ │ ├── issue-852.json │ │ ├── issue-933-security.yaml │ │ ├── issue-flink.yaml │ │ ├── multipart-openapi.yml │ │ ├── open-api-normalizer.json │ │ ├── petstore-openapi-bearer.json │ │ ├── petstore-openapi-custom-register-provider.json │ │ ├── petstore-openapi-httpbasic.json │ │ ├── petstore-openapi.json │ │ ├── simple-openapi.json │ │ └── suffix-prefix-openapi.json │ │ └── templates │ │ └── hello.qute ├── integration-tests │ ├── additional-properties │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── no-additional-properties-as-attr.yaml │ │ │ │ └── with-additional-properties-as-attr.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── additionalproperties │ │ │ ├── QuarkusAdditionalPropertiesAsAttributeAsFalseTest.java │ │ │ └── QuarkusAdditionalPropertiesAsAttributeTrueTest.java │ ├── array-enum │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── array-enum.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── ArrayEnumTest.java │ ├── auth-provider │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── io │ │ │ │ │ └── quarkiverse │ │ │ │ │ └── openapi │ │ │ │ │ └── generator │ │ │ │ │ └── it │ │ │ │ │ └── auth │ │ │ │ │ ├── TokenServerResource.java │ │ │ │ │ └── provider │ │ │ │ │ └── CustomCredentialsProvider.java │ │ │ ├── openapi │ │ │ │ ├── token-external-service1.yaml │ │ │ │ ├── token-external-service2.yaml │ │ │ │ ├── token-external-service3.yaml │ │ │ │ └── token-external-service5.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── auth │ │ │ ├── KeycloakServiceMock.java │ │ │ ├── TokenExternalServicesMock.java │ │ │ └── TokenWithCustomCredentialProviderTest.java │ ├── bean-validation │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── bean-validation-false.yaml │ │ │ │ ├── bean-validation-true.yaml │ │ │ │ └── issue-976.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── BeanValidationTest.java │ ├── beanparam │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ ├── BeanParamOpenApiTest.java │ │ │ └── WiremockBeanParam.java │ ├── change-custom-template-directory │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── custom │ │ │ │ └── templates │ │ │ │ │ └── api.qute │ │ │ ├── openapi │ │ │ │ └── simple-openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── it │ │ │ └── ChangeCustomTemplateDirectoryTest.java │ ├── change-directory │ │ ├── openapi-definitions │ │ │ └── simple-openapi.yaml │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── it │ │ │ └── ChangeDirectoryTest.java │ ├── circuit-breaker │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── simple-openapi.json │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── circuit │ │ │ └── breaker │ │ │ ├── SimpleOpenApiTest.java │ │ │ └── assertions │ │ │ └── Assertions.java │ ├── config-key │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── io │ │ │ │ │ └── quarkiverse │ │ │ │ │ └── openapi │ │ │ │ │ └── generator │ │ │ │ │ └── configkey │ │ │ │ │ ├── AnotherCustomAnnotation.java │ │ │ │ │ └── CustomAnnotation.java │ │ │ ├── openapi │ │ │ │ ├── config-key-openapi.yaml │ │ │ │ ├── config-key-with-dash.yaml │ │ │ │ └── empty-config-key.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── configkey │ │ │ ├── QuarkusConfigKeyOpenApiTest.java │ │ │ └── QuarkusConfigKeyWithDashOpenApiTest.java │ ├── cookie-authentication │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── cookie-authentication.json │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ ├── CookieAuthenticationTest.java │ │ │ └── WiremockCookieAuthentication.java │ ├── custom-templates │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── quarkus-simple-openapi.yaml │ │ │ └── resources │ │ │ │ ├── application.properties │ │ │ │ └── templates │ │ │ │ ├── api.qute │ │ │ │ └── pojoQueryParam.qute │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── QuarkusSimpleOpenApiTest.java │ ├── enum-property │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── enum-property.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── EnumPropertyTest.java │ ├── enum-unexpected │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── with-enum-unexpected.yaml │ │ │ │ └── without-enum-unexpected.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── EnumUnexpectedTest.java │ ├── equals-hashcode │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── quarkus-equals-hashcode-openapi.yaml │ │ │ │ └── quarkus-non-equals-hashcode-openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ ├── EqualsHashcodeTest.java │ │ │ └── VerifyGenerationTest.java │ ├── exclude │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── exclude-openapi.yaml │ │ │ │ └── openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── ExcludeTest.java │ ├── generate-flags │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── generate_apis_false.yaml │ │ │ │ └── generate_models_false.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── GenerateFlagsTest.java │ ├── generation-input │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── io │ │ │ │ └── quarkiverse │ │ │ │ └── openapi │ │ │ │ └── generator │ │ │ │ └── codegen │ │ │ │ └── ClassPathPetstoreOpenApiSpecInputProvider.java │ │ │ └── resources │ │ │ ├── META-INF │ │ │ └── services │ │ │ │ └── io.quarkiverse.openapi.generator.deployment.codegen.OpenApiSpecInputProvider │ │ │ ├── application.properties │ │ │ └── specs │ │ │ ├── README.md │ │ │ ├── petstore.json │ │ │ └── subtraction.yaml │ ├── generation-tests │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ ├── PetStoreTest.java │ │ │ └── WiremockPetStore.java │ ├── github │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ ├── openapi │ │ │ └── ghes-3.10.json │ │ │ └── resources │ │ │ └── application.properties │ ├── include │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── ignore-openapi.yaml │ │ │ │ └── include-openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── IncludeTest.java │ ├── initialize-empty-collections │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── quarkus-simple-openapi-empty-collections.yaml │ │ │ │ └── quarkus-simple-openapi-null-collections.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── initialiseEmptyCollections │ │ │ ├── QuarkusInitialiseEmptyCollectionWhenFalseTest.java │ │ │ └── QuarkusInitialiseEmptyCollectionWhenTrueTest.java │ ├── multipart-request │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── multipart-requests.yml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── multipart │ │ │ └── request │ │ │ ├── MultipartRestEasyClassicTest.java │ │ │ ├── MultipartRestEasyReactiveTest.java │ │ │ └── WiremockMultipart.java │ ├── mutiny-return-response │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── mutiny-multi-return-response-false-string-simple-openapi.yaml │ │ │ │ ├── mutiny-multi-return-response-false-void-simple-openapi.yaml │ │ │ │ ├── mutiny-multi-return-response-true-string-simple-openapi.yaml │ │ │ │ ├── mutiny-multi-return-response-true-void-simple-openapi.yaml │ │ │ │ ├── mutiny-return-response-false-string-simple-openapi.yaml │ │ │ │ ├── mutiny-return-response-false-void-simple-openapi.yaml │ │ │ │ ├── mutiny-return-response-true-string-simple-openapi.yaml │ │ │ │ └── mutiny-return-response-true-void-simple-openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── MutinyReturnResponseTest.java │ ├── mutiny │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── quarkus-multiple-endpoints-openapi.yaml │ │ │ │ ├── quarkus-multiple-endpoints-wrong-configuration-openapi.yaml │ │ │ │ └── quarkus-simple-openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── MutinyTest.java │ ├── open-api-normalizer │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── open-api-normalizer.json │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ ├── java │ │ │ └── io │ │ │ │ └── quarkiverse │ │ │ │ └── openapi │ │ │ │ └── generator │ │ │ │ └── it │ │ │ │ ├── QuarkusOpenApiNormalizerTest.java │ │ │ │ └── WiremockTestResource.java │ │ │ └── resources │ │ │ └── primate.json │ ├── override-credential-provider │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── io │ │ │ │ │ └── quarkiverse │ │ │ │ │ └── openapi │ │ │ │ │ └── generator │ │ │ │ │ └── it │ │ │ │ │ └── creds │ │ │ │ │ └── CustomCredentialsProvider.java │ │ │ ├── openapi │ │ │ │ └── simple-server.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── creds │ │ │ ├── CustomCredentialsProviderTest.java │ │ │ └── SimpleServerMockResource.java │ ├── part-filename │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── do-not-generate-part-filename.yml │ │ │ │ ├── do-not-use-field-name-in-part-filename.yml │ │ │ │ ├── generate-part-filename.yml │ │ │ │ ├── global-generate-part-filename.yml │ │ │ │ └── part-filename-value.yml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ ├── BasePartFilenameTest.java │ │ │ ├── PartFilenameRestEasyClassicTest.java │ │ │ └── PartFilenameRestEasyReactiveTest.java │ ├── path │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── openapi-path-with-forward-slash.yaml │ │ │ │ └── openapi-path.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── PathTest.java │ ├── polymorphism │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── polymorphism.json │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── PolymorphismTest.java │ ├── pom.xml │ ├── remove-operationid-prefix │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── openapi-prefix-count.yaml │ │ │ │ ├── openapi-prefix-delimiter.yaml │ │ │ │ └── openapi-remove-operation-id-prefix.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── RemoveOperationIdPrefixTest.java │ ├── return-response │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── return-response-false-string-simple-openapi.yaml │ │ │ │ ├── return-response-false-void-simple-openapi.yaml │ │ │ │ ├── return-response-true-string-simple-openapi.yaml │ │ │ │ └── return-response-true-void-simple-openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── ReturnResponseTest.java │ ├── security │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── io │ │ │ │ │ └── quarkiverse │ │ │ │ │ └── openapi │ │ │ │ │ └── generator │ │ │ │ │ └── it │ │ │ │ │ └── security │ │ │ │ │ ├── TokenPropagationResource.java │ │ │ │ │ └── auth │ │ │ │ │ └── DummyApiKeyAuthenticationProvider.java │ │ │ ├── openapi │ │ │ │ ├── fooopenapi.json │ │ │ │ ├── open weather custom security.yaml │ │ │ │ ├── open weather no security.yaml │ │ │ │ ├── open weather.yaml │ │ │ │ ├── token-propagation-external-service1.yaml │ │ │ │ ├── token-propagation-external-service2.yaml │ │ │ │ ├── token-propagation-external-service3.yaml │ │ │ │ ├── token-propagation-external-service4.yaml │ │ │ │ └── token-propagation-external-service5.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── security │ │ │ ├── AuthorizationHeaderApiKeyCanFilterWithoutDuplicateAuthorizationTest.java │ │ │ ├── KeycloakServiceMock.java │ │ │ ├── OpenWeatherCustomSecurityTest.java │ │ │ ├── OpenWeatherDefaultSecurityTest.java │ │ │ ├── OpenWeatherTest.java │ │ │ ├── TokenPropagationExternalServicesMock.java │ │ │ ├── TokenPropagationTest.java │ │ │ ├── WiremockFoo.java │ │ │ └── WiremockOpenWeather.java │ ├── serializable-model │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ ├── quarkus-non-serializable-openapi.yaml │ │ │ │ └── quarkus-serializable-openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── SerializableModelTest.java │ ├── simple │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── quarkus-simple-openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── QuarkusSimpleOpenApiTest.java │ ├── skip-validation │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── awx.json │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ ├── AWXTest.java │ │ │ └── WiremockAWX.java │ ├── suffix-prefix │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── openapi │ │ │ │ └── quarkus-suffix-prefix-openapi.yaml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── QuarkusSuffixPrefixOpenApiTest.java │ ├── type-mapping │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── io │ │ │ │ │ └── quarkiverse │ │ │ │ │ └── openapi │ │ │ │ │ └── generator │ │ │ │ │ └── it │ │ │ │ │ └── type │ │ │ │ │ └── mapping │ │ │ │ │ ├── OffsetDateTimeParamConverter.java │ │ │ │ │ └── OffsetDateTimeParamConverterProvider.java │ │ │ ├── openapi │ │ │ │ └── type-mappings-testing.yml │ │ │ └── resources │ │ │ │ └── application.properties │ │ │ └── test │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── it │ │ │ └── type │ │ │ └── mapping │ │ │ ├── TypeAndImportMappingRestEasyClassicTest.java │ │ │ ├── TypeAndImportMappingRestEasyReactiveTest.java │ │ │ └── WiremockTypeAndImportMapping.java │ └── without-oidc │ │ ├── pom.xml │ │ └── src │ │ ├── main │ │ ├── openapi │ │ │ └── quarkus-simple-openapi.yaml │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── openapi │ │ └── generator │ │ └── it │ │ └── QuarkusSimpleOpenApiTest.java ├── oidc │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── oidc │ │ │ ├── ClassicOidcClientRequestFilterDelegate.java │ │ │ ├── OidcAuthenticationRecorder.java │ │ │ ├── ReactiveOidcClientRequestFilterDelegate.java │ │ │ └── providers │ │ │ └── OAuth2AuthenticationProvider.java │ │ └── test │ │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── openapi │ │ └── generator │ │ └── oidc │ │ ├── OAuth2AuthenticationProviderTest.java │ │ └── ReactiveOAuth2AuthenticationProviderTest.java ├── pom.xml ├── runtime │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── codestarts │ │ │ └── quarkus │ │ │ │ └── openapi-generator-codestart │ │ │ │ ├── codestart.yml │ │ │ │ └── java │ │ │ │ ├── README.tpl.qute.md │ │ │ │ └── src │ │ │ │ └── main │ │ │ │ ├── openapi │ │ │ │ └── openapi.yml │ │ │ │ └── resources │ │ │ │ └── application.yml │ │ ├── java │ │ │ └── io │ │ │ │ └── quarkiverse │ │ │ │ └── openapi │ │ │ │ └── generator │ │ │ │ ├── AuthConfig.java │ │ │ │ ├── AuthName.java │ │ │ │ ├── AuthenticationRecorder.java │ │ │ │ ├── AuthsConfig.java │ │ │ │ ├── OidcClient.java │ │ │ │ ├── OpenApiGeneratorConfig.java │ │ │ │ ├── OpenApiGeneratorException.java │ │ │ │ ├── OpenApiSpec.java │ │ │ │ ├── SpecItemConfig.java │ │ │ │ ├── annotations │ │ │ │ ├── GeneratedClass.java │ │ │ │ ├── GeneratedMethod.java │ │ │ │ └── GeneratedParam.java │ │ │ │ ├── markers │ │ │ │ ├── ApiKeyAuthenticationMarker.java │ │ │ │ ├── BasicAuthenticationMarker.java │ │ │ │ ├── BearerAuthenticationMarker.java │ │ │ │ ├── OauthAuthenticationMarker.java │ │ │ │ └── OperationMarker.java │ │ │ │ └── providers │ │ │ │ ├── AbstractAuthProvider.java │ │ │ │ ├── AbstractAuthenticationPropagationHeadersFactory.java │ │ │ │ ├── ApiKeyAuthenticationProvider.java │ │ │ │ ├── ApiKeyIn.java │ │ │ │ ├── AuthProvider.java │ │ │ │ ├── AuthUtils.java │ │ │ │ ├── BaseCompositeAuthenticationProvider.java │ │ │ │ ├── BasicAuthenticationProvider.java │ │ │ │ ├── BearerAuthenticationProvider.java │ │ │ │ ├── ConfigCredentialsProvider.java │ │ │ │ ├── CredentialsContext.java │ │ │ │ ├── CredentialsProvider.java │ │ │ │ ├── DefaultHeadersProvider.java │ │ │ │ ├── HeadersProvider.java │ │ │ │ ├── OperationAuthInfo.java │ │ │ │ └── UrlPatternMatcher.java │ │ └── resources │ │ │ └── META-INF │ │ │ ├── beans.xml │ │ │ └── quarkus-extension.yaml │ │ └── test │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── providers │ │ │ ├── AbstractOpenApiSpecProviderTest.java │ │ │ ├── ApiKeyOpenApiSpecProviderTest.java │ │ │ ├── BasicOpenApiSpecProviderTest.java │ │ │ ├── BearerOpenApiSpecProviderTest.java │ │ │ └── UrlPatternMatcherTest.java │ │ └── resources │ │ └── application.properties └── test-utils │ ├── pom.xml │ └── src │ └── main │ └── java │ └── io │ └── quarkiverse │ └── openapi │ └── generator │ └── testutils │ ├── circuitbreaker │ └── assertions │ │ └── CircuitBreakerMethodAssert.java │ └── keycloak │ └── KeycloakRealmResourceManager.java ├── docs ├── antora.yml ├── modules │ └── ROOT │ │ ├── assets │ │ └── images │ │ │ ├── moqu-devui-card-framework.png │ │ │ ├── openapi.svg │ │ │ └── table-wiremock.png │ │ ├── nav.adoc │ │ └── pages │ │ ├── client.adoc │ │ ├── includes │ │ ├── additional-properties-as-attribute.adoc │ │ ├── additional-request-args.adoc │ │ ├── attributes.adoc │ │ ├── authentication-support.adoc │ │ ├── authorization-token-propagation.adoc │ │ ├── bean-validation.adoc │ │ ├── circuit-breaker.adoc │ │ ├── config-key.adoc │ │ ├── config.adoc │ │ ├── custom-auth-provider.adoc │ │ ├── dynamic-url.adoc │ │ ├── equals-hashcode.adoc │ │ ├── filter-openapi-spec-files.adoc │ │ ├── generate-apis.adoc │ │ ├── generate-models.adoc │ │ ├── getting-started.adoc │ │ ├── initialize-empty-collections.adoc │ │ ├── logging.adoc │ │ ├── quarkus-openapi-generator-moqu-wiremock.adoc │ │ ├── quarkus-openapi-generator-moqu-wiremock_quarkus.adoc │ │ ├── quarkus-openapi-generator-moqu-wiremock_quarkus.openapi-generator.adoc │ │ ├── quarkus-openapi-generator-server.adoc │ │ ├── quarkus-openapi-generator-server_quarkus.openapi.adoc │ │ ├── quarkus-openapi-generator-server_quarkus.quarkus.adoc │ │ ├── quarkus-openapi-generator.adoc │ │ ├── quarkus-openapi-generator_quarkus.adoc │ │ ├── quarkus-openapi-generator_quarkus.openapi-generator.adoc │ │ ├── resteasy-support.adoc │ │ ├── return-response-objects.adoc │ │ ├── sending-multipart-formdata.adoc │ │ ├── server-getting-started.adoc │ │ ├── supporting-unexpected-enums-values.adoc │ │ ├── template-customization.adoc │ │ └── want-to-contribute.adoc │ │ ├── index.adoc │ │ ├── moqu.adoc │ │ └── server.adoc ├── pom.xml └── templates │ └── includes │ └── attributes.adoc ├── moqu ├── core │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── moqu │ │ │ ├── Moqu.java │ │ │ ├── MoquImporter.java │ │ │ ├── MoquMapper.java │ │ │ ├── OpenAPIMoquImporter.java │ │ │ ├── ParameterType.java │ │ │ ├── SchemaReader.java │ │ │ ├── marshall │ │ │ └── ObjectMapperFactory.java │ │ │ ├── model │ │ │ ├── Header.java │ │ │ ├── Operation.java │ │ │ ├── Parameter.java │ │ │ ├── Request.java │ │ │ ├── RequestResponsePair.java │ │ │ └── Response.java │ │ │ └── wiremock │ │ │ ├── mapper │ │ │ └── WiremockMapper.java │ │ │ └── model │ │ │ ├── WiremockMapping.java │ │ │ ├── WiremockRequest.java │ │ │ └── WiremockResponse.java │ │ └── test │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── moqu │ │ │ ├── OpenAPIMoquImporterTest.java │ │ │ ├── TestUtils.java │ │ │ └── wiremock │ │ │ └── mapper │ │ │ ├── WiremockMapperTest.java │ │ │ └── WiremockPathParamTest.java │ │ └── resources │ │ └── wiremock │ │ ├── full.yml │ │ ├── mapper │ │ ├── should_map_one_wiremock_definition.yml │ │ └── should_map_two_wiremock_definition.yml │ │ ├── one_example_in_the_same_path.yml │ │ ├── path_param_one_path_param.yml │ │ ├── path_param_two_params_but_different_path.yml │ │ ├── path_param_two_path_params_combination.yml │ │ ├── path_param_two_path_params_only_one_with_example.yml │ │ ├── response_from_ref.yml │ │ ├── response_from_ref_and_noref.yml │ │ ├── response_from_ref_array.yml │ │ └── two_examples_in_the_same_path.yml ├── deployment │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── io │ │ │ │ └── quarkiverse │ │ │ │ └── openapi │ │ │ │ └── generator │ │ │ │ ├── MoquProjectProcessor.java │ │ │ │ ├── MoquWiremockProcessor.java │ │ │ │ ├── devui │ │ │ │ ├── MoquModel.java │ │ │ │ └── MoquWiremockDevUIProcessor.java │ │ │ │ └── items │ │ │ │ ├── MoquBuildItem.java │ │ │ │ └── MoquProjectBuildItem.java │ │ └── resources │ │ │ └── dev-ui │ │ │ └── qwc-moqu.js │ │ └── test │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── generator │ │ │ └── MoquProjectProcessorTest.java │ │ └── resources │ │ ├── api.yaml │ │ └── apiv2.json ├── pom.xml └── runtime │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── io │ │ └── quarkiverse │ │ └── openapi │ │ └── generator │ │ └── moqu │ │ ├── MoquConfig.java │ │ └── recorder │ │ └── MoquRoutesRecorder.java │ └── resources │ └── META-INF │ └── quarkus-extension.yaml ├── pom.xml ├── pull_request_template.md └── server ├── deployment ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── server │ │ │ └── generator │ │ │ └── deployment │ │ │ ├── CodegenConfig.java │ │ │ ├── ServerCodegenConfig.java │ │ │ └── codegen │ │ │ ├── ApicurioCodegenWrapper.java │ │ │ └── ApicurioOpenApiServerCodegen.java │ └── resources │ │ └── META-INF │ │ └── services │ │ └── io.quarkus.deployment.CodeGenProvider │ └── test │ ├── java │ └── io │ │ └── quarkiverse │ │ └── openapi │ │ └── server │ │ └── generator │ │ └── deployment │ │ ├── CodegenTest.java │ │ └── MockConfigUtils.java │ ├── resources │ ├── io │ │ └── quarkiverse │ │ │ └── openapi │ │ │ └── server │ │ │ └── generator │ │ │ └── deployment │ │ │ ├── doesNotExistDir.application.properties │ │ │ ├── inputDir.application.properties │ │ │ ├── json.application.properties │ │ │ └── yaml.application.properties │ └── openapi │ │ ├── petstore-openapi.json │ │ └── petstore-openapi.yaml │ └── resources2 │ └── petstore-openapi-2.json ├── integration-tests ├── codestarts │ ├── pom.xml │ └── src │ │ ├── main │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── openapi │ │ └── server │ │ └── generator │ │ └── it │ │ └── QuarkusOpenAPIGeneratorServerCodestartsTest.java ├── pom.xml ├── reactive │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── petstore │ │ │ │ └── PetStoreImpl.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── openapi │ │ │ └── petstore-openapi.json │ │ └── test │ │ └── java │ │ └── it │ │ └── PetStoreTest.java └── resteasy │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── petstore │ │ │ └── PetStoreImpl.java │ └── resources │ │ ├── application.properties │ │ └── openapi │ │ └── petstore-openapi.json │ └── test │ └── java │ └── io │ └── quarkiverse │ └── openapi │ └── server │ └── generator │ └── it │ └── PetStoreTest.java ├── pom.xml └── runtime ├── pom.xml └── src └── main ├── codestarts └── quarkus │ └── openapi-generator-server-codestart │ ├── codestart.yml │ └── java │ ├── README.tpl.qute.md │ └── src │ └── main │ └── resources │ ├── application.yml │ └── openapi │ └── openapi.yml └── resources └── META-INF ├── beans.xml └── quarkus-extension.yaml /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # More details are here: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners 5 | 6 | # The '*' pattern is global owners. 7 | 8 | # Order is important. The last matching pattern has the most precedence. 9 | # The folders are ordered as follows: 10 | 11 | # In each subsection folders are ordered first by depth, then alphabetically. 12 | # This should make it easy to add new rules without breaking existing ones. 13 | 14 | * @quarkiverse/quarkiverse-openapi-generator 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/-issue-number---problem-description-.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "[Issue number - problem description]" 3 | --- 4 | 5 | ## Extension 6 | - [ ] Server 7 | - [ ] Client 8 | 9 | ## Java Version 10 | 11 | 12 | ## Quarkus Version 13 | 14 | 15 | ## Description 16 | 17 | 18 | ## Steps to Reproduce (if applicable) 19 | 20 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maven updates for main branch 4 | - package-ecosystem: "maven" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | target-branch: "main" 9 | ignore: 10 | - dependency-name: "org.apache.maven.plugins:maven-compiler-plugin" 11 | 12 | # Maven updates for main-lts branch 13 | - package-ecosystem: "maven" 14 | directory: "/" 15 | schedule: 16 | interval: "daily" 17 | target-branch: "main-lts" 18 | ignore: 19 | - dependency-name: "org.apache.maven.plugins:maven-compiler-plugin" 20 | - dependency-name: "io.quarkus:quarkus-bom" 21 | - dependency-name: "io.quarkus.platform:quarkus-bom" 22 | 23 | # GitHub Actions updates for main branch 24 | - package-ecosystem: "github-actions" 25 | directory: "/" 26 | schedule: 27 | interval: "weekly" 28 | target-branch: "main" 29 | 30 | # GitHub Actions updates for main-lts branch 31 | - package-ecosystem: "github-actions" 32 | directory: "/" 33 | schedule: 34 | interval: "weekly" 35 | target-branch: "main-lts" 36 | -------------------------------------------------------------------------------- /.github/project.yml: -------------------------------------------------------------------------------- 1 | release: 2 | current-version: 2.10.0 3 | next-version: 3.0.0-SNAPSHOT 4 | -------------------------------------------------------------------------------- /.github/workflows/build_website.yml: -------------------------------------------------------------------------------- 1 | name: Build Website 2 | 3 | on: 4 | push: 5 | branches: 6 | - "main" 7 | - "main-lts" 8 | paths-ignore: 9 | - '.gitignore' 10 | - 'CODEOWNERS' 11 | - 'LICENSE' 12 | - '*.md' 13 | - '*.adoc' 14 | - '*.txt' 15 | - '.all-contributorsrc' 16 | pull_request: 17 | paths-ignore: 18 | - '.gitignore' 19 | - 'CODEOWNERS' 20 | - 'LICENSE' 21 | - '*.md' 22 | - '*.txt' 23 | - '.all-contributorsrc' 24 | jobs: 25 | build-website: 26 | name: Build Website 27 | runs-on: ubuntu-latest 28 | steps: 29 | - uses: actions/checkout@v4 30 | - name: Set up JDK 17 31 | uses: actions/setup-java@v4 32 | with: 33 | distribution: temurin 34 | java-version: 17 35 | cache: 'maven' 36 | 37 | - name: Build with Maven 38 | run: mvn '-Dorg.slf4j.simpleLogger.log.org.openapitools=off' -B formatter:validate impsort:check verify --file pom.xml -DskipTests 39 | 40 | - name: Store PR id 41 | if: github.event_name == 'pull_request' 42 | run: | 43 | echo ${{ github.event.number }} > ./docs/target/generated-docs/pr-id.txt 44 | 45 | - name: Publishing directory for PR preview 46 | if: github.event_name == 'pull_request' 47 | uses: actions/upload-artifact@v4 48 | with: 49 | name: site 50 | path: ./docs/target/generated-docs 51 | retention-days: 3 -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ "main", "main-lts" ] 6 | pull_request: 7 | branches: [ "main", "main-lts" ] 8 | schedule: 9 | - cron: "2 0 * * 6" 10 | 11 | jobs: 12 | analyze: 13 | name: Analyze 14 | runs-on: ubuntu-latest 15 | permissions: 16 | actions: read 17 | contents: read 18 | security-events: write 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | language: [ java ] 24 | 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v4 28 | 29 | - name: Setup Java 30 | uses: actions/setup-java@v4 31 | with: 32 | distribution: temurin 33 | java-version: 17 34 | 35 | - name: Initialize CodeQL 36 | uses: github/codeql-action/init@v3 37 | with: 38 | languages: ${{ matrix.language }} 39 | queries: +security-and-quality 40 | 41 | - name: Autobuild 42 | uses: github/codeql-action/autobuild@v3 43 | 44 | - name: Perform CodeQL Analysis 45 | uses: github/codeql-action/analyze@v3 46 | with: 47 | category: "/language:${{ matrix.language }}" 48 | -------------------------------------------------------------------------------- /.github/workflows/pr-backporting.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request Backporting 2 | 3 | on: 4 | pull_request_target: 5 | types: [closed, labeled] 6 | env: 7 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 8 | 9 | jobs: 10 | compute-targets: 11 | if: ${{ github.event.pull_request.state == 'closed' && github.event.pull_request.merged }} 12 | runs-on: ubuntu-latest 13 | outputs: 14 | target-branches: ${{ steps.set-targets.outputs.targets }} 15 | env: 16 | LABELS: ${{ toJSON(github.event.pull_request.labels) }} 17 | steps: 18 | - name: Set target branches 19 | id: set-targets 20 | uses: kiegroup/kie-ci/.ci/actions/parse-labels@main 21 | with: 22 | labels: ${LABELS} 23 | 24 | backporting: 25 | if: ${{ github.event.pull_request.state == 'closed' && github.event.pull_request.merged && needs.compute-targets.outputs.target-branches != '[]' }} 26 | name: "[${{ matrix.target-branch }}] - Backporting" 27 | runs-on: ubuntu-latest 28 | needs: compute-targets 29 | strategy: 30 | matrix: 31 | target-branch: ${{ fromJSON(needs.compute-targets.outputs.target-branches) }} 32 | fail-fast: false 33 | env: 34 | REVIEWERS: ${{ toJSON(github.event.pull_request.requested_reviewers) }} 35 | steps: 36 | - name: Backporting 37 | uses: kiegroup/kie-ci/.ci/actions/backporting@main 38 | with: 39 | target-branch: ${{ matrix.target-branch }} -------------------------------------------------------------------------------- /.github/workflows/pre-release.yml: -------------------------------------------------------------------------------- 1 | name: Quarkiverse Pre Release 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - '.github/project.yml' 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | pre-release: 14 | name: Pre-Release 15 | uses: quarkiverse/.github/.github/workflows/pre-release.yml@main 16 | secrets: inherit 17 | -------------------------------------------------------------------------------- /.github/workflows/preview_teardown.yml: -------------------------------------------------------------------------------- 1 | name: Surge.sh Preview Teardown 2 | 3 | on: 4 | pull_request_target: 5 | paths: 6 | - '*.adoc' 7 | types: [closed] 8 | 9 | jobs: 10 | preview-teardown: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Teardown surge preview 14 | id: deploy 15 | run: npx surge teardown https://quarkus-openapi-generator-preview-pr-${{ github.event.number }}.surge.sh --token ${{ secrets.SURGE_TOKEN }} 16 | - name: Update PR status comment 17 | uses: actions-cool/maintain-one-comment@v3.2.0 18 | with: 19 | token: ${{ secrets.GITHUB_TOKEN }} 20 | body: | 21 | 🙈 The PR is closed and the preview is expired. 22 | 23 | body-include: '' 24 | number: ${{ github.event.number }} -------------------------------------------------------------------------------- /.github/workflows/release-perform.yml: -------------------------------------------------------------------------------- 1 | name: Quarkiverse Perform Release 2 | run-name: Perform ${{github.event.inputs.tag || github.ref_name}} Release 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | workflow_dispatch: 8 | inputs: 9 | tag: 10 | description: 'Tag to release' 11 | required: true 12 | 13 | permissions: 14 | attestations: write 15 | id-token: write 16 | contents: read 17 | 18 | concurrency: 19 | group: ${{ github.workflow }}-${{ github.ref }} 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | perform-release: 24 | name: Perform Release 25 | uses: quarkiverse/.github/.github/workflows/perform-release.yml@main 26 | secrets: inherit 27 | with: 28 | version: ${{github.event.inputs.tag || github.ref_name}} 29 | -------------------------------------------------------------------------------- /.github/workflows/release-prepare.yml: -------------------------------------------------------------------------------- 1 | name: Quarkiverse Prepare Release 2 | 3 | on: 4 | pull_request: 5 | types: [ closed ] 6 | paths: 7 | - '.github/project.yml' 8 | 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | prepare-release: 15 | name: Prepare Release 16 | if: ${{ github.event.pull_request.merged == true}} 17 | uses: quarkiverse/.github/.github/workflows/prepare-release.yml@main 18 | secrets: inherit 19 | -------------------------------------------------------------------------------- /.github/workflows/snapshot_deploy.yml: -------------------------------------------------------------------------------- 1 | name: Snapshot Deploy 2 | 3 | concurrency: 4 | group: ${{ github.ref }}-${{ github.workflow }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | workflow_dispatch: 9 | push: 10 | branches: [ main ] 11 | 12 | defaults: 13 | run: 14 | shell: bash 15 | 16 | permissions: 17 | attestations: write 18 | id-token: write 19 | contents: read 20 | 21 | jobs: 22 | deploy-snapshot: 23 | name: Deploy Snapshots 24 | uses: quarkiverse/.github/.github/workflows/perform-release.yml@main 25 | secrets: inherit 26 | with: 27 | ref: main 28 | version: 3.0.0-SNAPSHOT 29 | -------------------------------------------------------------------------------- /.github/workflows/stale_issues.yml: -------------------------------------------------------------------------------- 1 | name: Close stale issues and PRs 2 | on: 3 | schedule: 4 | - cron: "0 12 * * *" 5 | 6 | permissions: 7 | issues: write 8 | pull-requests: write 9 | 10 | jobs: 11 | stale: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/stale@v9.1.0 15 | with: 16 | exempt-issue-labels: "pinned" 17 | stale-issue-message: "@ricardozanini @hbelmiro This is being labeled as Stale." 18 | stale-pr-message: "@ricardozanini @hbelmiro This is being labeled as Stale." 19 | close-issue-message: "@ricardozanini @hbelmiro This is being closed due to inactivity." 20 | close-pr-message: "@ricardozanini @hbelmiro This is being closed due to inactivity." -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | # Eclipse 26 | .project 27 | .classpath 28 | .settings/ 29 | bin/ 30 | 31 | # IntelliJ 32 | .idea 33 | *.ipr 34 | *.iml 35 | *.iws 36 | 37 | # NetBeans 38 | nb-configuration.xml 39 | 40 | # Visual Studio Code 41 | .vscode 42 | .factorypath 43 | 44 | # OSX 45 | .DS_Store 46 | 47 | # Vim 48 | *.swp 49 | *.swo 50 | 51 | # patch 52 | *.orig 53 | *.rej 54 | 55 | # Gradle 56 | .gradle/ 57 | build/ 58 | 59 | # Maven 60 | target/ 61 | pom.xml.tag 62 | pom.xml.releaseBackup 63 | pom.xml.versionsBackup 64 | release.properties -------------------------------------------------------------------------------- /.lgtm.yml: -------------------------------------------------------------------------------- 1 | # LGTM Settings (https://lgtm.com/) 2 | # For reference, see https://lgtm.com/help/lgtm/lgtm.yml-configuration-file 3 | # or template at https://lgtm.com/static/downloads/lgtm.template.yml 4 | 5 | extraction: 6 | java: 7 | index: 8 | maven: 9 | version: "3.8.4" 10 | # Specify the Java version required to build the project 11 | java_version: "17" -------------------------------------------------------------------------------- /client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/AuthProviderBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment; 2 | 3 | import io.quarkus.builder.item.MultiBuildItem; 4 | 5 | public final class AuthProviderBuildItem extends MultiBuildItem { 6 | 7 | final String openApiSpecId; 8 | final String name; 9 | 10 | AuthProviderBuildItem(String openApiSpecId, String name) { 11 | this.openApiSpecId = openApiSpecId; 12 | this.name = name; 13 | } 14 | 15 | public String getOpenApiSpecId() { 16 | return openApiSpecId; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/OpenApiGeneratorOptions.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment; 2 | 3 | import java.nio.file.Path; 4 | 5 | import org.eclipse.microprofile.config.Config; 6 | 7 | public record OpenApiGeneratorOptions( 8 | Config config, 9 | Path openApiFilePath, 10 | Path outDir, 11 | Path templateDir, 12 | boolean isRestEasyReactive) { 13 | } 14 | -------------------------------------------------------------------------------- /client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/codegen/OpenApiGeneratorCodeGen.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment.codegen; 2 | 3 | public class OpenApiGeneratorCodeGen extends OpenApiGeneratorCodeGenBase { 4 | @Override 5 | public String providerId() { 6 | return OpenApiGeneratorOutputPaths.OPENAPI_PATH; 7 | } 8 | 9 | @Override 10 | public String[] inputExtensions() { 11 | return new String[] { JSON, YAML, YML }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/codegen/OpenApiGeneratorOutputPaths.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment.codegen; 2 | 3 | import java.nio.file.Path; 4 | import java.util.ArrayList; 5 | import java.util.Arrays; 6 | import java.util.Collection; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | 10 | public class OpenApiGeneratorOutputPaths { 11 | 12 | public static final String OPENAPI_PATH = "open-api"; 13 | public static final String STREAM_PATH = "open-api-stream"; 14 | 15 | private static final Collection rootPaths = Arrays.asList(STREAM_PATH); 16 | 17 | public static Path getRelativePath(Path path) { 18 | List paths = new ArrayList<>(); 19 | Path currentPath = path; 20 | while (currentPath != null && currentPath.getFileName() != null) { 21 | if (rootPaths.contains(currentPath.getFileName().toString())) { 22 | Iterator iter = paths.iterator(); 23 | Path result = Path.of(iter.next()); 24 | while (iter.hasNext()) { 25 | result = result.resolve(iter.next()); 26 | } 27 | return result; 28 | } else { 29 | paths.add(0, currentPath.getFileName().toString()); 30 | currentPath = currentPath.getParent(); 31 | } 32 | } 33 | return path.getFileName(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/codegen/OpenApiSpecInputProvider.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment.codegen; 2 | 3 | import java.io.InputStream; 4 | import java.util.List; 5 | 6 | import io.quarkus.deployment.CodeGenContext; 7 | 8 | /** 9 | * Provider interface for clients to dynamically provide their own OpenAPI specification files. 10 | */ 11 | public interface OpenApiSpecInputProvider { 12 | 13 | /** 14 | * Fetch OpenAPI specification files from a given source. 15 | * 16 | * @return a list of spec files in {@link InputStream} format. 17 | */ 18 | List read(CodeGenContext context); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/template/ExprEvaluator.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment.template; 2 | 3 | import java.util.List; 4 | import java.util.concurrent.ExecutionException; 5 | 6 | import io.quarkus.qute.EvalContext; 7 | import io.quarkus.qute.Expression; 8 | 9 | final class ExprEvaluator { 10 | 11 | private ExprEvaluator() { 12 | } 13 | 14 | @SuppressWarnings("unchecked") 15 | public static T evaluate(EvalContext context, Expression expression) throws ExecutionException, InterruptedException { 16 | return (T) context.evaluate(expression).toCompletableFuture().get(); 17 | } 18 | 19 | @SuppressWarnings("unchecked") 20 | public static T[] evaluate(EvalContext context, List expressions, Class type) 21 | throws ExecutionException, InterruptedException { 22 | T[] results = (T[]) java.lang.reflect.Array.newInstance(type, expressions.size()); 23 | 24 | for (int i = 0; i < expressions.size(); i++) { 25 | Expression expression = expressions.get(i); 26 | T result = type.cast(context.evaluate(expression).toCompletableFuture().get()); 27 | results[i] = result; 28 | } 29 | 30 | return results; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClassicClientGeneratorWrapper.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment.wrapper; 2 | 3 | import java.nio.file.Path; 4 | 5 | public class OpenApiClassicClientGeneratorWrapper extends OpenApiClientGeneratorWrapper { 6 | 7 | public OpenApiClassicClientGeneratorWrapper(Path specFilePath, Path outputDir, boolean verbose, boolean validateSpec) { 8 | super(createConfigurator(), specFilePath, outputDir, verbose, validateSpec); 9 | } 10 | 11 | private static QuarkusCodegenConfigurator createConfigurator() { 12 | QuarkusCodegenConfigurator configurator = new QuarkusCodegenConfigurator(); 13 | configurator.addAdditionalProperty("is-resteasy-reactive", false); 14 | return configurator; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiReactiveClientGeneratorWrapper.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment.wrapper; 2 | 3 | import java.nio.file.Path; 4 | 5 | public class OpenApiReactiveClientGeneratorWrapper extends OpenApiClientGeneratorWrapper { 6 | 7 | public OpenApiReactiveClientGeneratorWrapper(Path specFilePath, Path outputDir, boolean verbose, boolean validateSpec) { 8 | super(createConfigurator(), specFilePath, outputDir, verbose, validateSpec); 9 | } 10 | 11 | private static QuarkusCodegenConfigurator createConfigurator() { 12 | QuarkusCodegenConfigurator configurator = new QuarkusCodegenConfigurator(); 13 | configurator.addAdditionalProperty("is-resteasy-reactive", true); 14 | return configurator; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/wrapper/QuarkusCodegenConfigurator.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment.wrapper; 2 | 3 | import org.openapitools.codegen.config.CodegenConfigurator; 4 | import org.openapitools.codegen.languages.JavaClientCodegen; 5 | 6 | public class QuarkusCodegenConfigurator extends CodegenConfigurator { 7 | 8 | public QuarkusCodegenConfigurator() { 9 | // immutable properties 10 | this.setGeneratorName("quarkus"); 11 | this.setTemplatingEngineName("qute"); 12 | this.setLibrary(JavaClientCodegen.MICROPROFILE); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /client/deployment/src/main/resources/META-INF/services/io.quarkus.deployment.CodeGenProvider: -------------------------------------------------------------------------------- 1 | io.quarkiverse.openapi.generator.deployment.codegen.OpenApiGeneratorCodeGen 2 | io.quarkiverse.openapi.generator.deployment.codegen.OpenApiGeneratorStreamCodeGen -------------------------------------------------------------------------------- /client/deployment/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig: -------------------------------------------------------------------------------- 1 | io.quarkiverse.openapi.generator.deployment.wrapper.QuarkusJavaClientCodegen 2 | -------------------------------------------------------------------------------- /client/deployment/src/main/resources/META-INF/services/org.openapitools.codegen.api.TemplatingEngineAdapter: -------------------------------------------------------------------------------- 1 | io.quarkiverse.openapi.generator.deployment.template.QuteTemplatingEngineAdapter 2 | -------------------------------------------------------------------------------- /client/deployment/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.log.category."org.openapitools".level=OFF 2 | -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/additionalEnumTypeAnnotations.qute: -------------------------------------------------------------------------------- 1 | {#for annon in e.additionalEnumTypeAnnotations.orEmpty}{annon}{/for} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/additionalEnumTypeUnexpectedMember.qute: -------------------------------------------------------------------------------- 1 | /** 2 | * Special value if the API response contains some new value not declared in this enum. 3 | * You should react accordingly. 4 | */ 5 | {additionalEnumTypeUnexpectedMemberName}({#if e.isContainer.or(false)}{e.items.dataType}{#else}{e.dataType}{/if}.valueOf("{additionalEnumTypeUnexpectedMemberStringValue}")){#if e.allowableValues},{/if} 6 | -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/additionalModelTypeAnnotations.qute: -------------------------------------------------------------------------------- 1 | {#for annon in additionalModelTypeAnnotations.orEmpty} 2 | {annon} 3 | {/for} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/auth/headersFactory.qute: -------------------------------------------------------------------------------- 1 | package {apiPackage}.auth; 2 | 3 | public class AuthenticationPropagationHeadersFactory extends io.quarkiverse.openapi.generator.providers.AbstractAuthenticationPropagationHeadersFactory { 4 | 5 | @jakarta.inject.Inject 6 | public AuthenticationPropagationHeadersFactory(@io.quarkiverse.openapi.generator.OpenApiSpec(openApiSpecId="{quarkus-generator.openApiSpecId}") io.quarkiverse.openapi.generator.providers.BaseCompositeAuthenticationProvider compositeProvider, io.quarkiverse.openapi.generator.OpenApiGeneratorConfig generatorConfig, io.quarkiverse.openapi.generator.providers.HeadersProvider headersProvider) { 7 | super(compositeProvider, generatorConfig, headersProvider); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/beanValidation.qute: -------------------------------------------------------------------------------- 1 | {#if use-bean-validation} 2 | {#include beanValidationCore.qute p=p/} 3 | {/if} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/beanValidationCore.qute: -------------------------------------------------------------------------------- 1 | {#if p.required} 2 | @jakarta.validation.constraints.NotNull 3 | {/if} 4 | {#if p.pattern} 5 | @jakarta.validation.constraints.Pattern(regexp = "{p.pattern}") 6 | {/if} 7 | {#if p.minLength || p.minItems} 8 | @jakarta.validation.constraints.Size(min = {p.minLength}{p.minItems}) 9 | {/if} 10 | {#if p.maxLength || p.maxItems} 11 | @jakarta.validation.constraints.Size(max = {p.maxLength}{p.maxItems}) 12 | {/if} 13 | {#if p.isInteger} 14 | {#if p.minimum} 15 | @jakarta.validation.constraints.Min({p.minimum}) 16 | {/if} 17 | {#if p.maximum} 18 | @jakarta.validation.constraints.Max({p.maximum}) 19 | {/if} 20 | {/if} 21 | {#if p.isLong} 22 | {#if p.minimum} 23 | @jakarta.validation.constraints.Min({p.minimum}L) 24 | {/if} 25 | {#if p.maximum} 26 | @jakarta.validation.constraints.Max({p.maximum}L) 27 | {/if} 28 | {/if} 29 | {#if !p.isInteger && !p.isLong} 30 | {#if p.minimum} 31 | @jakarta.validation.constraints.DecimalMin("{p.minimum}") 32 | {/if} 33 | {#if p.maximum} 34 | @jakarta.validation.constraints.DecimalMax("{p.maximum}") 35 | {/if} 36 | {/if} 37 | {#if use-bean-validation} 38 | @jakarta.validation.Valid 39 | {/if} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/beanValidationHeaderParams.qute: -------------------------------------------------------------------------------- 1 | {#include beanValidationCore.qute p=param/} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/beanValidationInlineCore.qute: -------------------------------------------------------------------------------- 1 | {#if p.required}@jakarta.validation.constraints.NotNull {/if}{#if p.pattern}@jakarta.validation.constraints.Pattern(regexp = "{p.pattern}") {/if}{#if p.minLength || p.minItems}@jakarta.validation.constraints.Size(min = {p.minLength}{p.minItems}) {/if}{#if p.maxLength || p.maxItems}@jakarta.validation.constraints.Size(max = {p.maxLength}{p.maxItems}) {/if}{#if p.isInteger}{#if p.minimum}@jakarta.validation.constraints.Min({p.minimum}) {/if}{#if p.maximum}@jakarta.validation.constraints.Max({p.maximum}) {/if}{/if}{#if p.isLong}{#if p.minimum}@jakarta.validation.constraints.Min({p.minimum}L) {/if}{#if p.maximum}@jakarta.validation.constraints.Max({p.maximum}L) {/if}{/if}{#if !p.isInteger && !p.isLong}{#if p.minimum}@jakarta.validation.constraints.DecimalMin("{p.minimum}") {/if}{#if p.maximum}@jakarta.validation.constraints.DecimalMax("{p.maximum}") {/if}{/if}{#if use-bean-validation}@jakarta.validation.Valid {/if} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/bodyParams.qute: -------------------------------------------------------------------------------- 1 | {#if param.isBodyParam}{param.dataType} {param.paramName}{/if} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/cookieParams.qute: -------------------------------------------------------------------------------- 1 | {#if param.isCookieParam}@io.quarkiverse.openapi.generator.annotations.GeneratedParam("{param.baseName}") @jakarta.ws.rs.CookieParam("{param.baseName}") {#if param.defaultValue}@jakarta.ws.rs.DefaultValue("\{{param.defaultValue}\}") {/if}{param.dataType} {param.paramName}{/if} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/headerParams.qute: -------------------------------------------------------------------------------- 1 | {#if param.isHeaderParam}@io.quarkiverse.openapi.generator.annotations.GeneratedParam("{param.baseName}") @jakarta.ws.rs.HeaderParam("{param.baseName}"){param.dataType} {param.paramName}{/if} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/model.qute: -------------------------------------------------------------------------------- 1 | package {package}; 2 | 3 | {#if use-bean-validation} 4 | {! https://github.com/OpenAPITools/openapi-generator/issues/18974 !} 5 | import jakarta.validation.constraints.*; 6 | import jakarta.validation.Valid; 7 | {/if} 8 | 9 | {#for imp in imports} 10 | import {imp.import}; 11 | {/for} 12 | {#if serializableModel} 13 | 14 | import java.io.Serializable; 15 | import java.util.Set; 16 | {/if} 17 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 18 | 19 | {#for m in models} 20 | {#if m.model.isEnum}{#include enumOuterClass.qute e=m.model/} 21 | {#else}{#include pojo.qute m=m.model codegen=classes-codegen package=modelPackage/}{/if} 22 | {/for} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/operationJavaDoc.qute: -------------------------------------------------------------------------------- 1 | {#if op.summary} 2 | * {op.summary} 3 | * 4 | {/if} 5 | {#if op.notes} 6 | * {op.notes} 7 | * 8 | {/if} 9 | {#for p in op.pathParams} 10 | * @param {p.paramName} {p.description} 11 | {/for} 12 | {#for p in op.queryParams} 13 | * @param {p.paramName} {p.description} 14 | {/for} 15 | {#for p in op.bodyParams} 16 | * @param {p.paramName} {p.description} 17 | {/for} 18 | {#for p in op.headerParams} 19 | * @param {p.paramName} {p.description} 20 | {/for} 21 | -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/pathParams.qute: -------------------------------------------------------------------------------- 1 | {#if param.isPathParam}@io.quarkiverse.openapi.generator.annotations.GeneratedParam("{param.baseName}") @jakarta.ws.rs.PathParam("{param.baseName}"){param.dataType} {param.paramName}{/if} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/pojoAdditionalProperties.qute: -------------------------------------------------------------------------------- 1 | {#if m.isAdditionalPropertiesTrue && additionalPropertiesAsAttribute} 2 | /** 3 | * A property that represents the additionalProperties keyword in the OAS document. 4 | */ 5 | private java.util.Map additionalProperties; 6 | 7 | /** 8 | * Sets the an additional property with the specified key and value. 9 | */ 10 | @com.fasterxml.jackson.annotation.JsonAnySetter 11 | public {m.classname} setAdditionalProperty(String key, {m.additionalPropertiesType} value) { 12 | if (this.additionalProperties == null) { 13 | this.additionalProperties = new java.util.HashMap(); 14 | } 15 | this.additionalProperties.put(key, value); 16 | return this; 17 | } 18 | 19 | /** 20 | * Gets the additionalProperties map. 21 | */ 22 | @com.fasterxml.jackson.annotation.JsonAnyGetter 23 | public java.util.Map getAdditionalProperties() { 24 | return this.additionalProperties; 25 | } 26 | 27 | /** 28 | * Gets the an additional property with the specified key. 29 | */ 30 | public {m.additionalPropertiesType} getAdditionalProperty(String key) { 31 | if (this.additionalProperties == null) { 32 | return null; 33 | } 34 | return this.additionalProperties.get(key); 35 | } 36 | {/if} -------------------------------------------------------------------------------- /client/deployment/src/main/resources/templates/libraries/microprofile/queryParams.qute: -------------------------------------------------------------------------------- 1 | {#if param.isQueryParam}@io.quarkiverse.openapi.generator.annotations.GeneratedParam("{param.baseName}") {#if param.isModel}@jakarta.ws.rs.BeanParam{#else}@jakarta.ws.rs.QueryParam("{param.baseName}"){/if} {#if param.isContainer}{#if param.defaultValue}@jakarta.ws.rs.DefaultValue("\{{param.defaultValue}\}"){/if}{/if}{#if param.isModel}{param.dataType}.{param.dataType}QueryParam{#else}{param.dataType}{/if} {param.paramName}{/if} -------------------------------------------------------------------------------- /client/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/CodegenConfigTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment; 2 | 3 | import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.BUILD_TIME_SPEC_PREFIX_FORMAT; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | 6 | import java.nio.file.Path; 7 | 8 | import org.junit.jupiter.api.Test; 9 | 10 | class CodegenConfigTest { 11 | 12 | @Test 13 | void verifyStreamUri() { 14 | final String resolvedPrefix = CodegenConfig 15 | .getBuildTimeSpecPropertyPrefix(Path.of("/home/myuser/open-api-stream/luke/my test openapi.json")); 16 | assertEquals(String.format(BUILD_TIME_SPEC_PREFIX_FORMAT, "luke_my_test_openapi_json"), resolvedPrefix); 17 | } 18 | 19 | @Test 20 | void verifySpaceEncoding() { 21 | final String resolvedPrefix = CodegenConfig 22 | .getBuildTimeSpecPropertyPrefix(Path.of("/home/myuser/luke/my test openapi.json")); 23 | assertEquals(String.format(BUILD_TIME_SPEC_PREFIX_FORMAT, "my_test_openapi_json"), resolvedPrefix); 24 | } 25 | 26 | @Test 27 | void withSingleFileName() { 28 | final String resolvedPrefix = CodegenConfig.getBuildTimeSpecPropertyPrefix(Path.of("my test openapi.json")); 29 | assertEquals(String.format(BUILD_TIME_SPEC_PREFIX_FORMAT, "my_test_openapi_json"), resolvedPrefix); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /client/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/MockConfigUtils.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment; 2 | 3 | import java.io.IOException; 4 | import java.io.UncheckedIOException; 5 | import java.net.URL; 6 | import java.util.Objects; 7 | 8 | import org.eclipse.microprofile.config.Config; 9 | import org.eclipse.microprofile.config.spi.ConfigProviderResolver; 10 | 11 | import io.smallrye.config.PropertiesConfigSource; 12 | 13 | public final class MockConfigUtils { 14 | 15 | private MockConfigUtils() { 16 | } 17 | 18 | public static Config getTestConfig(String propertiesFile) { 19 | PropertiesConfigSource configSource; 20 | try { 21 | configSource = new PropertiesConfigSource(getResource(propertiesFile)); 22 | } catch (IOException e) { 23 | throw new UncheckedIOException(e); 24 | } 25 | 26 | return ConfigProviderResolver 27 | .instance() 28 | .getBuilder() 29 | .withSources(configSource) 30 | .build(); 31 | } 32 | 33 | private static URL getResource(String resourcePath) { 34 | return Objects.requireNonNull(MockConfigUtils.class.getResource(resourcePath)); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /client/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/assertions/Assertions.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment.assertions; 2 | 3 | import com.github.javaparser.ast.body.MethodDeclaration; 4 | 5 | import io.quarkiverse.openapi.generator.testutils.circuitbreaker.assertions.CircuitBreakerMethodAssert; 6 | 7 | public final class Assertions extends org.assertj.core.api.Assertions { 8 | 9 | private Assertions() { 10 | } 11 | 12 | public static CircuitBreakerMethodAssert assertThat(MethodDeclaration actual) { 13 | return CircuitBreakerMethodAssert.assertThat(actual); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /client/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/wrapper/QuarkusJavaClientCodegenTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.deployment.wrapper; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.CsvSource; 5 | 6 | import io.quarkiverse.openapi.generator.deployment.assertions.Assertions; 7 | 8 | class QuarkusJavaClientCodegenTest { 9 | 10 | @ParameterizedTest 11 | @CsvSource({ 12 | "/status/addressStatus,String,SLASH_STATUS_SLASH_ADDRESSSTATUS", 13 | "$,String,DOLLAR_SYMBOL", 14 | "/users,String,SLASH_USERS", 15 | "' ',String,EMPTY", 16 | "123456,String,_123456", 17 | "quarkus_resources,String,QUARKUS_RESOURCES", 18 | "123456,Integer,NUMBER_123456", // old behavior 19 | "123+123,Long,NUMBER_123PLUS_123", // old behavior, 20 | "M123,String,M123", 21 | "MA456,String,MA456", 22 | "P1,String,P1", 23 | }) 24 | void toEnumVarName(String value, String dataType, String expectedVarName) { 25 | 26 | QuarkusJavaClientCodegen quarkusJavaClientCodegen = new QuarkusJavaClientCodegen(); 27 | 28 | String varName = quarkusJavaClientCodegen.toEnumVarName(value, dataType); 29 | 30 | Assertions.assertThat(varName).isEqualTo(expectedVarName); 31 | } 32 | } -------------------------------------------------------------------------------- /client/deployment/src/test/resources/circuitbreaker/missing_circuit_breaker_enabled_application.properties: -------------------------------------------------------------------------------- 1 | # used by io.quarkiverse.openapi.generator.deployment.circuitbreaker.CircuitBreakerConfigurationParserTest 2 | quarkus.openapi-generator.codegen.spec.any_api_json.base-package=org.acme.openapi 3 | quarkus.openapi-generator.codegen.spec.restcountries_json.base-package=org.acme.openapi 4 | 5 | org.acme.CountryResource/getCountries/CircuitBreaker/failOn = java.lang.IllegalArgumentException,java.lang.NullPointerException 6 | org.acme.CountryResource/getCountries/CircuitBreaker/skipOn = java.lang.NumberFormatException, java.lang.IndexOutOfBoundsException 7 | org.acme.CountryResource/getCountries/CircuitBreaker/delay = 33 8 | org.acme.CountryResource/getCountries/CircuitBreaker/delayUnit = MILLIS 9 | org.acme.CountryResource/getCountries/CircuitBreaker/requestVolumeThreshold = 42 10 | org.acme.CountryResource/getCountries/CircuitBreaker/failureRatio = 3.14 11 | org.acme.CountryResource/getCountries/CircuitBreaker/successThreshold = 22 12 | 13 | org.acme.CountryResource/getByCapital/CircuitBreaker/skipOn = java.lang.IndexOutOfBoundsException 14 | org.acme.CountryResource/getByCapital/CircuitBreaker/delay = 3 15 | org.acme.CountryResource/getByCapital/CircuitBreaker/successThreshold = 10 16 | 17 | org.acme.CityResource/get/CircuitBreaker/skipOn = java.lang.IndexOutOfBoundsException 18 | org.acme.CityResource/get/CircuitBreaker/delay = 3 19 | org.acme.CityResource/get/CircuitBreaker/successThreshold = 10 -------------------------------------------------------------------------------- /client/deployment/src/test/resources/codegen/application.properties: -------------------------------------------------------------------------------- 1 | 2 | # Base package for our generated code 3 | quarkus.openapi-generator.codegen.spec.issue_38_yaml.base-package=org.issue38 4 | 5 | # Should we generate deprecated attributes for the given model? 6 | # By default, deprecated attributes in model classes are generated 7 | # Using these properties you can fine tune the configuration for a given model 8 | # all the model classes are generated using the given package concatenated with ".model" and the classname 9 | # see the examples below 10 | org.issue38.model.MetaV1Condition.generateDeprecated=false 11 | org.issue38.model.ConnectorDeploymentSpec.generateDeprecated=false 12 | -------------------------------------------------------------------------------- /client/deployment/src/test/resources/deprecated/application.properties: -------------------------------------------------------------------------------- 1 | 2 | # Base package for our generated code 3 | quarkus.openapi-generator.codegen.spec.deprecated_json.base-package=org.deprecated 4 | 5 | # Should we generate deprecated operations for the given api? 6 | # By default, deprecated operations in model classes are generated 7 | # Using these properties you can fine tune the configuration for a given API 8 | # all the API classes are generated using the given package concatenated with ".api" and the classname 9 | # see the examples below 10 | org.deprecated.api.DefaultApi.generateDeprecated=false 11 | 12 | -------------------------------------------------------------------------------- /client/deployment/src/test/resources/openapi/deprecated.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.3", 3 | "info": { 4 | "title": "Simple API", 5 | "version": "1.0.0-SNAPSHOT" 6 | }, 7 | "paths": { 8 | "/hello": { 9 | "get": { 10 | "responses": { 11 | "200": { 12 | "description": "OK", 13 | "content": { 14 | "text/plain": { 15 | "schema": { 16 | "type": "string" 17 | } 18 | } 19 | } 20 | } 21 | } 22 | } 23 | }, 24 | 25 | "/bye": { 26 | "get": { 27 | "responses": { 28 | "200": { 29 | "description": "OK", 30 | "content": { 31 | "text/plain": { 32 | "schema": { 33 | "type": "string" 34 | } 35 | } 36 | } 37 | } 38 | }, 39 | "deprecated": true 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /client/deployment/src/test/resources/openapi/issue-933-security.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Generated API 4 | version: "1.0" 5 | paths: 6 | /: 7 | post: 8 | operationId: doOperation 9 | security: 10 | - client_id: [ ] 11 | - oauth: [ read, write ] 12 | - bearerAuth: [ ] 13 | requestBody: 14 | content: 15 | application/json: 16 | schema: 17 | $ref: '#/components/schemas/MultiplicationOperation' 18 | responses: 19 | "200": 20 | description: OK 21 | components: 22 | schemas: 23 | MultiplicationOperation: 24 | type: object 25 | securitySchemes: 26 | client_id: 27 | type: apiKey 28 | in: header 29 | name: X-Client-Id 30 | x-key-type: clientId 31 | bearerAuth: 32 | type: http 33 | scheme: bearer 34 | oauth: 35 | type: oauth2 36 | flows: 37 | authorizationCode: 38 | authorizationUrl: https://example.com/oauth/authorize 39 | tokenUrl: https://example.com/oauth/token 40 | scopes: 41 | read: Grants read access 42 | write: Grants write access 43 | admin: Grants read and write access to administrative information 44 | clientCredentials: 45 | tokenUrl: http://localhost:8382/oauth/token 46 | scopes: 47 | read: read -------------------------------------------------------------------------------- /client/deployment/src/test/resources/openapi/suffix-prefix-openapi.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.3", 3 | "info": { 4 | "title": "Simple API", 5 | "version": "1.0.0-SNAPSHOT" 6 | }, 7 | "paths": { 8 | "/hello": { 9 | "get": { 10 | "operationId": "helloMethod", 11 | "responses": { 12 | "200": { 13 | "description": "OK", 14 | "content": { 15 | "text/plain": { 16 | "schema": { 17 | "type": "string" 18 | } 19 | } 20 | } 21 | } 22 | } 23 | } 24 | }, 25 | 26 | "/bye": { 27 | "get": { 28 | "operationId": "Bye method_get", 29 | "responses": { 30 | "200": { 31 | "description": "OK", 32 | "content": { 33 | "text/plain": { 34 | "schema": { 35 | "type": "string" 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | } 43 | }, 44 | "components": { 45 | "schemas":{ 46 | "HelloModel": { 47 | "type": "object", 48 | "properties": { 49 | "id": { 50 | "type": "string" 51 | } 52 | } 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /client/deployment/src/test/resources/templates/hello.qute: -------------------------------------------------------------------------------- 1 | Hello! My name is {name} -------------------------------------------------------------------------------- /client/integration-tests/additional-properties/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # with additional properties as attribute = TRUE 2 | quarkus.openapi-generator.codegen.spec.with_additional_properties_as_attr_yaml.additional-properties-as-attribute=true 3 | 4 | 5 | # with additional properties as attribute = FALSE 6 | quarkus.openapi-generator.codegen.spec.no_additional_properties_as_attr_yaml.additional-properties-as-attribute=false 7 | 8 | quarkus.keycloak.devservices.enabled=false 9 | 10 | 11 | -------------------------------------------------------------------------------- /client/integration-tests/array-enum/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.rest-client.array_enum_yaml.url=http://localhost:8080 2 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/array-enum/src/test/java/io/quarkiverse/openapi/generator/it/ArrayEnumTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import jakarta.inject.Inject; 6 | 7 | import org.eclipse.microprofile.rest.client.inject.RestClient; 8 | import org.junit.jupiter.api.Test; 9 | import org.openapi.quarkus.array_enum_yaml.api.ArrayEnumResourceApi; 10 | import org.openapi.quarkus.array_enum_yaml.model.WebhookCreateUpdatePayload; 11 | 12 | import io.quarkus.test.junit.QuarkusTest; 13 | 14 | @QuarkusTest 15 | class ArrayEnumTest { 16 | 17 | @RestClient 18 | @Inject 19 | ArrayEnumResourceApi api; 20 | 21 | @Test 22 | void apiIsBeingGenerated() { 23 | assertThat(api).isNotNull(); 24 | } 25 | 26 | @Test 27 | void modelNonRequiredFieldTest() { 28 | WebhookCreateUpdatePayload webhookCreateUpdatePayload = new WebhookCreateUpdatePayload(); 29 | 30 | assertThat(webhookCreateUpdatePayload.getMessage()).isNull(); 31 | assertThat(webhookCreateUpdatePayload.getMessageMap()).isNull(); 32 | 33 | webhookCreateUpdatePayload.addMessageItem("Test"); 34 | webhookCreateUpdatePayload.putMessageMapItem("Test", "Test"); 35 | 36 | assertThat(webhookCreateUpdatePayload.getMessage()).isNotNull(); 37 | assertThat(webhookCreateUpdatePayload.getMessageMap()).isNotNull(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /client/integration-tests/auth-provider/src/main/java/io/quarkiverse/openapi/generator/it/auth/TokenServerResource.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it.auth; 2 | 3 | import jakarta.ws.rs.POST; 4 | import jakarta.ws.rs.Path; 5 | 6 | import org.eclipse.microprofile.rest.client.inject.RestClient; 7 | 8 | @Path("/token_server") 9 | public class TokenServerResource { 10 | 11 | @RestClient 12 | org.acme.externalservice1.api.DefaultApi defaultApi1; 13 | 14 | @RestClient 15 | org.acme.externalservice2.api.DefaultApi defaultApi2; 16 | 17 | @RestClient 18 | org.acme.externalservice3.api.DefaultApi defaultApi3; 19 | 20 | @RestClient 21 | org.acme.externalservice5.api.DefaultApi defaultApi5; 22 | 23 | @POST 24 | @Path("service1") 25 | public String service1() { 26 | defaultApi1.executeQuery1(); 27 | return "hello"; 28 | } 29 | 30 | @POST 31 | @Path("service2") 32 | public String service2() { 33 | defaultApi2.executeQuery2(); 34 | return "hello"; 35 | } 36 | 37 | @POST 38 | @Path("service3") 39 | public String service3() { 40 | defaultApi3.executeQuery3(); 41 | return "hello"; 42 | } 43 | 44 | @POST 45 | @Path("service5") 46 | public String service5() { 47 | defaultApi5.executeQuery5(); 48 | return "hello"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /client/integration-tests/auth-provider/src/main/java/io/quarkiverse/openapi/generator/it/auth/provider/CustomCredentialsProvider.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it.auth.provider; 2 | 3 | import jakarta.annotation.Priority; 4 | import jakarta.enterprise.context.Dependent; 5 | import jakarta.enterprise.inject.Alternative; 6 | import jakarta.enterprise.inject.Specializes; 7 | 8 | import io.quarkiverse.openapi.generator.providers.ConfigCredentialsProvider; 9 | import io.quarkiverse.openapi.generator.providers.CredentialsContext; 10 | 11 | @Dependent 12 | @Alternative 13 | @Specializes 14 | @Priority(200) 15 | public class CustomCredentialsProvider extends ConfigCredentialsProvider { 16 | public CustomCredentialsProvider() { 17 | } 18 | 19 | @Override 20 | public String getBearerToken(CredentialsContext input) { 21 | return super.getBearerToken(input) + "_TEST"; 22 | } 23 | 24 | @Override 25 | public String getOauth2BearerToken(CredentialsContext input) { 26 | return super.getOauth2BearerToken(input) + "_TEST"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /client/integration-tests/auth-provider/src/main/openapi/token-external-service1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: token-external-service1 API 5 | version: 3.0.0-SNAPSHOT 6 | paths: 7 | /token-external-service1/executeQuery1: 8 | post: 9 | operationId: executeQuery1 10 | responses: 11 | "200": 12 | description: OK 13 | security: 14 | - service1-http-bearer: [] 15 | components: 16 | securitySchemes: 17 | service1-http-bearer: 18 | type: http 19 | scheme: bearer -------------------------------------------------------------------------------- /client/integration-tests/auth-provider/src/main/openapi/token-external-service2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: token-external-service2 API 5 | version: 3.0.0-SNAPSHOT 6 | paths: 7 | /token-external-service2/executeQuery2: 8 | post: 9 | operationId: executeQuery2 10 | responses: 11 | "200": 12 | description: OK 13 | security: 14 | - service2-oauth2: [] 15 | components: 16 | securitySchemes: 17 | service2-oauth2: 18 | type: oauth2 19 | flows: 20 | clientCredentials: 21 | authorizationUrl: https://example.com/oauth 22 | tokenUrl: https://example.com/oauth/token 23 | scopes: {} -------------------------------------------------------------------------------- /client/integration-tests/auth-provider/src/main/openapi/token-external-service3.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: token-external-service3 API 5 | version: 3.0.0-SNAPSHOT 6 | paths: 7 | /token-external-service3/executeQuery3: 8 | post: 9 | operationId: executeQuery3 10 | responses: 11 | "200": 12 | description: OK 13 | security: 14 | - service3-http-bearer: [] 15 | components: 16 | securitySchemes: 17 | service3-http-bearer: 18 | type: http 19 | scheme: bearer -------------------------------------------------------------------------------- /client/integration-tests/auth-provider/src/main/openapi/token-external-service5.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: token-external-service5 API 5 | version: 3.0.0-SNAPSHOT 6 | paths: 7 | /token-external-service5/executeQuery5: 8 | post: 9 | operationId: executeQuery5 10 | responses: 11 | "200": 12 | description: OK 13 | security: 14 | - service5-oauth2: [] 15 | components: 16 | securitySchemes: 17 | service5-oauth2: 18 | type: oauth2 19 | flows: 20 | clientCredentials: 21 | authorizationUrl: https://example.com/oauth 22 | tokenUrl: https://example.com/oauth/token 23 | scopes: {} -------------------------------------------------------------------------------- /client/integration-tests/auth-provider/src/test/java/io/quarkiverse/openapi/generator/it/auth/TokenWithCustomCredentialProviderTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it.auth; 2 | 3 | import static io.quarkiverse.openapi.generator.it.auth.TokenExternalServicesMock.AUTHORIZATION_TOKEN; 4 | import static io.restassured.RestAssured.given; 5 | 6 | import java.util.Map; 7 | 8 | import jakarta.ws.rs.core.HttpHeaders; 9 | 10 | import org.junit.jupiter.api.Tag; 11 | import org.junit.jupiter.params.ParameterizedTest; 12 | import org.junit.jupiter.params.provider.ValueSource; 13 | 14 | import io.quarkus.test.common.QuarkusTestResource; 15 | import io.quarkus.test.junit.QuarkusTest; 16 | 17 | @QuarkusTestResource(TokenExternalServicesMock.class) 18 | @QuarkusTestResource(KeycloakServiceMock.class) 19 | @QuarkusTest 20 | // Enabled only for RESTEasy Classic while https://github.com/quarkiverse/quarkus-openapi-generator/issues/434 is not fixed 21 | @Tag("resteasy-classic") 22 | class TokenWithCustomCredentialProviderTest { 23 | 24 | @ParameterizedTest 25 | @ValueSource(strings = { "service1", "service2", "service3", "service5" }) 26 | void testService(String service) { 27 | Map headers = Map.of(HttpHeaders.AUTHORIZATION, AUTHORIZATION_TOKEN); 28 | 29 | given() 30 | .headers(headers) 31 | .post("/token_server/" + service) 32 | .then() 33 | .statusCode(200); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /client/integration-tests/bean-validation/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.bean_validation_true_yaml.use-bean-validation = true 2 | quarkus.openapi-generator.codegen.spec.issue_976_yaml.use-bean-validation = true 3 | quarkus.openapi-generator.codegen.spec.bean_validation_false_yaml.use-bean-validation = false 4 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/beanparam/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/change-custom-template-directory/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.template-base-dir=custom/templates 2 | quarkus.openapi-generator.codegen.spec.simple_openapi_yaml.base-package=org.simple.openapi 3 | quarkus.rest-client.simple_openapi_yaml.uri=http://localhost:8080 4 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/change-custom-template-directory/src/test/java/it/ChangeCustomTemplateDirectoryTest.java: -------------------------------------------------------------------------------- 1 | package it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import org.junit.jupiter.api.Test; 6 | import org.simple.openapi.api.ReactiveGreetingResourceApi; 7 | 8 | class ChangeCustomTemplateDirectoryTest { 9 | 10 | @Test 11 | void apiIsBeingGenerated() throws NoSuchMethodException { 12 | assertThat(ReactiveGreetingResourceApi.class.getMethod("myCustomMethod")).isNotNull(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /client/integration-tests/change-directory/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.input-base-dir=openapi-definitions 2 | quarkus.openapi-generator.codegen.spec.simple_openapi_yaml.base-package=org.simple.openapi 3 | quarkus.rest-client.simple_openapi_yaml.uri=http://localhost:8080 4 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/change-directory/src/test/java/it/ChangeDirectoryTest.java: -------------------------------------------------------------------------------- 1 | package it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import jakarta.inject.Inject; 6 | 7 | import org.eclipse.microprofile.rest.client.inject.RestClient; 8 | import org.junit.jupiter.api.Test; 9 | import org.simple.openapi.api.ReactiveGreetingResourceApi; 10 | 11 | import io.quarkus.test.junit.QuarkusTest; 12 | 13 | @QuarkusTest 14 | class ChangeDirectoryTest { 15 | 16 | @RestClient 17 | @Inject 18 | ReactiveGreetingResourceApi api; 19 | 20 | @Test 21 | void apiIsBeingGenerated() { 22 | assertThat(api).isNotNull(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/integration-tests/circuit-breaker/src/main/openapi/simple-openapi.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.3", 3 | "info": { 4 | "title": "Simple API", 5 | "version": "1.0.0-SNAPSHOT" 6 | }, 7 | "paths": { 8 | "/hello": { 9 | "get": { 10 | "responses": { 11 | "200": { 12 | "description": "OK", 13 | "content": { 14 | "text/plain": { 15 | "schema": { 16 | "type": "string" 17 | } 18 | } 19 | } 20 | } 21 | } 22 | } 23 | }, 24 | 25 | "/bye": { 26 | "get": { 27 | "responses": { 28 | "200": { 29 | "description": "OK", 30 | "content": { 31 | "text/plain": { 32 | "schema": { 33 | "type": "string" 34 | } 35 | } 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /client/integration-tests/circuit-breaker/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/enabled=true 2 | org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/failOn = java.lang.IllegalArgumentException,java.lang.NullPointerException 3 | org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/skipOn = java.lang.NumberFormatException, java.lang.IndexOutOfBoundsException 4 | org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/delay = 33 5 | org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/delayUnit = MILLIS 6 | org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/requestVolumeThreshold = 42 7 | org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/failureRatio = 3.14 8 | org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/successThreshold = 22 9 | 10 | quarkus.keycloak.devservices.enabled=false 11 | 12 | quarkus.openapi-generator.codegen.spec.simple_openapi_json.base-package=org.acme.openapi.simple 13 | -------------------------------------------------------------------------------- /client/integration-tests/circuit-breaker/src/test/java/io/quarkiverse/openapi/generator/it/circuit/breaker/assertions/Assertions.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it.circuit.breaker.assertions; 2 | 3 | import com.github.javaparser.ast.body.MethodDeclaration; 4 | 5 | import io.quarkiverse.openapi.generator.testutils.circuitbreaker.assertions.CircuitBreakerMethodAssert; 6 | 7 | public final class Assertions extends org.assertj.core.api.Assertions { 8 | 9 | private Assertions() { 10 | } 11 | 12 | public static CircuitBreakerMethodAssert assertThat(MethodDeclaration actual) { 13 | return CircuitBreakerMethodAssert.assertThat(actual); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /client/integration-tests/config-key/src/main/java/io/quarkiverse/openapi/generator/configkey/AnotherCustomAnnotation.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.configkey; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface AnotherCustomAnnotation { 8 | } 9 | -------------------------------------------------------------------------------- /client/integration-tests/config-key/src/main/java/io/quarkiverse/openapi/generator/configkey/CustomAnnotation.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.configkey; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface CustomAnnotation { 8 | } 9 | -------------------------------------------------------------------------------- /client/integration-tests/config-key/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # custom_config_key 2 | quarkus.rest-client.custom_config_key.url=http://localhost:8080 3 | quarkus.openapi-generator.codegen.spec.config_key_openapi_yaml.config-key=custom_config_key 4 | quarkus.openapi-generator.codegen.spec.custom_config_key.mutiny=true 5 | quarkus.openapi-generator.codegen.spec.custom_config_key.base-package=com.oapi.pkg 6 | 7 | # use the @AnotherCustomAnnotation with `config_key_openapi_yaml` 8 | quarkus.openapi-generator.codegen.spec.config_key_openapi_yaml.additional-api-type-annotations=@io.quarkiverse.openapi.generator.configkey.AnotherCustomAnnotation 9 | quarkus.openapi-generator.codegen.spec.custom_config_key.additional-api-type-annotations=@io.quarkiverse.openapi.generator.configkey.CustomAnnotation 10 | 11 | 12 | # empty config-key 13 | quarkus.openapi-generator.codegen.spec.empty_config_key_yaml.config-key= 14 | 15 | quarkus.openapi-generator.codegen.spec.empty_config_key_yaml.additional-api-type-annotations=@io.quarkiverse.openapi.generator.configkey.CustomAnnotation 16 | quarkus.rest-client.empty_config_key_yaml.url=http://localhost:8080 17 | 18 | quarkus.keycloak.devservices.enabled=false 19 | 20 | # config-key with `-` 21 | quarkus.openapi-generator.codegen.spec.config_key_with_dash_yaml.config-key=my-api 22 | quarkus.rest-client.my-api.url=http://localhost:8080 23 | -------------------------------------------------------------------------------- /client/integration-tests/config-key/src/test/java/io/quarkiverse/openapi/generator/configkey/QuarkusConfigKeyWithDashOpenApiTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.configkey; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import jakarta.inject.Inject; 6 | 7 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; 8 | import org.eclipse.microprofile.rest.client.inject.RestClient; 9 | import org.junit.jupiter.api.Test; 10 | import org.openapi.quarkus.config_key_with_dash_yaml.api.DefaultApi; 11 | 12 | import io.quarkus.test.junit.QuarkusTest; 13 | 14 | @QuarkusTest 15 | class QuarkusConfigKeyWithDashOpenApiTest { 16 | 17 | @RestClient 18 | @Inject 19 | DefaultApi defaultApi; 20 | 21 | @Test 22 | void apiIsBeingGenerated() { 23 | assertThat(defaultApi).isNotNull(); 24 | } 25 | 26 | @Test 27 | void config_key_should_have_dash() { 28 | assertThat(DefaultApi.class.getAnnotation(RegisterRestClient.class)).isNotNull(); 29 | assertThat(DefaultApi.class.getAnnotation(RegisterRestClient.class).configKey()).isEqualTo("my-api"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /client/integration-tests/cookie-authentication/src/main/openapi/cookie-authentication.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.1", 3 | "info": { 4 | "title": "Quarkus - Openapi Generator - Integration Tests - Client - Cookie Authentication", 5 | "version": "v1" 6 | }, 7 | "servers": [ 8 | { 9 | "url": "http://localhost:8080" 10 | } 11 | ], 12 | "security": [ 13 | { 14 | "cookie": [] 15 | } 16 | ], 17 | "tags": [ 18 | { 19 | "name": "Test" 20 | } 21 | ], 22 | "paths": { 23 | "/v1/test": { 24 | "get": { 25 | "tags": [ 26 | "Test" 27 | ], 28 | "operationId": "doTest", 29 | "responses": { 30 | "204": { 31 | "description": "Test succeeded" 32 | } 33 | } 34 | } 35 | } 36 | }, 37 | "components": { 38 | "securitySchemes": { 39 | "cookie": { 40 | "type": "apiKey", 41 | "name": "TASKLIST-SESSION", 42 | "in": "cookie" 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /client/integration-tests/cookie-authentication/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.cookie_authentication_json.mutiny=true 2 | quarkus.openapi-generator.cookie_authentication_json.auth.cookie.api-key=Quarkus 3 | 4 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/cookie-authentication/src/test/java/io/quarkiverse/openapi/generator/it/CookieAuthenticationTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; 4 | import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | import java.time.Duration; 8 | 9 | import jakarta.inject.Inject; 10 | import jakarta.ws.rs.core.Response; 11 | 12 | import org.eclipse.microprofile.rest.client.inject.RestClient; 13 | import org.junit.jupiter.api.Tag; 14 | import org.junit.jupiter.api.Test; 15 | import org.openapi.quarkus.cookie_authentication_json.api.TestApi; 16 | 17 | import com.github.tomakehurst.wiremock.WireMockServer; 18 | 19 | import io.quarkus.test.common.QuarkusTestResource; 20 | import io.quarkus.test.junit.QuarkusTest; 21 | 22 | @QuarkusTest 23 | @QuarkusTestResource(WiremockCookieAuthentication.class) 24 | @Tag("resteasy-reactive") 25 | class CookieAuthenticationTest { 26 | // Injected by Quarkus test resource 27 | WireMockServer wireMockServer; 28 | 29 | @RestClient 30 | @Inject 31 | TestApi testApi; 32 | 33 | @Test 34 | void apiIsBeingGenerated() { 35 | final Response response = testApi.doTest() 36 | .await() 37 | .atMost(Duration.ofSeconds(5L)); 38 | assertThat(response) 39 | .extracting(Response::getStatus) 40 | .isEqualTo(204); 41 | wireMockServer.verify(getRequestedFor(urlEqualTo("/v1/test"))); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /client/integration-tests/custom-templates/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.rest-client.quarkus_simple_openapi_yaml.url=http://localhost:8080 2 | 3 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/custom-templates/src/test/java/io/quarkiverse/openapi/generator/it/QuarkusSimpleOpenApiTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import org.junit.jupiter.api.Test; 6 | import org.openapi.quarkus.quarkus_simple_openapi_yaml.api.ReactiveGreetingResourceApi; 7 | import org.openapi.quarkus.quarkus_simple_openapi_yaml.model.CloudEvent; 8 | 9 | import io.quarkus.test.junit.QuarkusTest; 10 | 11 | @QuarkusTest 12 | class QuarkusSimpleOpenApiTest { 13 | 14 | @Test 15 | void apiIsBeingGenerated() throws NoSuchFieldException, NoSuchMethodException { 16 | assertThat(ReactiveGreetingResourceApi.class.getMethod("myCustomMethod")).isNotNull(); 17 | assertThat(CloudEvent.CloudEventQueryParam.class.getField("myCustomQueryParamAttribute")).isNotNull(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /client/integration-tests/enum-property/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/enum-unexpected/src/main/openapi/with-enum-unexpected.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: echo 4 | version: '1.0.0' 5 | description: "" 6 | paths: 7 | /echo: 8 | post: 9 | summary: Echo 10 | operationId: echo 11 | responses: 12 | "200": 13 | description: OK 14 | content: 15 | application/json: 16 | schema: 17 | $ref: '#/components/schemas/Echo' 18 | components: 19 | schemas: 20 | Echo: 21 | type: object 22 | required: 23 | - msgType 24 | properties: 25 | msgType: 26 | type: string 27 | enum: 28 | - 'text' 29 | -------------------------------------------------------------------------------- /client/integration-tests/enum-unexpected/src/main/openapi/without-enum-unexpected.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: echo 4 | version: '1.0.0' 5 | description: "" 6 | paths: 7 | /echo: 8 | post: 9 | summary: Echo 10 | operationId: echo 11 | responses: 12 | "200": 13 | description: OK 14 | content: 15 | application/json: 16 | schema: 17 | $ref: '#/components/schemas/Echo' 18 | components: 19 | schemas: 20 | Echo: 21 | type: object 22 | required: 23 | - msgType 24 | properties: 25 | msgType: 26 | type: string 27 | enum: 28 | - 'text' 29 | -------------------------------------------------------------------------------- /client/integration-tests/enum-unexpected/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.with_enum_unexpected_yaml.additional-enum-type-unexpected-member=true 2 | 3 | quarkus.openapi-generator.codegen.spec.without_enum_unexpected_yaml.additional-enum-type-unexpected-member=false 4 | 5 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/equals-hashcode/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.quarkus_equals_hashcode_openapi_yaml.base-package=org.acme.equals.hashcode 2 | 3 | quarkus.openapi-generator.codegen.spec.quarkus_non_equals_hashcode_openapi_yaml.base-package=org.acme.non.equals.hashcode 4 | quarkus.openapi-generator.codegen.spec.quarkus_non_equals_hashcode_openapi_yaml.equals-hashcode=false 5 | 6 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/equals-hashcode/src/test/java/io/quarkiverse/openapi/generator/it/EqualsHashcodeTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertNotEquals; 5 | 6 | import java.time.OffsetDateTime; 7 | 8 | import org.acme.equals.hashcode.model.Animal; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import io.quarkus.test.junit.QuarkusTest; 12 | 13 | @QuarkusTest 14 | class EqualsHashcodeTest { 15 | 16 | @Test 17 | void verifyModelNotEquals() { 18 | var object1 = new Animal(); 19 | object1.setDeceased(OffsetDateTime.now().minusHours(2)); 20 | 21 | var object2 = new Animal(); 22 | object2.setBorn(OffsetDateTime.now().minusYears(1)); 23 | 24 | assertNotEquals(object1, object2); 25 | } 26 | 27 | @Test 28 | void verifyModelEquals() { 29 | var offset = OffsetDateTime.now().minusHours(2); 30 | 31 | var object1 = new Animal(); 32 | object1.setDeceased(offset); 33 | 34 | var object2 = new Animal(); 35 | object2.setDeceased(offset); 36 | 37 | assertEquals(object1, object2); 38 | } 39 | 40 | @Test 41 | void verifyModelHasHashCode() { 42 | var offset = OffsetDateTime.now().minusHours(2); 43 | 44 | var object1 = new Animal(); 45 | object1.setDeceased(offset); 46 | 47 | var object2 = new Animal(); 48 | object2.setDeceased(offset); 49 | 50 | assertEquals(object1.hashCode(), object2.hashCode()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /client/integration-tests/exclude/src/main/openapi/exclude-openapi.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: greeting-flow API 5 | version: "1.0" 6 | paths: 7 | /hello_excluded: 8 | get: 9 | tags: 10 | - Excluded OpenAPI Resource 11 | operationId: hello_excluded 12 | responses: 13 | "200": 14 | description: OK 15 | content: 16 | text/plain: 17 | schema: 18 | type: string 19 | -------------------------------------------------------------------------------- /client/integration-tests/exclude/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.exclude=exclude-openapi.yaml 2 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/exclude/src/test/java/io/quarkiverse/openapi/generator/it/ExcludeTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | import static org.assertj.core.api.Assertions.assertThatCode; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | import io.quarkus.test.junit.QuarkusTest; 9 | 10 | @QuarkusTest 11 | class ExcludeTest { 12 | 13 | @Test 14 | void onlyNonExcludedClassesAreGenerated() throws ClassNotFoundException { 15 | assertThat(Class.forName("org.openapi.quarkus.openapi_yaml.api.SimpleOpenApiResourceApi")) 16 | .isNotNull(); 17 | 18 | assertThatCode(() -> Class.forName("org.openapi.quarkus.exclude_openapi_yaml.api.ExcludedOpenApiResourceApi")) 19 | .isInstanceOf(ClassNotFoundException.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /client/integration-tests/generate-flags/src/main/openapi/generate_apis_false.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: Test API 5 | version: "1.0" 6 | paths: 7 | /{pathParam}: 8 | get: 9 | tags: 10 | - NonExistentEndpoint 11 | operationId: test 12 | parameters: 13 | - name: pathParam 14 | in: path 15 | required: true 16 | schema: 17 | type: string 18 | minimum: 5 19 | - name: headerParam 20 | in: header 21 | required: false 22 | schema: 23 | type: integer 24 | maximum: 5 25 | - name: cookieParam 26 | in: cookie 27 | required: true 28 | schema: 29 | type: string 30 | minLength: 10 31 | responses: 32 | "200": 33 | description: OK 34 | content: 35 | text/plain: 36 | schema: 37 | type: string 38 | components: 39 | schemas: 40 | ExistentObject: 41 | type: object 42 | description: Some object not to be validated 43 | required: 44 | - id 45 | - name 46 | - size 47 | properties: 48 | id: 49 | type: integer 50 | minimum: 1 51 | maximum: 100 52 | name: 53 | type: string 54 | pattern: "[a-zA-Z]*" 55 | minLength: 1 56 | maxLength: 10 57 | size: 58 | type: number 59 | minimum: 1.0 60 | maximum: 10.0 -------------------------------------------------------------------------------- /client/integration-tests/generate-flags/src/main/openapi/generate_models_false.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: Test API 5 | version: "1.0" 6 | paths: 7 | /{pathParam}: 8 | get: 9 | tags: 10 | - ExistentEndpoint 11 | operationId: test 12 | parameters: 13 | - name: pathParam 14 | in: path 15 | required: true 16 | schema: 17 | type: string 18 | minimum: 5 19 | - name: headerParam 20 | in: header 21 | required: false 22 | schema: 23 | type: integer 24 | maximum: 5 25 | - name: cookieParam 26 | in: cookie 27 | required: true 28 | schema: 29 | type: string 30 | minLength: 10 31 | responses: 32 | "200": 33 | description: OK 34 | content: 35 | text/plain: 36 | schema: 37 | type: string 38 | components: 39 | schemas: 40 | NonExistentObject: 41 | type: object 42 | description: Some object not to be validated 43 | required: 44 | - id 45 | - name 46 | - size 47 | properties: 48 | id: 49 | type: integer 50 | minimum: 1 51 | maximum: 100 52 | name: 53 | type: string 54 | pattern: "[a-zA-Z]*" 55 | minLength: 1 56 | maxLength: 10 57 | size: 58 | type: number 59 | minimum: 1.0 60 | maximum: 10.0 -------------------------------------------------------------------------------- /client/integration-tests/generate-flags/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.generate_models_false_yaml.generate-models = false 2 | quarkus.openapi-generator.codegen.spec.generate_apis_false_yaml.generate-apis = false -------------------------------------------------------------------------------- /client/integration-tests/generate-flags/src/test/java/io/quarkiverse/openapi/generator/it/GenerateFlagsTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import org.assertj.core.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import io.quarkus.test.junit.QuarkusTest; 7 | 8 | @QuarkusTest 9 | class GenerateFlagsTest { 10 | 11 | @Test 12 | void testEndpointIsInPlace() throws ClassNotFoundException { 13 | Class.forName("org.openapi.quarkus.generate_models_false_yaml.api.ExistentEndpointApi"); 14 | } 15 | 16 | @Test 17 | void testModelIsInPlace() throws ClassNotFoundException { 18 | Class.forName("org.openapi.quarkus.generate_apis_false_yaml.model.ExistentObject"); 19 | } 20 | 21 | @Test 22 | void testEndpointIsNotInPlace() { 23 | Assertions.assertThatThrownBy(() -> { 24 | Class.forName("org.openapi.quarkus.generate_apis_false_yaml.model.NonExistentEndpointApi"); 25 | }).isInstanceOf(ClassNotFoundException.class); 26 | } 27 | 28 | @Test 29 | void testModelIsNotInPlace() { 30 | Assertions.assertThatThrownBy(() -> { 31 | Class.forName("org.openapi.quarkus.generate_models_false_yaml.api.NonExistentObject"); 32 | }).isInstanceOf(ClassNotFoundException.class); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /client/integration-tests/generation-input/README.md: -------------------------------------------------------------------------------- 1 | # OpenAPI Generator - OpenAPISpecInputProvider Example 2 | 3 | This module exemplifies a library that provides the OpenAPI specification file as an input stream reference. 4 | 5 | See [generation-tests](../generation-tests) as a how to use example. 6 | -------------------------------------------------------------------------------- /client/integration-tests/generation-input/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | quarkus-openapi-generator-integration-tests 6 | io.quarkiverse.openapi.generator 7 | 3.0.0-SNAPSHOT 8 | 9 | quarkus-openapi-generator-it-generation-input 10 | Quarkus - OpenAPI Generator - Integration Tests - Client - Generation Input 11 | Example library that implements the OpenApiSpecInputProvider interface 12 | 13 | 14 | 15 | io.quarkiverse.openapi.generator 16 | quarkus-openapi-generator-deployment 17 | ${project.version} 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /client/integration-tests/generation-input/src/main/java/io/quarkiverse/openapi/generator/codegen/ClassPathPetstoreOpenApiSpecInputProvider.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.codegen; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import io.quarkiverse.openapi.generator.deployment.codegen.OpenApiSpecInputProvider; 7 | import io.quarkiverse.openapi.generator.deployment.codegen.SpecInputModel; 8 | import io.quarkus.deployment.CodeGenContext; 9 | 10 | /** 11 | * Class used during tests to read the spec PetStore file from an alternative input. 12 | * The Petstore spec file must be named petstore.json in the src/main/resources/specs directory. 13 | * In a real production environment, implementations should dynamically load these spec files. 14 | */ 15 | public class ClassPathPetstoreOpenApiSpecInputProvider implements OpenApiSpecInputProvider { 16 | 17 | @Override 18 | public List read(CodeGenContext context) { 19 | final List inputModels = new ArrayList<>(); 20 | inputModels.add(new SpecInputModel("petstore.json", this.getClass().getResourceAsStream("/specs/petstore.json"))); 21 | inputModels.add(new SpecInputModel("subtraction.yaml", this.getClass().getResourceAsStream("/specs/subtraction.yaml"), 22 | "org.math")); 23 | return inputModels; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /client/integration-tests/generation-input/src/main/resources/META-INF/services/io.quarkiverse.openapi.generator.deployment.codegen.OpenApiSpecInputProvider: -------------------------------------------------------------------------------- 1 | io.quarkiverse.openapi.generator.codegen.ClassPathPetstoreOpenApiSpecInputProvider -------------------------------------------------------------------------------- /client/integration-tests/generation-input/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/generation-input/src/main/resources/specs/README.md: -------------------------------------------------------------------------------- 1 | # Providing OpenAPI spec files via InputStream 2 | 3 | This directory is just meant to be used in the integration test cases. Instead of reading from the `src/main/openapi` directory, a spec file can also be read via a given `InputStream`. 4 | 5 | For this to work, clients must implement the `OpenApiSpecInputProvider` interface. The implementation read the files from any other source (an HTTP server, for example), and provide the input stream. 6 | -------------------------------------------------------------------------------- /client/integration-tests/generation-input/src/main/resources/specs/subtraction.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: Generated API 5 | version: "1.0" 6 | paths: 7 | /: 8 | post: 9 | operationId: doOperation 10 | requestBody: 11 | content: 12 | application/json: 13 | schema: 14 | $ref: '#/components/schemas/SubtractionOperation' 15 | responses: 16 | "200": 17 | description: OK 18 | components: 19 | schemas: 20 | SubtractionOperation: 21 | type: object 22 | properties: 23 | difference: 24 | format: float 25 | type: number 26 | leftElement: 27 | format: float 28 | type: number 29 | rightElement: 30 | format: float 31 | type: number 32 | -------------------------------------------------------------------------------- /client/integration-tests/generation-tests/README.md: -------------------------------------------------------------------------------- 1 | # OpenAPI Generator - OpenAPISpecInputProvider Example Usage 2 | 3 | This module exemplifies how to use an input stream instead of a file in the `openapi` directory to generate the Rest Clients. 4 | 5 | See the [generation-input](../generation-input) module as a library reference. 6 | -------------------------------------------------------------------------------- /client/integration-tests/generation-tests/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.petstore_json.base-package=org.acme.petstore 2 | # This one is passed through the Classpath source provider. Uncomment to overwrite it 3 | #quarkus.openapi-generator.codegen.spec.subtraction_yaml.base-package=org.acme.subtraction 4 | quarkus.oidc-client.client-enabled=false 5 | # ${keycloak.url} is provided by test-utils 6 | # petstore_auth is the name of the security scheme from the openapi spec file (petstore.json) 7 | # you can configure your OAuth2 Client the way it fits your use case here. 8 | # see https://quarkus.io/guides/security-openid-connect-client 9 | quarkus.oidc-client.petstore_auth.auth-server-url=${keycloak.url} 10 | quarkus.oidc-client.petstore_auth.discovery-enabled=false 11 | quarkus.oidc-client.petstore_auth.token-path=/tokens 12 | quarkus.oidc-client.petstore_auth.credentials.secret=secret 13 | quarkus.oidc-client.petstore_auth.grant.type=password 14 | quarkus.oidc-client.petstore_auth.grant-options.password.username=alice 15 | quarkus.oidc-client.petstore_auth.grant-options.password.password=alice 16 | quarkus.oidc-client.petstore_auth.client-id=petstore-app 17 | 18 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/generation-tests/src/test/java/io/quarkiverse/openapi/generator/it/PetStoreTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; 4 | import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | 7 | import jakarta.inject.Inject; 8 | 9 | import org.acme.petstore.api.PetApi; 10 | import org.acme.petstore.model.Pet; 11 | import org.eclipse.microprofile.rest.client.inject.RestClient; 12 | import org.junit.jupiter.api.Test; 13 | 14 | import com.github.tomakehurst.wiremock.WireMockServer; 15 | 16 | import io.quarkiverse.openapi.generator.testutils.keycloak.KeycloakRealmResourceManager; 17 | import io.quarkus.test.common.WithTestResource; 18 | import io.quarkus.test.junit.QuarkusTest; 19 | 20 | @WithTestResource(WiremockPetStore.class) 21 | @WithTestResource(KeycloakRealmResourceManager.class) 22 | @QuarkusTest 23 | public class PetStoreTest { 24 | 25 | // injected by quarkus test resource 26 | WireMockServer petstoreServer; 27 | 28 | @RestClient 29 | @Inject 30 | PetApi petApi; 31 | 32 | @Test 33 | public void testGetPetById() { 34 | final Pet pet = petApi.getPetById(1234L); 35 | assertEquals("Bidu", pet.getName()); 36 | assertEquals(Pet.StatusEnum.AVAILABLE, pet.getStatus()); 37 | 38 | petstoreServer.verify(getRequestedFor(urlEqualTo("/pet/1234"))); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /client/integration-tests/github/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/include/src/main/openapi/ignore-openapi.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: greeting-flow API 5 | version: "1.0" 6 | paths: 7 | /hello_ignored: 8 | get: 9 | tags: 10 | - Ignored OpenAPI Resource 11 | operationId: hello_ignored 12 | responses: 13 | "200": 14 | description: OK 15 | content: 16 | text/plain: 17 | schema: 18 | type: string 19 | -------------------------------------------------------------------------------- /client/integration-tests/include/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.include=include-openapi.yaml 2 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/include/src/test/java/io/quarkiverse/openapi/generator/it/IncludeTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | import static org.assertj.core.api.Assertions.assertThatCode; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | import io.quarkus.test.junit.QuarkusTest; 9 | 10 | @QuarkusTest 11 | class IncludeTest { 12 | 13 | @Test 14 | void onlyIncludedClassesAreGenerated() throws ClassNotFoundException { 15 | assertThat(Class.forName("org.openapi.quarkus.include_openapi_yaml.api.SimpleOpenApiResourceApi")) 16 | .isNotNull(); 17 | 18 | assertThatCode(() -> Class.forName("org.openapi.quarkus.exclude_openapi_yaml.api.IgnoredOpenApiResourceApi")) 19 | .isInstanceOf(ClassNotFoundException.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /client/integration-tests/initialize-empty-collections/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # with initialise empty collections = TRUE 2 | quarkus.openapi-generator.codegen.spec.quarkus_simple_openapi_empty_collections_yaml.initialize-empty-collections=true 3 | # with initialise empty collections = TRUE 4 | quarkus.openapi-generator.codegen.spec.quarkus_simple_openapi_null_collections_yaml.initialize-empty-collections=false 5 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/initialize-empty-collections/src/test/java/io/quarkiverse/openapi/generator/initialiseEmptyCollections/QuarkusInitialiseEmptyCollectionWhenFalseTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.initialiseEmptyCollections; 2 | 3 | import jakarta.inject.Inject; 4 | 5 | import org.assertj.core.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | import org.openapi.quarkus.quarkus_simple_openapi_null_collections_yaml.model.CloudEvent; 8 | import org.openapi.quarkus.quarkus_simple_openapi_null_collections_yaml.model.Link; 9 | 10 | import com.fasterxml.jackson.core.JsonProcessingException; 11 | import com.fasterxml.jackson.databind.ObjectMapper; 12 | 13 | import io.quarkus.test.junit.QuarkusTest; 14 | 15 | @QuarkusTest 16 | public class QuarkusInitialiseEmptyCollectionWhenFalseTest { 17 | 18 | @Inject 19 | ObjectMapper objectMapper; 20 | 21 | @Test 22 | void when_initialize_empty_collections_is_false_then_should_not_initialize_collections() { 23 | var cloudEvent = new CloudEvent(); 24 | Assertions.assertThat(cloudEvent.getAttributeNames()).isNull(); 25 | var link = new Link(); 26 | Assertions.assertThat(link.getRels()).isNull(); 27 | } 28 | 29 | @Test 30 | void when_initialize_empty_collections_is_false_then_jackson_should_map_collections_correctly() 31 | throws JsonProcessingException { 32 | Assertions.assertThat(objectMapper.writeValueAsString(new Link())) 33 | .isEqualTo("{}"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /client/integration-tests/multipart-request/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.multipart_requests_yml.base-package=org.acme.openapi.multipart 2 | quarkus.openapi-generator.codegen.spec.multipart_requests_yml.additional-model-type-annotations=@io.quarkus.runtime.annotations.RegisterForReflection 3 | # By default the openapi-generator doesn't generate models for multipart requests 4 | quarkus.openapi-generator.codegen.spec.multipart_requests_yml.skip-form-model=false 5 | 6 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/mutiny/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.rest-client.quarkus_simple_openapi_yaml.url=http://localhost:8080 2 | quarkus.openapi-generator.codegen.spec.quarkus_simple_openapi_yaml.mutiny=true 3 | 4 | quarkus.openapi-generator.codegen.spec.quarkus_multiple_endpoints_openapi_yaml.mutiny=true 5 | quarkus.openapi-generator.codegen.spec.quarkus_multiple_endpoints_openapi_yaml.mutiny.operation-ids.testEndpoint1=Multi 6 | quarkus.openapi-generator.codegen.spec.quarkus_multiple_endpoints_openapi_yaml.mutiny.operation-ids.testEndpoint2=Uni 7 | 8 | quarkus.openapi-generator.codegen.spec.quarkus_multiple_endpoints_wrong_configuration_openapi_yaml.mutiny=true 9 | quarkus.openapi-generator.codegen.spec.quarkus_multiple_endpoints_wrong_configuration_openapi_yaml.mutiny.operation-ids.testEndpoint1=Multi 10 | quarkus.openapi-generator.codegen.spec.quarkus_multiple_endpoints_wrong_configuration_openapi_yaml.mutiny.operation-ids.testEndpoint2=Uni 11 | quarkus.openapi-generator.codegen.spec.quarkus_multiple_endpoints_wrong_configuration_openapi_yaml.mutiny.operation-ids.testEndpoint3=Umi 12 | 13 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/open-api-normalizer/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.open_api_normalizer_json.base-package=org.acme.openapi.animals 2 | quarkus.openapi-generator.codegen.spec.open_api_normalizer_json.type-mappings.DateTime=Instant 3 | quarkus.openapi-generator.codegen.spec.open_api_normalizer_json.import-mappings.Instant=java.time.Instant 4 | quarkus.openapi-generator.codegen.spec.open_api_normalizer_json.open-api-normalizer.REF_AS_PARENT_IN_ALLOF=true 5 | 6 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/open-api-normalizer/src/test/java/io/quarkiverse/openapi/generator/it/QuarkusOpenApiNormalizerTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import jakarta.inject.Inject; 6 | 7 | import org.acme.openapi.animals.api.PrimateApi; 8 | import org.acme.openapi.animals.model.Primate; 9 | import org.eclipse.microprofile.rest.client.inject.RestClient; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import io.quarkus.test.common.QuarkusTestResource; 13 | import io.quarkus.test.junit.QuarkusTest; 14 | 15 | @QuarkusTest 16 | @QuarkusTestResource(WiremockTestResource.class) 17 | class QuarkusOpenApiNormalizerTest { 18 | 19 | @RestClient 20 | @Inject 21 | PrimateApi api; 22 | 23 | @Test 24 | void primateHasAllFields() { 25 | Primate primate = api.getPrimateById(1L); 26 | 27 | assertThat(primate).isNotNull(); 28 | assertThat(primate.getId()).isEqualTo(1L); 29 | assertThat(primate.getName()).isEqualTo("Jane Doe"); 30 | assertThat(primate.getBorn()).isNotNull(); 31 | assertThat(primate.getDeceased()).isNotNull(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /client/integration-tests/open-api-normalizer/src/test/resources/primate.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "born": "1970-01-01T01:01:01.001Z", 4 | "deceased": "2020-01-01T01:01:01.001Z", 5 | "name": "Jane Doe", 6 | "gender": "female" 7 | } -------------------------------------------------------------------------------- /client/integration-tests/override-credential-provider/src/main/java/io/quarkiverse/openapi/generator/it/creds/CustomCredentialsProvider.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it.creds; 2 | 3 | import jakarta.annotation.Priority; 4 | import jakarta.enterprise.context.Dependent; 5 | import jakarta.enterprise.inject.Alternative; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import io.quarkiverse.openapi.generator.providers.ConfigCredentialsProvider; 11 | import io.quarkiverse.openapi.generator.providers.CredentialsContext; 12 | 13 | @Dependent 14 | @Alternative 15 | @Priority(200) 16 | public class CustomCredentialsProvider extends ConfigCredentialsProvider { 17 | private static final Logger LOGGER = LoggerFactory.getLogger(CustomCredentialsProvider.class); 18 | 19 | public static String TOKEN = "FIXED_TEST_TOKEN"; 20 | 21 | @Override 22 | public String getBearerToken(CredentialsContext input) { 23 | LOGGER.info("========> getBearerToken from CustomCredentialsProvider"); 24 | return TOKEN; 25 | } 26 | } -------------------------------------------------------------------------------- /client/integration-tests/override-credential-provider/src/main/openapi/simple-server.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Simple server API 4 | description: |- 5 | Simple server API 6 | version: 1.0.0 7 | tags: 8 | - name: Simple server API 9 | description: Simple server API 10 | servers: 11 | - url: / 12 | paths: 13 | /simple: 14 | get: 15 | summary: Send requests to simple server with simple JWT security scheme 16 | description: Send requests to simple server to check the auth header 17 | operationId: getWithSimpleBearerTokenSecurityScheme 18 | responses: 19 | "200": 20 | description: Successful operation 21 | security: 22 | - SimpleBearerToken: [] 23 | components: 24 | securitySchemes: 25 | SimpleBearerToken: 26 | type: http 27 | scheme: bearer -------------------------------------------------------------------------------- /client/integration-tests/override-credential-provider/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.simple_server_yaml.auth.SimpleBearerToken.header-name=X-Authorization-Simple 2 | # We have a custom CredentialsProvider that will ignore this token set in the config and will return a hard-coded one. 3 | quarkus.openapi-generator.simple_server_yaml.auth.SimpleBearerToken.bearer-token=WILL_BE_OVERRIDED -------------------------------------------------------------------------------- /client/integration-tests/part-filename/src/test/java/io/quarkiverse/openapi/generator/it/PartFilenameRestEasyClassicTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertNotNull; 5 | import static org.junit.jupiter.api.Assertions.assertNull; 6 | 7 | import java.lang.reflect.Field; 8 | 9 | import jakarta.ws.rs.core.MediaType; 10 | 11 | import org.jboss.resteasy.annotations.providers.multipart.PartFilename; 12 | import org.jboss.resteasy.annotations.providers.multipart.PartType; 13 | import org.junit.jupiter.api.Tag; 14 | 15 | import io.quarkus.test.junit.QuarkusTest; 16 | 17 | @QuarkusTest 18 | @Tag("resteasy-classic") 19 | class PartFilenameRestEasyClassicTest extends BasePartFilenameTest { 20 | 21 | @Override 22 | protected void testPartTypeAnnotation(Field field) { 23 | var partType = field.getAnnotation(PartType.class); 24 | assertNotNull(partType); 25 | assertEquals(MediaType.APPLICATION_OCTET_STREAM, partType.value()); 26 | } 27 | 28 | @Override 29 | protected void testPartFilenameAnnotation(Field field, boolean present, String value) { 30 | var partFilename = field.getAnnotation(PartFilename.class); 31 | if (present) { 32 | assertNotNull(partFilename); 33 | if (value != null) { 34 | assertEquals(value, partFilename.value()); 35 | } 36 | } else { 37 | assertNull(partFilename); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /client/integration-tests/part-filename/src/test/java/io/quarkiverse/openapi/generator/it/PartFilenameRestEasyReactiveTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertNotNull; 5 | import static org.junit.jupiter.api.Assertions.assertNull; 6 | 7 | import java.lang.reflect.Field; 8 | 9 | import jakarta.ws.rs.core.MediaType; 10 | 11 | import org.jboss.resteasy.reactive.PartFilename; 12 | import org.jboss.resteasy.reactive.PartType; 13 | import org.junit.jupiter.api.Tag; 14 | 15 | import io.quarkus.test.junit.QuarkusTest; 16 | 17 | @QuarkusTest 18 | @Tag("resteasy-reactive") 19 | class PartFilenameRestEasyReactiveTest extends BasePartFilenameTest { 20 | 21 | @Override 22 | protected void testPartTypeAnnotation(Field field) { 23 | var partType = field.getAnnotation(PartType.class); 24 | assertNotNull(partType); 25 | assertEquals(MediaType.APPLICATION_OCTET_STREAM, partType.value()); 26 | } 27 | 28 | @Override 29 | protected void testPartFilenameAnnotation(Field field, boolean present, String value) { 30 | var partFilename = field.getAnnotation(PartFilename.class); 31 | if (present) { 32 | assertNotNull(partFilename); 33 | if (value != null) { 34 | assertEquals(value, partFilename.value()); 35 | } 36 | } else { 37 | assertNull(partFilename); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /client/integration-tests/path/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.rest-client.quarkus_simple_openapi_yaml.url=http://localhost:8080 2 | -------------------------------------------------------------------------------- /client/integration-tests/polymorphism/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/remove-operationid-prefix/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.rest-client.quarkus_simple_openapi_yaml.url=http://localhost:8080 2 | 3 | quarkus.openapi-generator.codegen.spec.openapi_remove_operation_id_prefix_yaml.remove-operation-id-prefix=true 4 | 5 | quarkus.openapi-generator.codegen.spec.openapi_prefix_delimiter_yaml.remove-operation-id-prefix=true 6 | quarkus.openapi-generator.codegen.spec.openapi_prefix_delimiter_yaml.remove-operation-id-prefix-delimiter=. 7 | 8 | quarkus.openapi-generator.codegen.spec.openapi_prefix_count_yaml.remove-operation-id-prefix=true 9 | quarkus.openapi-generator.codegen.spec.openapi_prefix_count_yaml.remove-operation-id-prefix-delimiter=. 10 | quarkus.openapi-generator.codegen.spec.openapi_prefix_count_yaml.remove-operation-id-prefix-count=3 11 | -------------------------------------------------------------------------------- /client/integration-tests/return-response/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.return_response_false_string_simple_openapi_yaml.base-package = org.acme.openapi 2 | quarkus.openapi-generator.codegen.spec.return_response_false_void_simple_openapi_yaml.base-package = org.acme.openapi 3 | quarkus.openapi-generator.codegen.spec.return_response_true_string_simple_openapi_yaml.base-package = org.acme.openapi 4 | quarkus.openapi-generator.codegen.spec.return_response_true_void_simple_openapi_yaml.base-package = org.acme.openapi 5 | 6 | quarkus.openapi-generator.codegen.spec.return_response_false_string_simple_openapi_yaml.return-response = false 7 | quarkus.openapi-generator.codegen.spec.return_response_false_void_simple_openapi_yaml.return-response = false 8 | quarkus.openapi-generator.codegen.spec.return_response_true_string_simple_openapi_yaml.return-response = true 9 | quarkus.openapi-generator.codegen.spec.return_response_true_void_simple_openapi_yaml.return-response = true 10 | 11 | quarkus.openapi-generator.codegen.spec.return_response_false_string_simple_openapi_yaml.mutiny = false 12 | quarkus.openapi-generator.codegen.spec.return_response_false_void_simple_openapi_yaml.mutiny = false 13 | quarkus.openapi-generator.codegen.spec.return_response_true_string_simple_openapi_yaml.mutiny = false 14 | quarkus.openapi-generator.codegen.spec.return_response_true_void_simple_openapi_yaml.mutiny = false 15 | 16 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/security/src/main/java/io/quarkiverse/openapi/generator/it/security/auth/DummyApiKeyAuthenticationProvider.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it.security.auth; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import jakarta.annotation.PostConstruct; 7 | import jakarta.annotation.Priority; 8 | import jakarta.ws.rs.Priorities; 9 | import jakarta.ws.rs.client.ClientRequestContext; 10 | import jakarta.ws.rs.client.ClientRequestFilter; 11 | 12 | import io.quarkiverse.openapi.generator.providers.ApiKeyAuthenticationProvider; 13 | import io.quarkiverse.openapi.generator.providers.ApiKeyIn; 14 | import io.quarkiverse.openapi.generator.providers.AuthProvider; 15 | import io.quarkiverse.openapi.generator.providers.ConfigCredentialsProvider; 16 | 17 | @Priority(Priorities.AUTHENTICATION) 18 | public class DummyApiKeyAuthenticationProvider implements ClientRequestFilter { 19 | 20 | private AuthProvider authProvider; 21 | 22 | @PostConstruct 23 | public void init() { 24 | authProvider = new ApiKeyAuthenticationProvider("open_weather_custom_security_yaml", "app_id", ApiKeyIn.query, "appid", 25 | List.of(), new ConfigCredentialsProvider()); 26 | } 27 | 28 | @Override 29 | public final void filter(ClientRequestContext requestContext) throws IOException { 30 | authProvider.filter(requestContext); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /client/integration-tests/security/src/main/openapi/token-propagation-external-service1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: token-propagation-external-service1 API 5 | version: 3.0.0-SNAPSHOT 6 | paths: 7 | /token-propagation-external-service1/executeQuery1: 8 | post: 9 | operationId: executeQuery1 10 | responses: 11 | "200": 12 | description: OK 13 | security: 14 | - service1-http-bearer: [] 15 | components: 16 | securitySchemes: 17 | service1-http-bearer: 18 | type: http 19 | scheme: bearer -------------------------------------------------------------------------------- /client/integration-tests/security/src/main/openapi/token-propagation-external-service2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: external-service2 API 5 | version: 3.0.0-SNAPSHOT 6 | paths: 7 | /token-propagation-external-service2/executeQuery2: 8 | post: 9 | operationId: executeQuery2 10 | responses: 11 | "200": 12 | description: OK 13 | security: 14 | - service2-oauth2: [] 15 | components: 16 | securitySchemes: 17 | service2-oauth2: 18 | type: oauth2 19 | flows: 20 | clientCredentials: 21 | authorizationUrl: https://example.com/oauth 22 | tokenUrl: https://example.com/oauth/token 23 | scopes: {} -------------------------------------------------------------------------------- /client/integration-tests/security/src/main/openapi/token-propagation-external-service3.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: token-propagation-external-service3 API 5 | version: 3.0.0-SNAPSHOT 6 | paths: 7 | /token-propagation-external-service3/executeQuery3: 8 | post: 9 | operationId: executeQuery3 10 | responses: 11 | "200": 12 | description: OK 13 | security: 14 | - service3-http-bearer: [] 15 | components: 16 | securitySchemes: 17 | service3-http-bearer: 18 | type: http 19 | scheme: bearer -------------------------------------------------------------------------------- /client/integration-tests/security/src/main/openapi/token-propagation-external-service4.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: external-service4 API 5 | version: 3.0.0-SNAPSHOT 6 | paths: 7 | /token-propagation-external-service4/executeQuery4: 8 | post: 9 | operationId: executeQuery4 10 | responses: 11 | "200": 12 | description: OK 13 | security: 14 | - service4-oauth2: [] 15 | components: 16 | securitySchemes: 17 | service4-oauth2: 18 | type: oauth2 19 | flows: 20 | clientCredentials: 21 | authorizationUrl: https://example.com/oauth 22 | tokenUrl: https://example.com/oauth/token 23 | scopes: {} -------------------------------------------------------------------------------- /client/integration-tests/security/src/main/openapi/token-propagation-external-service5.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | openapi: 3.0.3 3 | info: 4 | title: external-service5 API 5 | version: 3.0.0-SNAPSHOT 6 | paths: 7 | /token-propagation-external-service5/executeQuery5: 8 | post: 9 | operationId: executeQuery5 10 | responses: 11 | "200": 12 | description: OK 13 | security: 14 | - service5-oauth2: [] 15 | components: 16 | securitySchemes: 17 | service5-oauth2: 18 | type: oauth2 19 | flows: 20 | clientCredentials: 21 | authorizationUrl: https://example.com/oauth 22 | tokenUrl: https://example.com/oauth/token 23 | scopes: {} -------------------------------------------------------------------------------- /client/integration-tests/serializable-model/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.quarkus_serializable_openapi_yaml.serializable-model=true 2 | quarkus.openapi-generator.codegen.spec.quarkus_serializable_openapi_yaml.base-package=org.acme.serializable 3 | 4 | quarkus.openapi-generator.codegen.spec.quarkus_non_serializable_openapi_yaml.base-package=org.acme.non.serializable 5 | 6 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/serializable-model/src/test/java/io/quarkiverse/openapi/generator/it/SerializableModelTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import java.io.Serializable; 6 | 7 | import org.junit.jupiter.api.Test; 8 | 9 | import io.quarkus.test.junit.QuarkusTest; 10 | 11 | @QuarkusTest 12 | class SerializableModelTest { 13 | 14 | @Test 15 | void verifySerializableIsEnabled() { 16 | var interfaces = org.acme.serializable.model.Animal.class.getInterfaces(); 17 | 18 | assertThat(interfaces).contains(Serializable.class); 19 | } 20 | 21 | @Test 22 | void verifySerializableIsNotEnabled() { 23 | var interfaces = org.acme.non.serializable.model.Animal.class.getInterfaces(); 24 | 25 | assertThat(interfaces).doesNotContain(Serializable.class); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /client/integration-tests/simple/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.rest-client.quarkus_simple_openapi_yaml.url=http://localhost:8080 2 | 3 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/simple/src/test/java/io/quarkiverse/openapi/generator/it/QuarkusSimpleOpenApiTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import jakarta.inject.Inject; 6 | 7 | import org.eclipse.microprofile.rest.client.inject.RestClient; 8 | import org.junit.jupiter.api.Test; 9 | import org.openapi.quarkus.quarkus_simple_openapi_yaml.api.ReactiveGreetingResourceApi; 10 | 11 | import io.quarkus.test.junit.QuarkusTest; 12 | 13 | @QuarkusTest 14 | class QuarkusSimpleOpenApiTest { 15 | 16 | @RestClient 17 | @Inject 18 | ReactiveGreetingResourceApi api; 19 | 20 | @Test 21 | void apiIsBeingGenerated() { 22 | assertThat(api).isNotNull(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/integration-tests/skip-validation/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.validateSpec=false 2 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/skip-validation/src/test/java/io/quarkiverse/openapi/generator/it/AWXTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; 4 | import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; 5 | import static org.junit.jupiter.api.Assertions.assertNotNull; 6 | 7 | import jakarta.inject.Inject; 8 | 9 | import org.eclipse.microprofile.config.inject.ConfigProperty; 10 | import org.eclipse.microprofile.rest.client.inject.RestClient; 11 | import org.junit.jupiter.api.Test; 12 | import org.openapi.quarkus.awx_json.api.JobTemplatesApi; 13 | import org.openapi.quarkus.awx_json.model.JobTemplatesJobTemplatesLaunchCreateRequest; 14 | 15 | import com.github.tomakehurst.wiremock.WireMockServer; 16 | 17 | import io.quarkus.test.common.QuarkusTestResource; 18 | import io.quarkus.test.junit.QuarkusTest; 19 | 20 | @QuarkusTestResource(WiremockAWX.class) 21 | @QuarkusTest 22 | public class AWXTest { 23 | 24 | // injected by quarkus test resource 25 | WireMockServer awxServer; 26 | 27 | @ConfigProperty(name = WiremockAWX.URL_KEY) 28 | String awxUrl; 29 | 30 | @RestClient 31 | @Inject 32 | JobTemplatesApi jobsApi; 33 | 34 | @Test 35 | public void verifyAWXApi() { 36 | jobsApi.jobTemplatesJobTemplatesLaunchCreate("7", new JobTemplatesJobTemplatesLaunchCreateRequest()); 37 | assertNotNull(awxUrl); 38 | awxServer.verify(postRequestedFor(urlEqualTo("/api/v2/job_templates/7/launch/"))); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /client/integration-tests/suffix-prefix/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.rest-client.quarkus_suffix_prefix_openapi_yaml.url=http://localhost:8080 2 | quarkus.openapi-generator.codegen.spec.quarkus_suffix_prefix_openapi_yaml.api-name-suffix=CustomApiSuffix 3 | quarkus.openapi-generator.codegen.spec.quarkus_suffix_prefix_openapi_yaml.model-name-suffix=CustomModelSuffix 4 | quarkus.openapi-generator.codegen.spec.quarkus_suffix_prefix_openapi_yaml.model-name-prefix=CustomModelPrefix 5 | 6 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/suffix-prefix/src/test/java/io/quarkiverse/openapi/generator/it/QuarkusSuffixPrefixOpenApiTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThatCode; 4 | 5 | import org.junit.jupiter.params.ParameterizedTest; 6 | import org.junit.jupiter.params.provider.ValueSource; 7 | 8 | class QuarkusSuffixPrefixOpenApiTest { 9 | @ParameterizedTest 10 | @ValueSource(strings = { 11 | "org.openapi.quarkus.quarkus_suffix_prefix_openapi_yaml.api.ReactiveGreetingResourceCustomApiSuffix", 12 | "org.openapi.quarkus.quarkus_suffix_prefix_openapi_yaml.model.CustomModelPrefixLinkCustomModelSuffix" 13 | }) 14 | void apiIsBeingGenerated(String className) { 15 | assertThatCode(() -> Class.forName(className)) 16 | .doesNotThrowAnyException(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /client/integration-tests/type-mapping/src/main/java/io/quarkiverse/openapi/generator/it/type/mapping/OffsetDateTimeParamConverter.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it.type.mapping; 2 | 3 | import java.time.OffsetDateTime; 4 | 5 | import jakarta.ws.rs.ext.ParamConverter; 6 | 7 | public class OffsetDateTimeParamConverter implements ParamConverter { 8 | 9 | @Override 10 | public OffsetDateTime fromString(String value) { 11 | return value == null ? null : OffsetDateTime.parse(value); 12 | } 13 | 14 | @Override 15 | public String toString(OffsetDateTime value) { 16 | return value == null ? null : value.toString(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /client/integration-tests/type-mapping/src/main/java/io/quarkiverse/openapi/generator/it/type/mapping/OffsetDateTimeParamConverterProvider.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it.type.mapping; 2 | 3 | import java.lang.annotation.Annotation; 4 | import java.lang.reflect.Type; 5 | import java.time.OffsetDateTime; 6 | 7 | import jakarta.ws.rs.ext.ParamConverter; 8 | import jakarta.ws.rs.ext.ParamConverterProvider; 9 | import jakarta.ws.rs.ext.Provider; 10 | 11 | @Provider 12 | public class OffsetDateTimeParamConverterProvider implements ParamConverterProvider { 13 | 14 | @Override 15 | public ParamConverter getConverter(Class rawType, Type genericType, Annotation[] annotations) { 16 | if (OffsetDateTime.class.equals(rawType)) { 17 | return (ParamConverter) new OffsetDateTimeParamConverter(); 18 | } 19 | return null; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /client/integration-tests/type-mapping/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.codegen.spec.type_mappings_testing_yml.type-mappings.UUID=String 2 | quarkus.openapi-generator.codegen.spec.type_mappings_testing_yml.type-mappings.File=InputStream 3 | quarkus.openapi-generator.codegen.spec.type_mappings_testing_yml.import-mappings.File=java.io.InputStream 4 | quarkus.openapi-generator.codegen.spec.type_mappings_testing_yml.schema-mappings.YearMonth=java.time.YearMonth 5 | quarkus.openapi-generator.codegen.spec.type_mappings_testing_yml.base-package=org.acme.openapi.typemapping 6 | quarkus.openapi-generator.codegen.spec.type_mappings_testing_yml.additional-api-type-annotations=@org.eclipse.microprofile.rest.client.annotation.RegisterProvider(io.quarkiverse.openapi.generator.it.type.mapping.OffsetDateTimeParamConverterProvider.class) 7 | 8 | quarkus.keycloak.devservices.enabled=false -------------------------------------------------------------------------------- /client/integration-tests/type-mapping/src/test/java/io/quarkiverse/openapi/generator/it/type/mapping/WiremockTypeAndImportMapping.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it.type.mapping; 2 | 3 | import static com.github.tomakehurst.wiremock.client.WireMock.*; 4 | 5 | import java.util.Collections; 6 | import java.util.Map; 7 | 8 | import com.github.tomakehurst.wiremock.WireMockServer; 9 | import com.github.tomakehurst.wiremock.core.WireMockConfiguration; 10 | 11 | import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; 12 | 13 | public class WiremockTypeAndImportMapping implements QuarkusTestResourceLifecycleManager { 14 | 15 | private WireMockServer wireMockServer; 16 | 17 | @Override 18 | public Map start() { 19 | wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort()); 20 | wireMockServer.start(); 21 | 22 | wireMockServer.stubFor(post(anyUrl()) 23 | .willReturn(aResponse().withStatus(204))); 24 | return Collections.singletonMap("org.acme.openapi.typemapping.api.TypeMappingApi/mp-rest/url", 25 | wireMockServer.baseUrl()); 26 | } 27 | 28 | @Override 29 | public void inject(TestInjector testInjector) { 30 | testInjector.injectIntoFields(wireMockServer, f -> f.getName().equals("typeMappingServer")); 31 | } 32 | 33 | @Override 34 | public void stop() { 35 | if (null != wireMockServer) { 36 | wireMockServer.stop(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /client/integration-tests/without-oidc/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.rest-client.quarkus_simple_openapi_yaml.url=http://localhost:8080 2 | -------------------------------------------------------------------------------- /client/integration-tests/without-oidc/src/test/java/io/quarkiverse/openapi/generator/it/QuarkusSimpleOpenApiTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.it; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import jakarta.inject.Inject; 6 | 7 | import org.eclipse.microprofile.rest.client.inject.RestClient; 8 | import org.junit.jupiter.api.Test; 9 | import org.openapi.quarkus.quarkus_simple_openapi_yaml.api.ReactiveGreetingResourceApi; 10 | 11 | import io.quarkus.test.junit.QuarkusTest; 12 | 13 | @QuarkusTest 14 | class QuarkusSimpleOpenApiTest { 15 | 16 | @RestClient 17 | @Inject 18 | ReactiveGreetingResourceApi api; 19 | 20 | @Test 21 | void apiIsBeingGenerated() { 22 | assertThat(api).isNotNull(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/oidc/src/main/java/io/quarkiverse/openapi/generator/oidc/OidcAuthenticationRecorder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.oidc; 2 | 3 | import java.util.List; 4 | import java.util.function.Function; 5 | 6 | import io.quarkiverse.openapi.generator.OidcClient; 7 | import io.quarkiverse.openapi.generator.oidc.providers.OAuth2AuthenticationProvider; 8 | import io.quarkiverse.openapi.generator.providers.AuthProvider; 9 | import io.quarkiverse.openapi.generator.providers.CredentialsProvider; 10 | import io.quarkiverse.openapi.generator.providers.OperationAuthInfo; 11 | import io.quarkus.arc.SyntheticCreationalContext; 12 | import io.quarkus.runtime.annotations.Recorder; 13 | 14 | @Recorder 15 | public class OidcAuthenticationRecorder { 16 | 17 | public Function, AuthProvider> recordOauthAuthProvider( 18 | String name, 19 | String openApiSpecId, 20 | List operations) { 21 | return context -> new OAuth2AuthenticationProvider(name, openApiSpecId, 22 | context.getInjectedReference(OAuth2AuthenticationProvider.OidcClientRequestFilterDelegate.class, 23 | new OidcClient.Literal(name)), 24 | operations, 25 | context.getInjectedReference(CredentialsProvider.class)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | quarkus-openapi-generator-parent 5 | io.quarkiverse.openapi.generator 6 | 3.0.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | quarkus-openapi-generator-client-parent 11 | Quarkus - OpenAPI Generator - Client - Parent 12 | pom 13 | 14 | 15 | deployment 16 | runtime 17 | test-utils 18 | oidc 19 | 20 | -------------------------------------------------------------------------------- /client/runtime/src/main/codestarts/quarkus/openapi-generator-codestart/codestart.yml: -------------------------------------------------------------------------------- 1 | name: openapi-generator-codestart 2 | ref: openapi-generator 3 | type: code 4 | tags: extension-codestart 5 | metadata: 6 | title: OpenAPI Generator Client Codestart 7 | description: Start to code with the OpenAPI Generator Client extension. 8 | related-guide-section: https://docs.quarkiverse.io/quarkus-openapi-generator/dev/client.html -------------------------------------------------------------------------------- /client/runtime/src/main/codestarts/quarkus/openapi-generator-codestart/java/README.tpl.qute.md: -------------------------------------------------------------------------------- 1 | {#include readme-header /} 2 | 3 | ## Requirements 4 | 5 | If you do not have added the `io.quarkus:quarkus-rest-client-jackson` or `io.quarkus:quarkus-rest-client-reactive-jackson` extension in your project, add it first: 6 | 7 | Remember, you just need to add one of them, depending on your needs. 8 | 9 | ### REST Client Jackson: 10 | 11 | Quarkus CLI: 12 | 13 | ```bash 14 | quarkus ext add io.quarkus:quarkus-rest-client-jackson 15 | ``` 16 | 17 | Maven: 18 | ```bash 19 | ./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-rest-client-jackson" 20 | ``` 21 | 22 | Gradle: 23 | 24 | ```bash 25 | ./gradlew addExtension --extensions="io.quarkus:quarkus-rest-client-jackson" 26 | ``` 27 | 28 | or 29 | 30 | ### REST Client Reactive Jackson: 31 | 32 | Quarkus CLI: 33 | 34 | ```bash 35 | quarkus ext add io.quarkus:quarkus-rest-client-reactive-jackson 36 | ``` 37 | 38 | Maven: 39 | 40 | ```bash 41 | ./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-rest-client-reactive-jackson" 42 | ``` 43 | 44 | Gradle: 45 | 46 | ```bash 47 | ./gradlew addExtension --extensions="io.quarkus:quarkus-rest-client-reactive-jackson" 48 | ``` -------------------------------------------------------------------------------- /client/runtime/src/main/codestarts/quarkus/openapi-generator-codestart/java/src/main/openapi/openapi.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Generated API 4 | version: "1.0" 5 | paths: 6 | /fruits: 7 | get: 8 | responses: 9 | 200: 10 | description: OK 11 | content: 12 | application/json: { } 13 | post: 14 | requestBody: 15 | content: 16 | application/json: 17 | schema: 18 | $ref: '#/components/schemas/Fruit' 19 | responses: 20 | 200: 21 | description: OK 22 | content: 23 | application/json: { } 24 | delete: 25 | requestBody: 26 | content: 27 | application/json: 28 | schema: 29 | $ref: '#/components/schemas/Fruit' 30 | responses: 31 | 200: 32 | description: OK 33 | content: 34 | application/json: { } 35 | components: 36 | schemas: 37 | Fruit: 38 | properties: 39 | description: 40 | type: string 41 | name: 42 | type: string -------------------------------------------------------------------------------- /client/runtime/src/main/codestarts/quarkus/openapi-generator-codestart/java/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | quarkus: 2 | openapi-generator: 3 | codegen: 4 | spec: 5 | openapi_yml: 6 | model-name-prefix: QuarkusOpenApiGenerator -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/AuthName.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.ElementType.PARAMETER; 6 | import static java.lang.annotation.ElementType.TYPE; 7 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 8 | 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.Target; 11 | 12 | import jakarta.inject.Qualifier; 13 | 14 | @Qualifier 15 | @Retention(RUNTIME) 16 | @Target({ METHOD, FIELD, PARAMETER, TYPE }) 17 | public @interface AuthName { 18 | 19 | String name(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/AuthsConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator; 2 | 3 | import java.util.Map; 4 | import java.util.Optional; 5 | 6 | import io.smallrye.config.WithParentName; 7 | 8 | public interface AuthsConfig { 9 | 10 | /** 11 | * Configurations for the individual securitySchemes present on a given OpenApi spec definition file. 12 | *

13 | * The key must be any of the sanitized names of the securitySchemes. 14 | * For example, given a file named petstore.json with a securityScheme named "petstore-auth", we have that the file 15 | * name is sanitized into the name petstore_json and the security scheme name is sanitized into the name 16 | * "petstore_auth". And thus, the specific configurations for this security scheme must start with the prefix 17 | * quarkus.openapi-generator.petstore_json.auth.petstore_auth 18 | * 19 | * @see SpecItemConfig 20 | * @see AuthConfig 21 | */ 22 | @WithParentName() 23 | Map authConfigs(); 24 | 25 | default Optional getItemConfig(String authConfig) { 26 | return Optional.ofNullable(authConfigs().get(authConfig)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/OidcClient.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.ElementType.PARAMETER; 6 | import static java.lang.annotation.ElementType.TYPE; 7 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 8 | 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.Target; 11 | 12 | import jakarta.enterprise.util.AnnotationLiteral; 13 | import jakarta.enterprise.util.Nonbinding; 14 | import jakarta.inject.Qualifier; 15 | 16 | @Qualifier 17 | @Retention(RUNTIME) 18 | @Target({ METHOD, FIELD, PARAMETER, TYPE }) 19 | public @interface OidcClient { 20 | 21 | String DEFAULT = "io.quarkiverse.openapi.generator.DEFAULT"; 22 | 23 | @Nonbinding 24 | String name() default DEFAULT; 25 | 26 | final class Literal extends AnnotationLiteral implements OidcClient { 27 | public Literal(String name) { 28 | this.name = name; 29 | } 30 | 31 | final String name; 32 | 33 | @Override 34 | public String name() { 35 | return name; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/OpenApiGeneratorException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator; 2 | 3 | public class OpenApiGeneratorException extends RuntimeException { 4 | 5 | public OpenApiGeneratorException(String message) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/OpenApiSpec.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.ElementType.PARAMETER; 6 | import static java.lang.annotation.ElementType.TYPE; 7 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 8 | 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.Target; 11 | 12 | import jakarta.enterprise.util.AnnotationLiteral; 13 | import jakarta.inject.Qualifier; 14 | 15 | @Qualifier 16 | @Retention(RUNTIME) 17 | @Target({ METHOD, FIELD, PARAMETER, TYPE }) 18 | public @interface OpenApiSpec { 19 | 20 | String openApiSpecId(); 21 | 22 | final class Literal extends AnnotationLiteral implements OpenApiSpec { 23 | public Literal(String openApiSpecId) { 24 | this.openApiSpecId = openApiSpecId; 25 | } 26 | 27 | final String openApiSpecId; 28 | 29 | @Override 30 | public String openApiSpecId() { 31 | return openApiSpecId; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/SpecItemConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator; 2 | 3 | import java.util.Optional; 4 | 5 | /** 6 | * This class represents the runtime authentication related configurations for the individual OpenApi spec definitions, 7 | * i.e. the provided files. 8 | */ 9 | public interface SpecItemConfig { 10 | 11 | /** 12 | * Authentication related configurations for the different securitySchemes present on a given OpenApi spec 13 | * definition file. 14 | *

15 | * For example, given a file named petstore.json, the following prefix must be used to configure the authentication 16 | * related information quarkus.openapi-generator.petstore_json.auth 17 | * 18 | * @see AuthsConfig 19 | */ 20 | AuthsConfig auth(); 21 | 22 | default Optional getAuth() { 23 | return Optional.ofNullable(auth()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/annotations/GeneratedClass.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.annotations; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.Target; 8 | 9 | @Retention(RUNTIME) 10 | @Target(TYPE) 11 | public @interface GeneratedClass { 12 | String value(); 13 | 14 | String tag() default ""; 15 | } 16 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/annotations/GeneratedMethod.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.annotations; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.Target; 8 | 9 | @Retention(RUNTIME) 10 | @Target(METHOD) 11 | public @interface GeneratedMethod { 12 | /** Operation id */ 13 | String value(); 14 | } 15 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/annotations/GeneratedParam.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.annotations; 2 | 3 | import static java.lang.annotation.ElementType.PARAMETER; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.Target; 8 | 9 | @Retention(RUNTIME) 10 | @Target(PARAMETER) 11 | public @interface GeneratedParam { 12 | String value(); 13 | } 14 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/markers/ApiKeyAuthenticationMarker.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.markers; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | 5 | import java.lang.annotation.Repeatable; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | import io.quarkiverse.openapi.generator.providers.ApiKeyIn; 11 | 12 | @Target(TYPE) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Repeatable(ApiKeyAuthenticationMarker.AuthenticationMarkers.class) 15 | public @interface ApiKeyAuthenticationMarker { 16 | 17 | String name(); 18 | 19 | String openApiSpecId(); 20 | 21 | ApiKeyIn apiKeyIn(); 22 | 23 | String apiKeyName(); 24 | 25 | @Target(TYPE) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @interface AuthenticationMarkers { 28 | ApiKeyAuthenticationMarker[] value(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/markers/BasicAuthenticationMarker.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.markers; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | 5 | import java.lang.annotation.Repeatable; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Target(TYPE) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Repeatable(BasicAuthenticationMarker.AuthenticationMarkers.class) 13 | public @interface BasicAuthenticationMarker { 14 | 15 | String name(); 16 | 17 | String openApiSpecId(); 18 | 19 | @Target(TYPE) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @interface AuthenticationMarkers { 22 | BasicAuthenticationMarker[] value(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/markers/BearerAuthenticationMarker.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.markers; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | 5 | import java.lang.annotation.Repeatable; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Target(TYPE) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Repeatable(BearerAuthenticationMarker.AuthenticationMarkers.class) 13 | public @interface BearerAuthenticationMarker { 14 | 15 | String name(); 16 | 17 | String openApiSpecId(); 18 | 19 | String scheme(); 20 | 21 | @Target(TYPE) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | @interface AuthenticationMarkers { 24 | BearerAuthenticationMarker[] value(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/markers/OauthAuthenticationMarker.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.markers; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | 5 | import java.lang.annotation.Repeatable; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Target(TYPE) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Repeatable(OauthAuthenticationMarker.AuthenticationMarkers.class) 13 | public @interface OauthAuthenticationMarker { 14 | 15 | String name(); 16 | 17 | String openApiSpecId(); 18 | 19 | @Target(TYPE) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @interface AuthenticationMarkers { 22 | OauthAuthenticationMarker[] value(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/markers/OperationMarker.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.markers; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | 5 | import java.lang.annotation.Repeatable; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Target(METHOD) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Repeatable(OperationMarker.OperationMarkers.class) 13 | public @interface OperationMarker { 14 | 15 | String name(); 16 | 17 | String openApiSpecId(); 18 | 19 | String operationId(); 20 | 21 | String path(); 22 | 23 | String method(); 24 | 25 | @Target(METHOD) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @interface OperationMarkers { 28 | OperationMarker[] value(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/ApiKeyIn.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.providers; 2 | 3 | /** 4 | * @see OpenAPI Spec - Security Scheme Object - Fixed Fields 5 | */ 6 | public enum ApiKeyIn { 7 | query, 8 | header, 9 | cookie; 10 | } 11 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/AuthProvider.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.providers; 2 | 3 | import java.util.List; 4 | 5 | import jakarta.ws.rs.client.ClientRequestFilter; 6 | 7 | /** 8 | * Authentication Provider for {@link ClientRequestFilter}s generated by the extension. 9 | */ 10 | public interface AuthProvider extends ClientRequestFilter { 11 | 12 | /** 13 | * Get the name of the Security Provider as defined in the OpenAPI Spec file. 14 | * 15 | * @see OpenAPI Spec - Security Requirement 16 | * Object 17 | */ 18 | String getName(); 19 | 20 | List operationsToFilter(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/AuthUtils.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.providers; 2 | 3 | import java.util.Base64; 4 | 5 | public final class AuthUtils { 6 | 7 | private static final String BASIC_HEADER_PREFIX = "Basic"; 8 | private static final String BEARER_HEADER_PREFIX = "Bearer"; 9 | 10 | private AuthUtils() { 11 | } 12 | 13 | public static String basicAuthAccessTokenWithoutPrefix(final String username, final String password) { 14 | return Base64.getEncoder().encodeToString(String.format("%s:%s", username, password).getBytes()); 15 | } 16 | 17 | public static String basicAuthAccessToken(final String basicToken) { 18 | return String.format("%s %s", 19 | BASIC_HEADER_PREFIX, 20 | basicToken); 21 | } 22 | 23 | public static String authTokenOrBearer(final String scheme, final String token) { 24 | if (scheme == null) { 25 | return token; 26 | } 27 | // forcing the right case 28 | if (BEARER_HEADER_PREFIX.equalsIgnoreCase(scheme)) { 29 | return String.format("%s %s", BEARER_HEADER_PREFIX, token); 30 | } 31 | return String.format("%s %s", scheme, token); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/DefaultHeadersProvider.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.providers; 2 | 3 | import jakarta.enterprise.context.ApplicationScoped; 4 | import jakarta.ws.rs.core.MultivaluedHashMap; 5 | import jakarta.ws.rs.core.MultivaluedMap; 6 | 7 | import io.quarkiverse.openapi.generator.OpenApiGeneratorConfig; 8 | import io.quarkus.arc.DefaultBean; 9 | 10 | @DefaultBean 11 | @ApplicationScoped 12 | public class DefaultHeadersProvider implements HeadersProvider { 13 | 14 | @Override 15 | public MultivaluedMap getStringHeaders(OpenApiGeneratorConfig generatorConfig) { 16 | return new MultivaluedHashMap<>(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /client/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/HeadersProvider.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.providers; 2 | 3 | import jakarta.ws.rs.core.MultivaluedMap; 4 | 5 | import io.quarkiverse.openapi.generator.OpenApiGeneratorConfig; 6 | 7 | public interface HeadersProvider { 8 | 9 | MultivaluedMap getStringHeaders(OpenApiGeneratorConfig generatorConfig); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /client/runtime/src/main/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-openapi-generator/aee8e52cac006bc1ee7a1e01775e2ad6cbbeac69/client/runtime/src/main/resources/META-INF/beans.xml -------------------------------------------------------------------------------- /client/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: "OpenAPI Generator - REST Client Generator" 2 | artifact: ${project.groupId}:${project.artifactId}:${project.version} 3 | metadata: 4 | keywords: 5 | - "openapi" 6 | - "openapi-generator" 7 | - "rest" 8 | - "rest-client" 9 | categories: 10 | - "web" 11 | guide: "https://docs.quarkiverse.io/quarkus-openapi-generator/dev/index.html" 12 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-openapi-generator/main/docs/modules/ROOT/assets/images/openapi.svg" 13 | status: "preview" 14 | codestart: 15 | name: "openapi-generator" 16 | languages: 17 | - "java" 18 | artifact: "io.quarkiverse.openapi.generator:quarkus-openapi-generator:codestarts:jar:${project.version}" 19 | -------------------------------------------------------------------------------- /client/runtime/src/test/java/io/quarkiverse/openapi/generator/providers/AbstractOpenApiSpecProviderTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.providers; 2 | 3 | import jakarta.ws.rs.client.ClientRequestContext; 4 | import jakarta.ws.rs.core.MultivaluedHashMap; 5 | import jakarta.ws.rs.core.MultivaluedMap; 6 | 7 | import org.assertj.core.api.Assertions; 8 | import org.junit.jupiter.api.BeforeEach; 9 | import org.junit.jupiter.api.extension.ExtendWith; 10 | import org.mockito.Mock; 11 | import org.mockito.Mockito; 12 | import org.mockito.junit.jupiter.MockitoExtension; 13 | 14 | @ExtendWith(MockitoExtension.class) 15 | abstract class AbstractOpenApiSpecProviderTest { 16 | 17 | protected static final String OPEN_API_FILE_SPEC_ID = "open_api_file_spec_id_json"; 18 | protected static final String AUTH_SCHEME_NAME = "auth_scheme_name"; 19 | 20 | @Mock 21 | protected ClientRequestContext requestContext; 22 | protected MultivaluedMap headers; 23 | 24 | protected T provider; 25 | 26 | @BeforeEach 27 | void setUp() { 28 | headers = new MultivaluedHashMap<>(); 29 | Mockito.lenient().doReturn(headers).when(requestContext).getHeaders(); 30 | provider = createProvider(); 31 | } 32 | 33 | protected abstract T createProvider(); 34 | 35 | protected void assertHeader(MultivaluedMap headers, String headerName, String value) { 36 | Assertions.assertThat(headers.getFirst(headerName)) 37 | .isNotNull() 38 | .isEqualTo(value); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /client/runtime/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi-generator.open_api_file_spec_id_json.auth.auth_scheme_name.api-key=API_KEY_VALUE 2 | quarkus.openapi-generator.open_api_file_spec_id_json.auth.auth_scheme_name.username=USER 3 | quarkus.openapi-generator.open_api_file_spec_id_json.auth.auth_scheme_name.password=PASSWORD 4 | quarkus.openapi-generator.open_api_file_spec_id_json.auth.auth_scheme_name.bearer-token=INCOMING_TOKEN -------------------------------------------------------------------------------- /client/test-utils/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | quarkus-openapi-generator-client-parent 6 | io.quarkiverse.openapi.generator 7 | 3.0.0-SNAPSHOT 8 | ../pom.xml 9 | 10 | quarkus-openapi-generator-test-utils 11 | Quarkus - OpenAPI Generator - Client - Test Utils 12 | 13 | 14 | 15 | com.github.javaparser 16 | javaparser-core 17 | compile 18 | 19 | 20 | org.assertj 21 | assertj-core 22 | compile 23 | 24 | 25 | org.wiremock 26 | wiremock 27 | 28 | 29 | io.quarkus 30 | quarkus-junit5 31 | 32 | 33 | org.awaitility 34 | awaitility 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/antora.yml: -------------------------------------------------------------------------------- 1 | name: quarkus-openapi-generator 2 | title: OpenAPI Generator 3 | version: dev 4 | nav: 5 | - modules/ROOT/nav.adoc 6 | -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/moqu-devui-card-framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-openapi-generator/aee8e52cac006bc1ee7a1e01775e2ad6cbbeac69/docs/modules/ROOT/assets/images/moqu-devui-card-framework.png -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/table-wiremock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-openapi-generator/aee8e52cac006bc1ee7a1e01775e2ad6cbbeac69/docs/modules/ROOT/assets/images/table-wiremock.png -------------------------------------------------------------------------------- /docs/modules/ROOT/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:client.adoc[Client Generator] 2 | * xref:server.adoc[Server Generator] 3 | * xref:moqu.adoc[Moqu Wiremock Generator] -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/additional-properties-as-attribute.adoc: -------------------------------------------------------------------------------- 1 | In some cases is necessary to use https://swagger.io/docs/specification/data-models/dictionaries/[additionalProperties] inside the OpenAPI specification, by default this extension creates an object that inherits a `java.util.HashMap` 2 | class. It works well, but there are some issues with Jackson on serialize/deserialize: 3 | 4 | - Serialization throws `com.fasterxml.jackson.databind.exc.MismatchedInputException` exception. 5 | - Deserialization `Jackson` does ignore plain fields. 6 | 7 | If you want to use composition instead inheritance and serialize/deserialize with Jackson without those problems, consider to configure the `additional-properties-as-attributes`. 8 | 9 | To map `additionalProperties` as attribute, add the following entry to your properties file. In this example, our spec file is in `src/main/openapi/petstore.json`: 10 | 11 | ---- 12 | quarkus.openapi-generator.codegen.spec.petstore_json.additional-properties-as-attribute=true 13 | ---- 14 | 15 | This configuration implies that all models using `additionalProperties` will be mapped using a `java.util.Map` as composition. -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/additional-request-args.adoc: -------------------------------------------------------------------------------- 1 | To add custom request specific parameters you can use the `additional-request-args` property. 2 | 3 | Should work with: 4 | 5 | * @PathParam 6 | * @QueryParam 7 | * @CookieParam 8 | * @FormParam 9 | * @MatrixParam 10 | 11 | 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`: 12 | 13 | ---- 14 | quarkus.openapi-generator.codegen.spec.petstore_json.additional-request-args=@CookieParam("cookie") String cookie;@HeaderParam("x-correlation-id") String correlationId 15 | ---- 16 | 17 | This configuration is applied to every generated method. -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/attributes.adoc: -------------------------------------------------------------------------------- 1 | :project-version: 2.10.0 2 | 3 | :examples-dir: ./../examples/ 4 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/bean-validation.adoc: -------------------------------------------------------------------------------- 1 | To enable bean validation support for validation properties specified in OpenApi. 2 | 3 | - @Valid 4 | - @Size 5 | - @Min 6 | - @Pattern 7 | - etc. 8 | 9 | == Example 10 | 11 | Given you want to validate parameters of components from `my-openapi.yaml` file, you must add the following to your `application.properties` file: 12 | 13 | [source,properties] 14 | ---- 15 | quarkus.openapi-generator.codegen.spec.my_openapi_yaml.use-bean-validation=true 16 | ---- -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/dynamic-url.adoc: -------------------------------------------------------------------------------- 1 | 2 | If you need the generated `RestClient` to target different server URLs at runtime—rather than relying solely on the static URL from the application configuration—you can enable dynamic base URL support. 3 | 4 | To do so, set the following property in your configuration: 5 | 6 | [source,properties] 7 | ---- 8 | quarkus.openapi-generator.codegen.spec.my_openapi_yaml.use-dynamic-url=true 9 | ---- 10 | 11 | When this property is enabled and `quarkus-rest-client` is present on the classpath, the generator will include a method parameter annotated with `@io.quarkus.rest.client.reactive.Url`. This allows your application to supply the target URL dynamically at runtime. 12 | 13 | This feature is particularly useful when integrating with multiple instances of the same API or switching endpoints based on contextual information. 14 | 15 | For more details, refer to the official Quarkus documentation: 16 | https://quarkus.io/version/3.20/guides/rest-client#dynamic-base-urls 17 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/equals-hashcode.adoc: -------------------------------------------------------------------------------- 1 | By default, `hashcode` and `equals` methods are automatically generated for all models. These methods are based on all the variables in the model and can not be customized. 2 | 3 | To disable set `equals-hashcode` to false: 4 | 5 | [source,properties] 6 | ---- 7 | quarkus.openapi-generator.codegen.spec.my_openapi_yaml.equals-hashcode=false 8 | ---- -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/filter-openapi-spec-files.adoc: -------------------------------------------------------------------------------- 1 | 2 | By default, the extension will process every OpenAPI specification file in the given path. 3 | To limit code generation to only a specific set of OpenAPI specification files, you can set the `quarkus.openapi-generator.codegen.include` property. 4 | 5 | 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: 6 | 7 | [source,properties] 8 | ---- 9 | quarkus.openapi-generator.codegen.include=include-openapi.yaml,include-openapi-2.yaml 10 | ---- 11 | 12 | If you prefer to specify which files you want to skip, you can set the `quarkus.openapi-generator.codegen.exclude` property. 13 | 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: 14 | 15 | [source,properties] 16 | ---- 17 | quarkus.openapi-generator.codegen.exclude=exclude-openapi.yaml,exclude-openapi-2.yaml 18 | ---- 19 | 20 | IMPORTANT: `exclude` supersedes `include`, meaning that if a file is in both property it will NOT be analysed. 21 | 22 | See the module `integration-tests/ignore` for an example of how to use this feature. -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/generate-apis.adoc: -------------------------------------------------------------------------------- 1 | APIs are generated by default. To disable them set `generate-apis` to false: 2 | 3 | [source,properties] 4 | ---- 5 | quarkus.openapi-generator.codegen.spec.my_openapi_yaml.generate-apis=false 6 | ---- -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/generate-models.adoc: -------------------------------------------------------------------------------- 1 | Models are generated by default. To disable them set `generate-models` to false: 2 | 3 | [source,properties] 4 | ---- 5 | quarkus.openapi-generator.codegen.spec.my_openapi_yaml.generate-models=false 6 | ---- -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/initialize-empty-collections.adoc: -------------------------------------------------------------------------------- 1 | In the default configuration, the generated RestClient is designed to set container types (e.g., lists, maps, or other collections) to null when no data is provided by the API. 2 | 3 | However, if you prefer container types to default to empty values instead (e.g., an empty list or map), you can override the default behavior by setting the following property in your configuration: 4 | 5 | [source,properties] 6 | quarkus.openapi-generator.codegen.spec.my_openapi_yaml.initialize-empty-collections=true 7 | 8 | When this property is set to true, the generator will ensure that container types are initialized with empty values instead of null, allowing you to avoid null-checks and directly work with populated collections. 9 | This feature is particularly useful when you expect the generated code to follow a defensive programming approach, or when dealing with APIs that always expect empty containers instead of null values. -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/logging.adoc: -------------------------------------------------------------------------------- 1 | Since the most part of this extension work is in the `generate-code` execution phase of the Quarkus Maven's plugin, the log configuration must be set in the Maven context. When building your project, add `-Dorg.slf4j.simpleLogger.log.org.openapitools=off` to the `mvn` command to reduce the internal generator noise. For example: 2 | 3 | [source,shell] 4 | ---- 5 | mvn clean install -Dorg.slf4j.simpleLogger.log.org.openapitools=off 6 | ---- 7 | 8 | For more information, see the https://maven.apache.org/maven-logging.html[Maven Logging Configuration] and https://maven.apache.org/configure.html[Maven Configuration] guides. 9 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/quarkus-openapi-generator-moqu-wiremock.adoc: -------------------------------------------------------------------------------- 1 | [.configuration-legend] 2 | icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime 3 | [.configuration-reference.searchable, cols="80,.^10,.^10"] 4 | |=== 5 | 6 | h|[.header-title]##Configuration property## 7 | h|Type 8 | h|Default 9 | 10 | a|icon:lock[title=Fixed at build time] [[quarkus-openapi-generator-moqu-wiremock_quarkus-openapi-generator-moqu-resource-dir]] [.property-path]##link:#quarkus-openapi-generator-moqu-wiremock_quarkus-openapi-generator-moqu-resource-dir[`quarkus.openapi-generator.moqu.resource-dir`]## 11 | ifdef::add-copy-button-to-config-props[] 12 | config_property_copy_button:+++quarkus.openapi-generator.moqu.resource-dir+++[] 13 | endif::add-copy-button-to-config-props[] 14 | 15 | 16 | [.description] 17 | -- 18 | Path to the Moqu (relative to the project). 19 | 20 | 21 | ifdef::add-copy-button-to-env-var[] 22 | Environment variable: env_var_with_copy_button:+++QUARKUS_OPENAPI_GENERATOR_MOQU_RESOURCE_DIR+++[] 23 | endif::add-copy-button-to-env-var[] 24 | ifndef::add-copy-button-to-env-var[] 25 | Environment variable: `+++QUARKUS_OPENAPI_GENERATOR_MOQU_RESOURCE_DIR+++` 26 | endif::add-copy-button-to-env-var[] 27 | -- 28 | |string 29 | |`openapi` 30 | 31 | |=== 32 | 33 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/quarkus-openapi-generator-moqu-wiremock_quarkus.adoc: -------------------------------------------------------------------------------- 1 | [.configuration-legend] 2 | icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime 3 | [.configuration-reference.searchable, cols="80,.^10,.^10"] 4 | |=== 5 | 6 | h|[.header-title]##Configuration property## 7 | h|Type 8 | h|Default 9 | 10 | a|icon:lock[title=Fixed at build time] [[quarkus-openapi-generator-moqu-wiremock_quarkus-resource-dir]] [.property-path]##link:#quarkus-openapi-generator-moqu-wiremock_quarkus-resource-dir[`quarkus.resource-dir`]## 11 | ifdef::add-copy-button-to-config-props[] 12 | config_property_copy_button:+++quarkus.resource-dir+++[] 13 | endif::add-copy-button-to-config-props[] 14 | 15 | 16 | [.description] 17 | -- 18 | Path to the Moqu (relative to the project). 19 | 20 | 21 | ifdef::add-copy-button-to-env-var[] 22 | Environment variable: env_var_with_copy_button:+++QUARKUS_RESOURCE_DIR+++[] 23 | endif::add-copy-button-to-env-var[] 24 | ifndef::add-copy-button-to-env-var[] 25 | Environment variable: `+++QUARKUS_RESOURCE_DIR+++` 26 | endif::add-copy-button-to-env-var[] 27 | -- 28 | |string 29 | |`openapi` 30 | 31 | |=== 32 | 33 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/quarkus-openapi-generator-moqu-wiremock_quarkus.openapi-generator.adoc: -------------------------------------------------------------------------------- 1 | [.configuration-legend] 2 | icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime 3 | [.configuration-reference.searchable, cols="80,.^10,.^10"] 4 | |=== 5 | 6 | h|[.header-title]##Configuration property## 7 | h|Type 8 | h|Default 9 | 10 | a|icon:lock[title=Fixed at build time] [[quarkus-openapi-generator-moqu-wiremock_quarkus-openapi-generator-moqu-resource-dir]] [.property-path]##link:#quarkus-openapi-generator-moqu-wiremock_quarkus-openapi-generator-moqu-resource-dir[`quarkus.openapi-generator.moqu.resource-dir`]## 11 | ifdef::add-copy-button-to-config-props[] 12 | config_property_copy_button:+++quarkus.openapi-generator.moqu.resource-dir+++[] 13 | endif::add-copy-button-to-config-props[] 14 | 15 | 16 | [.description] 17 | -- 18 | Path to the Moqu (relative to the project). 19 | 20 | 21 | ifdef::add-copy-button-to-env-var[] 22 | Environment variable: env_var_with_copy_button:+++QUARKUS_OPENAPI_GENERATOR_MOQU_RESOURCE_DIR+++[] 23 | endif::add-copy-button-to-env-var[] 24 | ifndef::add-copy-button-to-env-var[] 25 | Environment variable: `+++QUARKUS_OPENAPI_GENERATOR_MOQU_RESOURCE_DIR+++` 26 | endif::add-copy-button-to-env-var[] 27 | -- 28 | |string 29 | |`openapi` 30 | 31 | |=== 32 | 33 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/quarkus-openapi-generator-server_quarkus.quarkus.adoc: -------------------------------------------------------------------------------- 1 | [.configuration-legend] 2 | icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime 3 | [.configuration-reference.searchable, cols="80,.^10,.^10"] 4 | |=== 5 | 6 | h|[.header-title]##Configuration property## 7 | h|Type 8 | h|Default 9 | 10 | 3+|No configuration properties found. 11 | 12 | |=== 13 | 14 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/return-response-objects.adoc: -------------------------------------------------------------------------------- 1 | By default, this extension generates the methods according to their returning models based on the https://spec.openapis.org/oas/v3.1.0#schema-object[OpenAPI specification Schema Object]. If no response model is defined, `jakarta.ws.rs.core.Response` is returned. 2 | 3 | If you want to return `jakarta.ws.rs.core.Response` in _all_ cases instead, you can set the `return-response` property to `true`. 4 | 5 | == Example 6 | 7 | Given you want to return `jakarta.ws.rs.core.Response` for the `my-openapi.yaml` file, you must add the following to your `application.properties` file: 8 | 9 | [source,properties] 10 | ---- 11 | quarkus.openapi-generator.codegen.spec.my_openapi_yaml.return-response=true 12 | ---- -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/supporting-unexpected-enums-values.adoc: -------------------------------------------------------------------------------- 1 | If you are generating a client to an unreliable service, Enums could evolve on the service within a same version without new endpoints. In this case, the client could receive enum values that are unexpected. 2 | 3 | To circumvent this, you can generate an `UNEXPECTED` value with option `additional-enum-type-unexpected-member`. You can customise the name of this enum with `additional-enum-type-unexpected-member-name`. 4 | 5 | The value can be customised with `additional-enum-type-unexpected-member-string-value`. 6 | 7 | [source,properties] 8 | ---- 9 | quarkus.openapi-generator.codegen.spec.my_openapi_yaml.additional-enum-type-unexpected-member=true 10 | quarkus.openapi-generator.codegen.spec.my_openapi_yaml.additional-enum-type-unexpected-member.name=UNEXPECTED 11 | quarkus.openapi-generator.codegen.spec.my_openapi_yaml.additional-enum-type-unexpected-member-string-value=unexpected 12 | ---- 13 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/template-customization.adoc: -------------------------------------------------------------------------------- 1 | You have the option to swap out the https://github.com/quarkiverse/quarkus-openapi-generator/tree/main/deployment/src/main/resources/templates/libraries/microprofile[templates used by this extension] with your customized versions. To achieve this, place your custom templates under the `resources/templates` directory. It's crucial that the filename of each custom template matches that of the original template. 2 | 3 | You can find an example of using customized templates in https://github.com/quarkiverse/quarkus-openapi-generator/tree/main/integration-tests/custom-templates[integration-tests/custom-templates]. 4 | 5 | IMPORTANT: While the option to replace templates exists, it's essential to exercise caution and consider this as a final resort. Prior to altering templates, exhaust all possibilities of achieving your goals through configuration settings. Modifying templates could have broader implications for the extension's functionality and may introduce complexities. Only resort to template replacement when configuration adjustments prove insufficient for your requirements. 6 | 7 | Furthermore, be aware that customizing templates increases the risk of compatibility issues during future upgrades. Therefore, exercise discretion and weigh the benefits against the potential risks before opting for template customization. -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/want-to-contribute.adoc: -------------------------------------------------------------------------------- 1 | **Want to contribute? Great!** We try to make it easy, and all contributions, even the smaller ones, are more than welcome. This includes bug reports, fixes, documentation, examples... But first, read https://github.com/quarkiverse/quarkus-openapi-generator/blob/main/CONTRIBUTING.md[this page]. -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = Quarkus - OpenAPI Generator 2 | 3 | include::./includes/attributes.adoc[] 4 | :extension-status: preview 5 | 6 | This a multipurpose Quarkus' extension for generation of https://quarkus.io/guides/rest-client[Rest Clients] and xref:server.adoc[Server stubs] based on OpenAPI specification files. 7 | 8 | Currently, we support two types of code generation: 9 | 10 | Quarkus - OpenAPI Generator - Client: xref:client.adoc[Refer to our documentation] on how to generate these clients. 11 | 12 | Quarkus - OpenAPI Generator - Server: xref:server.adoc[Follow our guidelines] to generate server stubs using Apicurio. 13 | 14 | WARNING: Check versions 1.x.x if you're still using Quarkus 2. But be aware that we no longer support Quarkus 2. That means there are no updates planned for those versions. 15 | 16 | This extension is based on the https://openapi-generator.tech/[OpenAPI Generator Tool]. Please consider donation to help them maintain the 17 | project: https://opencollective.com/openapi_generator/donate 18 | 19 | include::includes/want-to-contribute.adoc[] 20 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/server.adoc: -------------------------------------------------------------------------------- 1 | = Quarkus - OpenAPI Generator - Server 2 | 3 | include::./includes/attributes.adoc[] 4 | 5 | :extension-status: preview 6 | 7 | Quarkus' extension for generation of server Stubs based on OpenAPI specification files. 8 | 9 | This extension is based on the https://github.com/Apicurio/apicurio-codegen[Apicurio Codegen tool]. 10 | 11 | This extension is for REST code generation for server side only. 12 | 13 | include::includes/want-to-contribute.adoc[] 14 | 15 | [[getting-started]] 16 | == Getting Started 17 | 18 | include::./includes/server-getting-started.adoc[leveloffset=+1, opts=optional] 19 | 20 | == Configuration Properties 21 | 22 | include::./includes/quarkus-openapi-generator-server.adoc[opts=optional, leveloffset=+1] 23 | -------------------------------------------------------------------------------- /docs/templates/includes/attributes.adoc: -------------------------------------------------------------------------------- 1 | :project-version: ${release.current-version} 2 | 3 | :examples-dir: ./../examples/ 4 | -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/Moqu.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Objects; 7 | 8 | import io.quarkiverse.openapi.moqu.model.RequestResponsePair; 9 | 10 | /** 11 | * Represents a collection of request-response pairs, providing methods to access 12 | * these pairs in an immutable list. 13 | */ 14 | public class Moqu { 15 | 16 | private List requestResponsePairs = new ArrayList<>(); 17 | 18 | /** 19 | * Constructs a {@code Moqu} instance with the provided list of request-response pairs. 20 | * 21 | * @param requestResponsePairs the list of {@link RequestResponsePair} objects to initialize 22 | * the collection. Must not be {@code null}. 23 | * @throws NullPointerException if {@code requestResponsePairs} is null. 24 | */ 25 | public Moqu(List requestResponsePairs) { 26 | this.requestResponsePairs = Objects.requireNonNull(requestResponsePairs); 27 | } 28 | 29 | /** 30 | * Returns an unmodifiable list of request-response pairs. 31 | * 32 | * @return an immutable list of {@link RequestResponsePair}. 33 | */ 34 | public List getRequestResponsePairs() { 35 | return Collections.unmodifiableList(requestResponsePairs); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/MoquImporter.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu; 2 | 3 | /** 4 | * {@link MoquImporter} aims to convert a specification into a {@link Moqu} model. 5 | * It provides a method to parse the content, typically from an OpenAPI specification, 6 | * and generate a corresponding {@link Moqu} instance. 7 | */ 8 | public interface MoquImporter { 9 | 10 | /** 11 | * Parses the provided OpenAPI content and generates a new {@link Moqu} instance. 12 | * 13 | * @param content the OpenAPI content as a string, which will be parsed into a {@link Moqu} model. 14 | * @return a new {@link Moqu} instance based on the provided content. 15 | */ 16 | Moqu parse(String content); 17 | } -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/MoquMapper.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * A generic interface for mapping a {@link Moqu} instance to a list of objects of type {@code T}. 7 | * 8 | * @param the type of objects to which the {@link Moqu} instance will be mapped. 9 | */ 10 | public interface MoquMapper { 11 | 12 | /** 13 | * Maps the given {@link Moqu} instance to a list of objects of type {@code T}. 14 | * 15 | * @param moqu the {@link Moqu} instance to be mapped. 16 | * @return a list of mapped objects of type {@code T}. 17 | */ 18 | List map(Moqu moqu); 19 | } -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/ParameterType.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu; 2 | 3 | /** 4 | * Enum representing the type of a parameter in an HTTP request, indicating its location. 5 | * The parameter can be part of the path, query string, or headers. 6 | */ 7 | public enum ParameterType { 8 | 9 | /** 10 | * Indicates that the parameter is part of the URL path. 11 | */ 12 | PATH("path"), 13 | 14 | /** 15 | * Indicates that the parameter is part of the query string. 16 | */ 17 | QUERY("query"), 18 | 19 | /** 20 | * Indicates that the parameter is part of the HTTP headers. 21 | */ 22 | HEADER("header"); 23 | 24 | private final String value; 25 | 26 | /** 27 | * Constructs a {@code ParameterType} with the given string value representing the parameter location. 28 | * 29 | * @param value the string value corresponding to the parameter type. 30 | */ 31 | ParameterType(String value) { 32 | this.value = value; 33 | } 34 | 35 | /** 36 | * Returns the string value associated with this {@code ParameterType}. 37 | * 38 | * @return the string representation of the parameter type. 39 | */ 40 | public String value() { 41 | return this.value; 42 | } 43 | } -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/marshall/ObjectMapperFactory.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu.marshall; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | /** 6 | * Responsible for providing a Single of {@link ObjectMapper} instance. 7 | */ 8 | public class ObjectMapperFactory { 9 | 10 | private static final ObjectMapper objectMapper = new ObjectMapper(); 11 | 12 | public static ObjectMapper getInstance() { 13 | return objectMapper; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/model/Header.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Represents an HTTP header with a name and a set of associated values. 7 | * 8 | * @param name the name of the HTTP header (e.g., "Accept", "Content-Type"). 9 | * @param value the set of values associated with the header, allowing multiple values (e.g., "application/json", "text/html"). 10 | */ 11 | public record Header(String name, List value) { 12 | } -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/model/Operation.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu.model; 2 | 3 | /** 4 | * Represents an HTTP operation. 5 | *

6 | * 7 | * @param httpMethod the HTTP verb used for the current {@link Operation}. 8 | */ 9 | public record Operation(String httpMethod) { 10 | } 11 | -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/model/Parameter.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu.model; 2 | 3 | import io.quarkiverse.openapi.moqu.ParameterType; 4 | 5 | /** 6 | * Represents an HTTP request parameter with a key, value, and location indicating where the parameter is used. 7 | * 8 | * @param key the key of the parameter (e.g., "id", "query"). 9 | * @param value the value of the parameter associated with the key. 10 | * @param where the location of the parameter in the request (e.g., query string, path, header), defined by 11 | * {@link ParameterType}. 12 | */ 13 | public record Parameter(String key, String value, ParameterType where) { 14 | } -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/model/Request.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu.model; 2 | 3 | import java.util.Collection; 4 | 5 | /** 6 | * Represents an HTTP request with essential details such as URL, HTTP method, 7 | * example name, accepted header, and parameters. 8 | * 9 | * @param url the URL to which the request is sent. 10 | * @param httpMethod the HTTP method (GET, POST, PUT, DELETE, etc.) used for the request. 11 | * @param exampleName the name of the example associated with the request. 12 | * @param accept the "Accept" header, which specifies the expected response format. 13 | * @param parameters the list of parameters to be included in the request. 14 | */ 15 | public record Request(String url, String httpMethod, String exampleName, Header accept, Collection parameters) { 16 | } 17 | -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/model/RequestResponsePair.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu.model; 2 | 3 | /** 4 | * Represents a pair of an HTTP request and its corresponding response. 5 | * 6 | * @param request the HTTP request that was sent. 7 | * @param response the HTTP response received for the given request. 8 | */ 9 | public record RequestResponsePair(Request request, Response response) { 10 | } -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/model/Response.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu.model; 2 | 3 | import java.util.List; 4 | 5 | import io.swagger.v3.oas.models.media.MediaType; 6 | 7 | /** 8 | * Represents an HTTP response with details such as the example name, media type, 9 | * status code, content, and headers. 10 | * 11 | * @param exampleName the name of the example associated with this response. 12 | * @param mediaType the media type of the response content (e.g., application/json, text/html), 13 | * represented by {@link MediaType}. 14 | * @param statusCode the HTTP status code of the response (e.g., 200, 404). 15 | * @param content the body of the response as a string. 16 | * @param headers the list of headers included in the response. 17 | */ 18 | public record Response(String exampleName, MediaType mediaType, int statusCode, 19 | String content, List

headers) { 20 | } 21 | -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/wiremock/model/WiremockMapping.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu.wiremock.model; 2 | 3 | public record WiremockMapping(WiremockRequest request, WiremockResponse response) { 4 | } -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/wiremock/model/WiremockRequest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu.wiremock.model; 2 | 3 | public record WiremockRequest( 4 | String method, 5 | String url) { 6 | } 7 | -------------------------------------------------------------------------------- /moqu/core/src/main/java/io/quarkiverse/openapi/moqu/wiremock/model/WiremockResponse.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu.wiremock.model; 2 | 3 | import java.util.Map; 4 | 5 | public record WiremockResponse(Integer status, 6 | String body, 7 | Map headers) { 8 | } 9 | -------------------------------------------------------------------------------- /moqu/core/src/test/java/io/quarkiverse/openapi/moqu/TestUtils.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.moqu; 2 | 3 | import java.io.IOException; 4 | import java.net.URISyntaxException; 5 | import java.net.URL; 6 | import java.nio.file.Files; 7 | import java.nio.file.Path; 8 | 9 | public class TestUtils { 10 | 11 | public static String readContentFromFile(String resourcePath) { 12 | URL url = Thread.currentThread().getContextClassLoader().getResource((resourcePath)); 13 | assert url != null; 14 | try { 15 | return Files.readString(Path.of(url.toURI())); 16 | } catch (IOException | URISyntaxException e) { 17 | return null; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/full.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | servers: 3 | - url: http://localhost:8888 4 | info: 5 | version: 999-SNAPSHOT 6 | title: Method GET one path param 7 | paths: 8 | "/frameworks/{id}": 9 | get: 10 | parameters: 11 | - name: id 12 | in: path 13 | examples: 14 | quarkus: 15 | value: 1 16 | responses: 17 | 200: 18 | content: 19 | "application/json": 20 | examples: 21 | quarkus: 22 | $ref: "#/components/schemas/Framework" 23 | description: Ok 24 | components: 25 | schemas: 26 | Framework: 27 | type: object 28 | properties: 29 | name: 30 | type: string 31 | example: "Quarkus" 32 | versions: 33 | type: array 34 | example: ["999-SNAPSHOT", "3.15.1"] 35 | supportsJava: 36 | type: boolean 37 | example: true 38 | contributors: 39 | type: integer 40 | example: 1000 41 | rules: 42 | type: object 43 | example: 44 | hello: world 45 | 46 | -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/mapper/should_map_one_wiremock_definition.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: "Users API" 4 | version: 1.0.0-alpha 5 | servers: 6 | - url: http://localhost:8888 7 | paths: 8 | /users/{userId}: 9 | get: 10 | description: Get user by ID 11 | parameters: 12 | - name: userId 13 | in: path 14 | required: true 15 | schema: 16 | type: number 17 | examples: 18 | john: 19 | value: 1 20 | responses: 21 | "200": 22 | description: Ok 23 | content: 24 | "application/json": 25 | examples: 26 | john: 27 | value: 28 | '{"id": 1, "name": "John Doe"}' -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/mapper/should_map_two_wiremock_definition.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: "Users API" 4 | version: 1.0.0-alpha 5 | servers: 6 | - url: http://localhost:8888 7 | paths: 8 | /users/{userId}: 9 | get: 10 | description: Get user by ID 11 | parameters: 12 | - name: userId 13 | in: path 14 | required: true 15 | schema: 16 | type: number 17 | examples: 18 | john: 19 | value: 1 20 | mary: 21 | value: 2 22 | responses: 23 | "200": 24 | description: Ok 25 | content: 26 | "application/json": 27 | examples: 28 | john: 29 | value: 30 | '{"id": 1, "name": "John Doe"}' 31 | mary: 32 | value: 33 | '{"id": 2, "name": "Mary Doe"}' -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/one_example_in_the_same_path.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: "Users API" 4 | version: 1.0.0-alpha 5 | servers: 6 | - url: http://localhost:8888 7 | paths: 8 | /users/{id}: 9 | get: 10 | description: Get user by ID 11 | parameters: 12 | - name: id 13 | in: path 14 | required: true 15 | schema: 16 | type: number 17 | examples: 18 | john: 19 | value: 1 20 | responses: 21 | "200": 22 | description: Ok 23 | content: 24 | "application/json": 25 | examples: 26 | john: 27 | value: 28 | '{"id": 1, "name": "John Doe"}' -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/path_param_one_path_param.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | servers: 3 | - url: http://localhost:8888 4 | info: 5 | version: 999-SNAPSHOT 6 | title: Method GET one path param 7 | paths: 8 | "/users/{userId}": 9 | get: 10 | parameters: 11 | - name: userId 12 | in: path 13 | examples: 14 | quarkus: 15 | value: 1 16 | responses: 17 | 200: 18 | content: 19 | "application/json": 20 | examples: 21 | quarkus: 22 | value: '{"name": "Quarkus"}' 23 | description: Ok 24 | -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/path_param_two_params_but_different_path.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | servers: 3 | - url: http://localhost:8888 4 | info: 5 | version: 999-SNAPSHOT 6 | title: Method GET one path param 7 | paths: 8 | "/users/{userId}": 9 | get: 10 | parameters: 11 | - name: userId 12 | in: path 13 | examples: 14 | john: 15 | value: 1 16 | responses: 17 | 200: 18 | content: 19 | "application/json": 20 | examples: 21 | john: 22 | value: '{"name": "John Doe"}' 23 | description: Ok 24 | "/frameworks/{name}": 25 | get: 26 | parameters: 27 | - name: name 28 | in: path 29 | examples: 30 | quarkus: 31 | value: quarkus 32 | responses: 33 | 200: 34 | content: 35 | "application/json": 36 | examples: 37 | quarkus: 38 | value: '{"description": "Quarkus, build time augmentation toolkit"}' 39 | description: Ok 40 | -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/path_param_two_path_params_combination.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | servers: 3 | - url: http://localhost:8888 4 | info: 5 | version: 999-SNAPSHOT 6 | title: Method GET one path param 7 | paths: 8 | "/users/{userId}/books/{bookId}": 9 | get: 10 | parameters: 11 | - name: userId 12 | in: path 13 | examples: 14 | john: 15 | value: 1 16 | mary: 17 | value: 2 18 | - name: bookId 19 | in: path 20 | examples: 21 | john: 22 | value: 80 23 | mary: 24 | value: 70 25 | 26 | responses: 27 | 200: 28 | content: 29 | "application/json": 30 | examples: 31 | john: 32 | value: '{"name": "Book for John", "chapters": 8}' 33 | mary: 34 | value: '{"name": "Book for Mary", "chapters": 10}' 35 | description: Ok 36 | -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/path_param_two_path_params_only_one_with_example.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | servers: 3 | - url: http://localhost:8888 4 | info: 5 | version: 999-SNAPSHOT 6 | title: Method GET one path param 7 | paths: 8 | "/users/{userId}/books/{bookId}": 9 | get: 10 | parameters: 11 | - name: userId 12 | in: path 13 | examples: 14 | john: 15 | value: 1 16 | - name: bookId 17 | in: path 18 | responses: 19 | 200: 20 | content: 21 | "application/json": 22 | examples: 23 | john: 24 | value: '{"name": "Book for John", "chapters": 8}' 25 | description: Ok -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/response_from_ref.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | servers: 3 | - url: http://localhost:8888 4 | info: 5 | version: 999-SNAPSHOT 6 | title: Method GET one path param 7 | paths: 8 | "/frameworks/{id}": 9 | get: 10 | parameters: 11 | - name: id 12 | in: path 13 | examples: 14 | quarkus: 15 | value: 1 16 | responses: 17 | 200: 18 | content: 19 | "application/json": 20 | examples: 21 | quarkus: 22 | $ref: "#/components/schemas/Framework" 23 | description: Ok 24 | components: 25 | schemas: 26 | Framework: 27 | type: object 28 | properties: 29 | name: 30 | type: string 31 | example: "Quarkus" -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/response_from_ref_and_noref.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | servers: 3 | - url: http://localhost:8888 4 | info: 5 | version: 999-SNAPSHOT 6 | title: Method GET one path param 7 | paths: 8 | "/frameworks/{id}": 9 | get: 10 | parameters: 11 | - name: id 12 | in: path 13 | examples: 14 | quarkus: 15 | value: 1 16 | vertx: 17 | value: 2 18 | responses: 19 | 200: 20 | content: 21 | "application/json": 22 | examples: 23 | quarkus: 24 | $ref: "#/components/schemas/Framework" 25 | vertx: 26 | value: '{ "name": "Vert.x", "versions": ["999-SNAPSHOT"]}' 27 | description: Ok 28 | components: 29 | schemas: 30 | Framework: 31 | type: object 32 | properties: 33 | name: 34 | type: string 35 | example: "Quarkus" 36 | versions: 37 | type: array 38 | example: [ "999-SNAPSHOT", "3.15.1" ] 39 | -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/response_from_ref_array.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | servers: 3 | - url: http://localhost:8888 4 | info: 5 | version: 999-SNAPSHOT 6 | title: Method GET one path param 7 | paths: 8 | "/frameworks/{id}": 9 | get: 10 | parameters: 11 | - name: id 12 | in: path 13 | examples: 14 | quarkus: 15 | value: 1 16 | responses: 17 | 200: 18 | content: 19 | "application/json": 20 | examples: 21 | quarkus: 22 | $ref: "#/components/schemas/Framework" 23 | description: Ok 24 | components: 25 | schemas: 26 | Framework: 27 | type: object 28 | properties: 29 | name: 30 | type: string 31 | example: "Quarkus" 32 | versions: 33 | type: array 34 | example: ["999-SNAPSHOT", "3.15.1"] 35 | supportsJava: 36 | type: boolean 37 | example: true 38 | -------------------------------------------------------------------------------- /moqu/core/src/test/resources/wiremock/two_examples_in_the_same_path.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: "Users API" 4 | version: 1.0.0-alpha 5 | servers: 6 | - url: http://localhost:8888 7 | paths: 8 | /users/{userId}: 9 | get: 10 | description: Get user by ID 11 | parameters: 12 | - name: userId 13 | in: path 14 | required: true 15 | schema: 16 | type: number 17 | examples: 18 | john: 19 | value: 1 20 | mary: 21 | value: 2 22 | responses: 23 | "200": 24 | description: Ok 25 | content: 26 | "application/json": 27 | examples: 28 | john: 29 | value: 30 | '{"id": 1, "name": "John Doe"}' 31 | mary: 32 | value: 33 | '{"id": 2, "name": "Mary Doe"}' -------------------------------------------------------------------------------- /moqu/deployment/src/main/java/io/quarkiverse/openapi/generator/MoquWiremockProcessor.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator; 2 | 3 | import io.quarkus.deployment.annotations.BuildStep; 4 | import io.quarkus.deployment.builditem.FeatureBuildItem; 5 | 6 | public class MoquWiremockProcessor { 7 | 8 | @BuildStep 9 | FeatureBuildItem feature() { 10 | return new FeatureBuildItem("moqu-wiremock"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /moqu/deployment/src/main/java/io/quarkiverse/openapi/generator/devui/MoquModel.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.devui; 2 | 3 | public record MoquModel(String name, String link) { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /moqu/deployment/src/main/java/io/quarkiverse/openapi/generator/items/MoquBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.items; 2 | 3 | import io.quarkiverse.openapi.moqu.Moqu; 4 | import io.quarkus.builder.item.MultiBuildItem; 5 | 6 | public final class MoquBuildItem extends MultiBuildItem { 7 | 8 | private final String filename; 9 | private final String extension; 10 | private final Moqu moqu; 11 | 12 | public MoquBuildItem(String filename, String extension, Moqu moqu) { 13 | this.filename = filename; 14 | this.extension = extension; 15 | this.moqu = moqu; 16 | } 17 | 18 | public String getFilename() { 19 | return filename; 20 | } 21 | 22 | public String getExtension() { 23 | return extension; 24 | } 25 | 26 | public Moqu getMoqu() { 27 | return moqu; 28 | } 29 | 30 | public String getFullFilename() { 31 | return filename + "." + extension; 32 | } 33 | 34 | public String prefixUri(String basePath) { 35 | return String.format("%s/%s/%s", basePath, extension, filename); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /moqu/deployment/src/main/java/io/quarkiverse/openapi/generator/items/MoquProjectBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.items; 2 | 3 | import java.util.Collections; 4 | import java.util.Map; 5 | 6 | import io.quarkus.builder.item.SimpleBuildItem; 7 | 8 | public final class MoquProjectBuildItem extends SimpleBuildItem { 9 | 10 | private final Map specs; 11 | 12 | public MoquProjectBuildItem(Map specs) { 13 | this.specs = specs; 14 | } 15 | 16 | public Map specs() { 17 | return Collections.unmodifiableMap(specs); 18 | } 19 | 20 | public record File(String filename, String extension, String content) { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /moqu/deployment/src/test/resources/api.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | servers: 3 | - url: http://localhost:8888 4 | info: 5 | version: 999-SNAPSHOT 6 | title: Method GET one path param 7 | paths: 8 | "/users/{id}": 9 | get: 10 | parameters: 11 | - name: id 12 | in: path 13 | examples: 14 | alice: 15 | value: 1 16 | responses: 17 | 200: 18 | content: 19 | "application/json": 20 | examples: 21 | quarkus: 22 | $ref: "#/components/schemas/User" 23 | description: Ok 24 | components: 25 | schemas: 26 | User: 27 | type: object 28 | properties: 29 | name: 30 | type: string 31 | example: "Alice" 32 | age: 33 | type: number 34 | example: 80 35 | 36 | -------------------------------------------------------------------------------- /moqu/deployment/src/test/resources/apiv2.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.3", 3 | "servers": [ 4 | { 5 | "url": "http://localhost:8888" 6 | } 7 | ], 8 | "info": { 9 | "version": "999-SNAPSHOT", 10 | "title": "Method GET one path param" 11 | }, 12 | "paths": { 13 | "/users/{id}": { 14 | "get": { 15 | "parameters": [ 16 | { 17 | "name": "id", 18 | "in": "path", 19 | "examples": { 20 | "alice": { 21 | "value": 1 22 | } 23 | } 24 | } 25 | ], 26 | "responses": { 27 | "200": { 28 | "description": "Ok", 29 | "content": { 30 | "application/json": { 31 | "examples": { 32 | "quarkus": { 33 | "$ref": "#/components/schemas/User" 34 | } 35 | } 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | }, 43 | "components": { 44 | "schemas": { 45 | "User": { 46 | "type": "object", 47 | "properties": { 48 | "name": { 49 | "type": "string", 50 | "example": "Alice" 51 | }, 52 | "age": { 53 | "type": "number", 54 | "example": 80 55 | } 56 | } 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /moqu/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | io.quarkiverse.openapi.generator 5 | quarkus-openapi-generator-parent 6 | 3.0.0-SNAPSHOT 7 | ../pom.xml 8 | 9 | 4.0.0 10 | pom 11 | quarkus-openapi-generator-moqu-parent 12 | Quarkus - Openapi Generator - Moqu - Parent 13 | 14 | 15 | core 16 | deployment 17 | runtime 18 | 19 | 20 | -------------------------------------------------------------------------------- /moqu/runtime/src/main/java/io/quarkiverse/openapi/generator/moqu/MoquConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.generator.moqu; 2 | 3 | import io.quarkus.runtime.annotations.ConfigPhase; 4 | import io.quarkus.runtime.annotations.ConfigRoot; 5 | import io.smallrye.config.ConfigMapping; 6 | import io.smallrye.config.WithDefault; 7 | 8 | @ConfigMapping(prefix = "quarkus.openapi-generator.moqu") 9 | @ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) 10 | public interface MoquConfig { 11 | 12 | String DEFAULT_RESOURCE_DIR = "openapi"; 13 | 14 | /** 15 | * Path to the Moqu OpenAPI files, relative to the src/main/resources directory. 16 | */ 17 | @WithDefault(DEFAULT_RESOURCE_DIR) 18 | String resourceDir(); 19 | } 20 | -------------------------------------------------------------------------------- /moqu/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: "OpenAPI Generator - Moqu - Wiremock Generator" 2 | artifact: ${project.groupId}:${project.artifactId}:${project.version} 3 | description: The OpenAPI Generator Moqu Wiremock extension converts an OpenAPI specification into a Wiremock definition. 4 | metadata: 5 | keywords: 6 | - "openapi" 7 | - "openapi-generator" 8 | - "wiremock" 9 | categories: 10 | - "web" 11 | status: "preview" 12 | -------------------------------------------------------------------------------- /server/deployment/src/main/java/io/quarkiverse/openapi/server/generator/deployment/CodegenConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.server.generator.deployment; 2 | 3 | import io.quarkus.runtime.annotations.ConfigPhase; 4 | import io.quarkus.runtime.annotations.ConfigRoot; 5 | import io.smallrye.config.ConfigMapping; 6 | 7 | @ConfigRoot(phase = ConfigPhase.BUILD_TIME) 8 | @ConfigMapping(prefix = CodegenConfig.CODEGEN_TIME_CONFIG_PREFIX) 9 | public interface CodegenConfig extends ServerCodegenConfig { 10 | 11 | String CODEGEN_TIME_CONFIG_PREFIX = "quarkus.openapi.generator"; 12 | String CODEGEN_BASE_PACKAGE = CODEGEN_TIME_CONFIG_PREFIX + ".base-package"; 13 | String CODEGEN_SPEC = CODEGEN_TIME_CONFIG_PREFIX + ".spec"; 14 | String INPUT_BASE_DIR = CODEGEN_TIME_CONFIG_PREFIX + ".input-base-dir"; 15 | String CODEGEN_REACTIVE = CODEGEN_TIME_CONFIG_PREFIX + ".reactive"; 16 | 17 | static String getBasePackagePropertyName() { 18 | return CODEGEN_BASE_PACKAGE; 19 | } 20 | 21 | static String getSpecPropertyName() { 22 | return CODEGEN_SPEC; 23 | } 24 | 25 | static String getInputBaseDirPropertyName() { 26 | return INPUT_BASE_DIR; 27 | } 28 | 29 | static String getCodegenReactive() { 30 | return CODEGEN_REACTIVE; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /server/deployment/src/main/java/io/quarkiverse/openapi/server/generator/deployment/ServerCodegenConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.server.generator.deployment; 2 | 3 | import java.util.Optional; 4 | 5 | import io.smallrye.config.WithDefault; 6 | 7 | public interface ServerCodegenConfig { 8 | 9 | String DEFAULT_PACKAGE = "io.apicurio.api"; 10 | String DEFAULT_DIR = "openapi"; 11 | 12 | /** 13 | * The OpenAPI specification filename. 14 | */ 15 | Optional spec(); 16 | 17 | /** 18 | * The input base dir where the OpenAPI specification is. 19 | */ 20 | @WithDefault("src/main/resources/openapi") 21 | Optional inputBaseDir(); 22 | 23 | /** 24 | * Whether it must generate with reactive code. 25 | */ 26 | @WithDefault("false") 27 | boolean reactive(); 28 | 29 | /** 30 | * The base package to be used to generated sources. 31 | */ 32 | @WithDefault(DEFAULT_PACKAGE) 33 | Optional basePackage(); 34 | } 35 | -------------------------------------------------------------------------------- /server/deployment/src/main/resources/META-INF/services/io.quarkus.deployment.CodeGenProvider: -------------------------------------------------------------------------------- 1 | io.quarkiverse.openapi.server.generator.deployment.codegen.ApicurioOpenApiServerCodegen -------------------------------------------------------------------------------- /server/deployment/src/test/java/io/quarkiverse/openapi/server/generator/deployment/MockConfigUtils.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.server.generator.deployment; 2 | 3 | import java.io.IOException; 4 | import java.io.UncheckedIOException; 5 | import java.net.URL; 6 | import java.util.Objects; 7 | 8 | import org.eclipse.microprofile.config.Config; 9 | import org.eclipse.microprofile.config.spi.ConfigProviderResolver; 10 | 11 | import io.smallrye.config.PropertiesConfigSource; 12 | 13 | public final class MockConfigUtils { 14 | 15 | private MockConfigUtils() { 16 | } 17 | 18 | public static Config getTestConfig(String propertiesFile) { 19 | PropertiesConfigSource configSource; 20 | try { 21 | configSource = new PropertiesConfigSource(getResource(propertiesFile)); 22 | } catch (IOException e) { 23 | throw new UncheckedIOException(e); 24 | } 25 | 26 | return ConfigProviderResolver 27 | .instance() 28 | .getBuilder() 29 | .withSources(configSource) 30 | .build(); 31 | } 32 | 33 | private static URL getResource(String resourcePath) { 34 | return Objects.requireNonNull(MockConfigUtils.class.getResource(resourcePath)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /server/deployment/src/test/resources/io/quarkiverse/openapi/server/generator/deployment/doesNotExistDir.application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi.generator.spec=petstore-openapi-2.json 2 | quarkus.openapi.generator.base-package=io.petstore -------------------------------------------------------------------------------- /server/deployment/src/test/resources/io/quarkiverse/openapi/server/generator/deployment/inputDir.application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi.generator.spec=petstore-openapi-2.json 2 | quarkus.openapi.generator.input-base-dir=src/test/resources2 3 | quarkus.openapi.generator.base-package=io.petstore -------------------------------------------------------------------------------- /server/deployment/src/test/resources/io/quarkiverse/openapi/server/generator/deployment/json.application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi.generator.spec=petstore-openapi.json 2 | quarkus.openapi.generator.base-package=io.petstore -------------------------------------------------------------------------------- /server/deployment/src/test/resources/io/quarkiverse/openapi/server/generator/deployment/yaml.application.properties: -------------------------------------------------------------------------------- 1 | quarkus.openapi.generator.spec=petstore-openapi.yaml 2 | quarkus.openapi.generator.base-package=io.petstore -------------------------------------------------------------------------------- /server/integration-tests/codestarts/src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-openapi-generator/aee8e52cac006bc1ee7a1e01775e2ad6cbbeac69/server/integration-tests/codestarts/src/main/resources/application.properties -------------------------------------------------------------------------------- /server/integration-tests/codestarts/src/test/java/io/quarkiverse/openapi/server/generator/it/QuarkusOpenAPIGeneratorServerCodestartsTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.server.generator.it; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.RegisterExtension; 5 | 6 | import io.quarkus.devtools.codestarts.quarkus.QuarkusCodestartCatalog; 7 | import io.quarkus.devtools.testing.codestarts.QuarkusCodestartTest; 8 | 9 | public class QuarkusOpenAPIGeneratorServerCodestartsTest { 10 | 11 | @RegisterExtension 12 | public static QuarkusCodestartTest codestartTest = QuarkusCodestartTest.builder() 13 | .languages(QuarkusCodestartCatalog.Language.JAVA) 14 | .setupStandaloneExtensionTest("io.quarkiverse.openapi.generator:quarkus-openapi-generator-server").build(); 15 | 16 | @Test 17 | void testContent() throws Throwable { 18 | codestartTest 19 | .assertThatGeneratedFile(QuarkusCodestartCatalog.Language.JAVA, "src/main/resources/application.properties") 20 | .content() 21 | .contains("quarkus.openapi.generator.spec=openapi.yml"); 22 | codestartTest 23 | .assertThatGeneratedFile(QuarkusCodestartCatalog.Language.JAVA, "src/main/resources/openapi/openapi.yml") 24 | .content() 25 | .contains("title: Generated API"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /server/integration-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | quarkus-openapi-generator-server-parent 5 | io.quarkiverse.openapi.generator 6 | 3.0.0-SNAPSHOT 7 | ../pom.xml 8 | 9 | 4.0.0 10 | 11 | pom 12 | 13 | quarkus-openapi-generator-server-integration-tests-parent 14 | Quarkus - OpenAPI Generator - Server - Integration Tests 15 | 16 | 17 | reactive 18 | resteasy 19 | codestarts 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /server/integration-tests/reactive/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # Codegen properties 2 | quarkus.openapi.generator.spec=petstore-openapi.json 3 | quarkus.openapi.generator.base-package=io.petstore 4 | quarkus.openapi.generator.reactive=true 5 | -------------------------------------------------------------------------------- /server/integration-tests/reactive/src/test/java/it/PetStoreTest.java: -------------------------------------------------------------------------------- 1 | package it; 2 | 3 | import static io.restassured.RestAssured.given; 4 | import static org.hamcrest.CoreMatchers.anything; 5 | 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | 9 | import io.petstore.beans.Pet; 10 | import io.quarkus.test.junit.QuarkusTest; 11 | import io.restassured.http.ContentType; 12 | 13 | @QuarkusTest 14 | public class PetStoreTest { 15 | 16 | @Test 17 | public void testapi() { 18 | 19 | Pet pet = new Pet(); 20 | pet.setName("test"); 21 | pet.setId(1234L); 22 | pet.setStatus(Pet.Status.available); 23 | 24 | given() 25 | .when() 26 | .contentType(ContentType.JSON) 27 | .body(pet) 28 | .post("/pet") 29 | .then() 30 | .statusCode(204) 31 | .body(anything()); 32 | 33 | final Pet returnedPet = given() 34 | .when() 35 | .accept(ContentType.JSON) 36 | .get("/pet/1234") 37 | .then() 38 | .statusCode(200) 39 | .extract() 40 | .body() 41 | .as(Pet.class); 42 | 43 | Assertions.assertEquals(pet.getId(), returnedPet.getId()); 44 | Assertions.assertEquals(pet.getName(), returnedPet.getName()); 45 | Assertions.assertEquals(pet.getStatus(), returnedPet.getStatus()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /server/integration-tests/resteasy/src/main/java/io/petstore/PetStoreImpl.java: -------------------------------------------------------------------------------- 1 | package io.petstore; 2 | 3 | import java.io.InputStream; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import io.petstore.beans.ApiResponse; 9 | import io.petstore.beans.Pet; 10 | 11 | public class PetStoreImpl implements PetResource { 12 | 13 | private static final Map PETS = new HashMap<>(); 14 | 15 | @Override 16 | public Pet updatePet(Pet data) { 17 | return PETS.put(data.getId(), data); 18 | } 19 | 20 | @Override 21 | public Pet addPet(Pet data) { 22 | return PETS.put(data.getId(), data); 23 | } 24 | 25 | @Override 26 | public List findPetsByStatus(String status) { 27 | return null; 28 | } 29 | 30 | @Override 31 | public List findPetsByTags(List tags) { 32 | return null; 33 | } 34 | 35 | @Override 36 | public Pet getPetById(long petId) { 37 | return PETS.get(petId); 38 | } 39 | 40 | @Override 41 | public void updatePetWithForm(long petId, String name, String status) { 42 | 43 | } 44 | 45 | @Override 46 | public void deletePet(String apiKey, long petId) { 47 | PETS.remove(petId); 48 | } 49 | 50 | @Override 51 | public ApiResponse uploadFile(long petId, String additionalMetadata, InputStream data) { 52 | return null; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /server/integration-tests/resteasy/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # Codegen properties 2 | quarkus.openapi.generator.spec=petstore-openapi.json 3 | quarkus.openapi.generator.base-package=io.petstore 4 | quarkus.openapi.generator.reactive=false 5 | -------------------------------------------------------------------------------- /server/integration-tests/resteasy/src/test/java/io/quarkiverse/openapi/server/generator/it/PetStoreTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.openapi.server.generator.it; 2 | 3 | import static io.restassured.RestAssured.given; 4 | import static org.hamcrest.CoreMatchers.anything; 5 | 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | 9 | import io.petstore.beans.Pet; 10 | import io.quarkus.test.junit.QuarkusTest; 11 | import io.restassured.http.ContentType; 12 | 13 | @QuarkusTest 14 | public class PetStoreTest { 15 | 16 | @Test 17 | public void testapi() { 18 | 19 | Pet pet = new Pet(); 20 | pet.setName("test"); 21 | pet.setId(1234L); 22 | pet.setStatus(Pet.Status.available); 23 | 24 | given() 25 | .when() 26 | .contentType(ContentType.JSON) 27 | .body(pet) 28 | .post("/pet") 29 | .then() 30 | .statusCode(204) 31 | .body(anything()); 32 | 33 | final Pet returnedPet = given() 34 | .when() 35 | .accept(ContentType.JSON) 36 | .get("/pet/1234") 37 | .then() 38 | .statusCode(200) 39 | .extract() 40 | .body() 41 | .as(Pet.class); 42 | 43 | Assertions.assertEquals(pet.getId(), returnedPet.getId()); 44 | Assertions.assertEquals(pet.getName(), returnedPet.getName()); 45 | Assertions.assertEquals(pet.getStatus(), returnedPet.getStatus()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | quarkus-openapi-generator-parent 5 | io.quarkiverse.openapi.generator 6 | 3.0.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | quarkus-openapi-generator-server-parent 11 | Quarkus - OpenAPI Generator - Server - Parent 12 | pom 13 | 14 | 15 | deployment 16 | runtime 17 | 18 | 19 | -------------------------------------------------------------------------------- /server/runtime/src/main/codestarts/quarkus/openapi-generator-server-codestart/codestart.yml: -------------------------------------------------------------------------------- 1 | name: openapi-generator-server-codestart 2 | ref: openapi-generator-server 3 | type: code 4 | tags: extension-codestart 5 | metadata: 6 | title: OpenAPI Generator Server 7 | description: This codestart generates a simple API with OpenAPI documentation. 8 | related-guide-section: https://docs.quarkiverse.io/quarkus-openapi-generator/dev/server.html 9 | language: 10 | base: 11 | dependencies: 12 | - io.quarkus:quarkus-resteasy 13 | - io.quarkus:quarkus-smallrye-openapi -------------------------------------------------------------------------------- /server/runtime/src/main/codestarts/quarkus/openapi-generator-server-codestart/java/README.tpl.qute.md: -------------------------------------------------------------------------------- 1 | {#include readme-header /} 2 | 3 | ## Requirements 4 | 5 | If you do not have added the `io.quarkus:quarkus-smallrye-openapi` extension in your project, add it first: 6 | 7 | ### SmallRye OpenAPI: 8 | 9 | Quarkus CLI: 10 | 11 | ```bash 12 | quarkus ext add io.quarkus:quarkus-smallrye-openapi 13 | ``` 14 | 15 | Maven: 16 | ```bash 17 | ./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-smallrye-openapi" 18 | ``` 19 | 20 | Gradle: 21 | 22 | ```bash 23 | ./gradlew addExtension --extensions="io.quarkus:quarkus-smallrye-openapi" 24 | ``` -------------------------------------------------------------------------------- /server/runtime/src/main/codestarts/quarkus/openapi-generator-server-codestart/java/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | quarkus: 2 | openapi: 3 | generator: 4 | spec: 5 | openapi.yml -------------------------------------------------------------------------------- /server/runtime/src/main/codestarts/quarkus/openapi-generator-server-codestart/java/src/main/resources/openapi/openapi.yml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.3 2 | info: 3 | title: Generated API 4 | version: "1.0" 5 | paths: 6 | /pets: 7 | get: 8 | responses: 9 | 200: 10 | description: OK 11 | content: 12 | application/json: { } 13 | post: 14 | requestBody: 15 | content: 16 | application/json: 17 | schema: 18 | $ref: '#/components/schemas/Pet' 19 | responses: 20 | 200: 21 | description: OK 22 | content: 23 | application/json: { } 24 | delete: 25 | requestBody: 26 | content: 27 | application/json: 28 | schema: 29 | $ref: '#/components/schemas/Pet' 30 | responses: 31 | 200: 32 | description: OK 33 | content: 34 | application/json: { } 35 | components: 36 | schemas: 37 | Pet: 38 | properties: 39 | description: 40 | type: string 41 | name: 42 | type: string -------------------------------------------------------------------------------- /server/runtime/src/main/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-openapi-generator/aee8e52cac006bc1ee7a1e01775e2ad6cbbeac69/server/runtime/src/main/resources/META-INF/beans.xml -------------------------------------------------------------------------------- /server/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: "OpenAPI Generator - REST Server Generator" 2 | description: "Provides personalized code generation to get started in a Server project " 3 | artifact: ${project.groupId}:${project.artifactId}:${project.version} 4 | metadata: 5 | keywords: 6 | - "openapi" 7 | - "openapi-generator-server" 8 | - "rest" 9 | - "server" 10 | categories: 11 | - "web" 12 | guide: "https://docs.quarkiverse.io/quarkus-openapi-generator/dev/index.html" 13 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-openapi-generator/main/docs/modules/ROOT/assets/images/openapi.svg" 14 | status: "preview" 15 | codestart: 16 | name: "openapi-generator-server" 17 | languages: 18 | - "java" 19 | artifact: "io.quarkiverse.openapi.generator:quarkus-openapi-generator-server:codestarts:jar:${project.version}" --------------------------------------------------------------------------------