diff --git a/_data/versioned/latest/index/quarkus.yaml b/_data/versioned/latest/index/quarkus.yaml index 94304f3c9c..37d67c1ec0 100644 --- a/_data/versioned/latest/index/quarkus.yaml +++ b/_data/versioned/latest/index/quarkus.yaml @@ -37,6 +37,7 @@ types: - title: Contexts and Dependency Injection filename: cdi-reference.adoc summary: Go more in depth into the Quarkus implementation of CDI. + keywords: arc categories: core type: reference url: /guides/cdi-reference @@ -55,7 +56,7 @@ types: - title: Logging configuration filename: logging.adoc summary: "Read about the use of logging API in Quarkus, configuring logging output, and using logging adapters to unify the output from other logging APIs." - categories: "core, getting-started, observability" + categories: "getting-started, core, observability" id: logging type: reference url: /guides/logging @@ -173,6 +174,7 @@ types: - title: Configuring Well-Known OpenID Connect Providers filename: security-openid-connect-providers.adoc summary: This document explains how to configure well-known social OIDC and OAuth2 providers. + keywords: oidc github twitter google facebook mastodon microsoft apple spotify twitch categories: "security, web" id: security-openid-connect-providers type: concepts @@ -236,7 +238,7 @@ types: - title: Security vulnerability detection and reporting in Quarkus filename: security-vulnerability-detection.adoc summary: Most of the Quarkus tags are registered in the US National Vulnerability Database (NVD) in Common Platform Enumeration (CPE) name format. - categories: "contributing, security" + categories: "security, contributing" id: security-vulnerability-detection type: concepts url: /guides/security-vulnerability-detection @@ -265,7 +267,7 @@ types: - title: Use virtual threads in REST applications filename: resteasy-reactive-virtual-threads.adoc summary: How to use virtual threads in a REST application - categories: "core, web" + categories: "web, core" id: resteasy-reactive-virtual-threads type: howto url: /guides/resteasy-reactive-virtual-threads @@ -273,7 +275,7 @@ types: - title: Building a Native Executable filename: building-native-image.adoc summary: Build native executables with GraalVM or Mandrel. - categories: "native, getting-started" + categories: "getting-started, native" type: tutorial url: /guides/building-native-image - title: Collect metrics using Micrometer @@ -338,7 +340,7 @@ types: - title: Your second Quarkus application filename: getting-started-dev-services.adoc summary: Discover some of the features that make developing with Quarkus a joyful experience. - categories: "core, getting-started, data" + categories: "getting-started, data, core" id: getting-started-dev-services-tutorial type: tutorial url: /guides/getting-started-dev-services @@ -406,6 +408,7 @@ types: - title: Application Initialization and Termination filename: lifecycle.adoc summary: You often need to execute custom actions when the application starts and clean up everything when the application stops. + keywords: lifecycle event categories: core type: guide url: /guides/lifecycle @@ -565,6 +568,7 @@ types: - title: Dev Services and UI for OpenID Connect (OIDC) filename: security-openid-connect-dev-services.adoc summary: Start Keycloak or other providers automatically in dev and test modes. + keywords: sso oidc security keycloak categories: security type: guide url: /guides/security-openid-connect-dev-services @@ -789,6 +793,7 @@ types: - title: Introduction to Contexts and Dependency Injection (CDI) filename: cdi.adoc summary: "Quarkus DI solution is based on the [Jakarta Contexts and Dependency Injection 4.0](https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html) specification." + keywords: qualifier event interceptor observer arc categories: core type: guide url: /guides/cdi @@ -1087,7 +1092,7 @@ types: - title: Testing Your Application filename: getting-started-testing.adoc summary: "This guide covers testing in JVM mode, native mode, and injection of resources into tests" - categories: "native, tooling, core" + categories: "tooling, native, core" id: testing type: guide url: /guides/getting-started-testing @@ -1154,6 +1159,8 @@ types: - title: Using Keycloak Admin Client filename: security-keycloak-admin-client.adoc summary: The Quarkus Keycloak Admin Client and its reactive twin support Keycloak Admin Client which can be used to configure a running Keycloak server. + keywords: sso oidc security keycloak + categories: security type: guide url: /guides/security-keycloak-admin-client - title: Using Kotlin @@ -1176,6 +1183,7 @@ types: - title: Using OAuth2 RBAC filename: security-oauth2.adoc summary: This guide explains how your Quarkus application can utilize OAuth2 tokens to provide secured access to the Jakarta REST endpoints. + keywords: oauth categories: security type: guide url: /guides/security-oauth2 @@ -1188,12 +1196,14 @@ types: - title: Using OpenID Connect (OIDC) Multi-Tenancy filename: security-openid-connect-multitenancy.adoc summary: This guide demonstrates how your OpenID Connect application can support multi-tenancy so that you can serve multiple tenants from a single application. + keywords: sso oidc oauth2 security categories: security type: guide url: /guides/security-openid-connect-multitenancy - title: Using OpenID Connect (OIDC) and Keycloak to Centralize Authorization filename: security-keycloak-authorization.adoc summary: This guide demonstrates how your Quarkus application can authorize access to protected resources using Keycloak Authorization Services. + keywords: sso oidc security keycloak categories: security type: guide url: /guides/security-keycloak-authorization diff --git a/_data/versioned/main/index/quarkus.yaml b/_data/versioned/main/index/quarkus.yaml index 9c2541111f..ad045f5fca 100644 --- a/_data/versioned/main/index/quarkus.yaml +++ b/_data/versioned/main/index/quarkus.yaml @@ -5,7 +5,16 @@ types: - title: Authorization of web endpoints filename: security-authorize-web-endpoints-reference.adoc summary: Quarkus has an integrated pluggable web security layer. - categories: "web, security" + categories: "security, web" + topics: + - security + - authorization + - http + - rest + extensions: + - io.quarkus:quarkus-vertx-http + - io.quarkus:quarkus-resteasy-reactive + - io.quarkus:quarkus-resteasy id: security-authorize-web-endpoints-reference type: reference url: /guides/security-authorize-web-endpoints-reference @@ -13,24 +22,60 @@ types: filename: class-loading-reference.adoc summary: Learn more about Quarkus class loading infrastructure. categories: architecture + topics: + - internals + - extensions + extensions: + - io.quarkus:quarkus-core type: reference url: /guides/class-loading-reference - title: Command Mode Applications filename: command-mode-reference.adoc summary: This reference guide explains how to develop command line applications with Quarkus. - categories: "core, command-line" + categories: "command-line, core" + topics: + - command-line + - cli + extensions: + - io.quarkus:quarkus-core type: reference url: /guides/command-mode-reference - title: Configuration Reference Guide filename: config-reference.adoc summary: Learn more about how to configure your Quarkus applications. categories: core + topics: + - configuration + extensions: + - io.quarkus:quarkus-core type: reference url: /guides/config-reference - title: Configure data sources in Quarkus filename: datasource.adoc summary: Use a unified configuration model to define data sources for Java Database Connectivity (JDBC) and Reactive drivers. categories: "data, getting-started" + topics: + - data + - database + - datasource + - sql + - jdbc + - reactive + extensions: + - io.quarkus:quarkus-agroal + - io.quarkus:quarkus-reactive-mysql-client + - io.quarkus:quarkus-reactive-oracle-client + - io.quarkus:quarkus-reactive-pg-client + - io.quarkus:quarkus-reactive-db2-client + - io.quarkus:quarkus-reactive-mssql-client + - io.quarkus:quarkus-jdbc-db2 + - io.quarkus:quarkus-jdbc-derby + - io.quarkus:quarkus-jdbc-h2 + - io.quarkus:quarkus-jdbc-mariadb + - io.quarkus:quarkus-jdbc-mssql + - io.quarkus:quarkus-jdbc-mysql + - io.quarkus:quarkus-jdbc-oracle + - io.quarkus:quarkus-jdbc-postgresql id: datasources type: reference url: /guides/datasource @@ -39,24 +84,51 @@ types: summary: Go more in depth into the Quarkus implementation of CDI. keywords: arc categories: core + topics: + - cdi + - arc + - injection + - interceptor + - observer + extensions: + - io.quarkus:quarkus-arc type: reference url: /guides/cdi-reference - title: HTTP Reference filename: http-reference.adoc summary: Learn more about configuring Quarkus' Vert.x based HTTP layer - and Undertow if you are using servlets. categories: web + topics: + - http + - web + - webjars + - vertx + - servlet + - undertow + extensions: + - io.quarkus:quarkus-vertx-http type: reference url: /guides/http-reference - title: Infinispan Client Extension Reference Guide filename: infinispan-client-reference.adoc summary: "Infinispan is an in memory distributed data store and cache server that offers flexible deployment options and robust capabilities for storing, managing, and processing data." categories: data + topics: + - data + - infinispan + extensions: + - io.quarkus:quarkus-infinispan-client type: reference url: /guides/infinispan-client-reference - title: Logging configuration filename: logging.adoc summary: "Read about the use of logging API in Quarkus, configuring logging output, and using logging adapters to unify the output from other logging APIs." - categories: "observability, core, getting-started" + categories: "core, getting-started, observability" + topics: + - logging + - observability + extensions: + - io.quarkus:quarkus-core id: logging type: reference url: /guides/logging @@ -64,18 +136,33 @@ types: filename: mailer-reference.adoc summary: This reference guide explains in more details the configuration and usage of the Quarkus Mailer. categories: miscellaneous + topics: + - mail + - mailer + extensions: + - io.quarkus:quarkus-mailer type: reference url: /guides/mailer-reference - title: Management interface reference filename: management-interface-reference.adoc summary: Management interface configuration categories: observability + topics: + - management + - observability + extensions: + - io.quarkus:quarkus-vertx-http type: reference url: /guides/management-interface-reference - title: Micrometer Metrics filename: telemetry-micrometer.adoc summary: "Use Micrometer to collect metrics produced by Quarkus, its extensions, and your application." categories: observability + topics: + - observability + - micrometer + extensions: + - io.quarkus:quarkus-micrometer id: telemetry-micrometer type: reference url: /guides/telemetry-micrometer @@ -83,18 +170,32 @@ types: filename: native-reference.adoc summary: "This guide is a companion to the Building a Native Executable, Using SSL With Native Images, and Writing Native Applications, guides." categories: native + topics: + - native id: native-reference type: reference url: /guides/native-reference - title: OpenID Connect (OIDC) and OAuth2 Client and Filters Reference Guide filename: security-openid-connect-client-reference.adoc summary: 'This reference guide explains how to use:' + categories: security + topics: + - security + - oidc + - client + extensions: + - io.quarkus:quarkus-oidc-client type: reference url: /guides/security-openid-connect-client-reference - title: OpenID Connect (OIDC) configuration properties filename: security-oidc-configuration-properties-reference.adoc summary: "As a Quarkus developer, you configure the Quarkus OpenID Connect (OIDC) extension by setting the following properties in the src/main/resources/application.properties file." categories: security + topics: + - security + - oidc + extensions: + - io.quarkus:quarkus-oidc id: security-oidc-configuration-properties-reference type: reference url: /guides/security-oidc-configuration-properties-reference @@ -102,6 +203,9 @@ types: filename: doc-reference.adoc summary: Guidelines are provided to help you to contribute clear and consistent content that is also sourced in the required diataxis structure and composition of Quarkus documentation. categories: contributing + topics: + - internals + - documentation id: doc-reference type: reference url: /guides/doc-reference @@ -109,38 +213,88 @@ types: filename: qute-reference.adoc summary: Learn everything you need to know about the Qute template engine. categories: miscellaneous + topics: + - templating + - qute + extensions: + - io.quarkus:quarkus-qute + - io.quarkus:quarkus-resteasy-qute + - io.quarkus:quarkus-resteasy-reactive-qute type: reference url: /guides/qute-reference - title: Reactive Messaging AMQP 1.0 Connector Reference Documentation filename: amqp-reference.adoc summary: This guide is the companion from the Getting Started with AMQP 1.0. + categories: messaging + topics: + - messaging + - amqp + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-amqp type: reference url: /guides/amqp-reference - title: Reactive Messaging RabbitMQ Connector Reference Documentation filename: rabbitmq-reference.adoc summary: This guide is the companion from the Getting Started with RabbitMQ. + categories: messaging + topics: + - messaging + - reactive-messaging + - rabbitmq + - devservices + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-rabbitmq type: reference url: /guides/rabbitmq-reference - title: Redis Cache filename: cache-redis-reference.adoc summary: Use Redis as the Quarkus cache backend categories: data + topics: + - redis + - cache + - data + extensions: + - io.quarkus:quarkus-redis-cache + - io.quarkus:quarkus-redis-client type: reference url: /guides/cache-redis-reference - title: Redis Extension Reference Guide filename: redis-reference.adoc summary: "Redis is an in-memory data store used as a database, cache, streaming engine, and message broker." + categories: data + topics: + - data + - redis + - nosql + extensions: + - io.quarkus:quarkus-redis-client type: reference url: /guides/redis-reference - title: Scheduler Reference Guide filename: scheduler-reference.adoc summary: Learn more about the Scheduler extension. categories: miscellaneous + topics: + - scheduling + - cronjob + extensions: + - io.quarkus:quarkus-scheduler type: reference url: /guides/scheduler-reference - title: Stork Reference Guide filename: stork-reference.adoc summary: This guide is the companion from the Stork Getting Started Guide. + categories: cloud + topics: + - service-discovery + - load-balancing + - stork + extensions: + - io.quarkus:quarkus-smallrye-stork type: reference url: /guides/stork-reference - title: Vert.x Reference Guide @@ -151,8 +305,12 @@ types: url: /guides/vertx-reference - title: Virtual Thread support reference filename: virtual-threads.adoc - summary: This guide explains how to benefit from Java 19+ virtual threads in Quarkus application. + summary: This guide explains how to benefit from Java 21+ virtual threads in Quarkus application. categories: core + topics: + - virtual-threads + extensions: + - io.quarkus:quarkus-core id: virtual-threads type: reference url: /guides/virtual-threads @@ -160,14 +318,27 @@ types: - title: Authentication mechanisms in Quarkus filename: security-authentication-mechanisms.adoc summary: "The Quarkus Security framework supports multiple authentication mechanisms, which you can use to secure your applications." - categories: "web, security" + categories: "security, web" + topics: + - security + - authentication id: security-authentication-mechanisms type: concepts url: /guides/security-authentication-mechanisms - title: Basic authentication filename: security-basic-authentication.adoc summary: HTTP Basic authentication is one of the least resource-demanding techniques that enforce access controls to web resources. - categories: "web, security" + categories: "security, web" + topics: + - security + - authentication + - basic-authentication + - http + extensions: + - io.quarkus:quarkus-vertx-http + - io.quarkus:quarkus-elytron-security-jdbc + - io.quarkus:quarkus-elytron-security-ldap + - io.quarkus:quarkus-security-jpa-reactive id: security-basic-authentication type: concepts url: /guides/security-basic-authentication @@ -175,7 +346,21 @@ types: filename: security-openid-connect-providers.adoc summary: This document explains how to configure well-known social OIDC and OAuth2 providers. keywords: oidc github twitter google facebook mastodon microsoft apple spotify twitch - categories: "web, security" + categories: "security, web" + topics: + - security + - oidc + - github + - twitter + - google + - facebook + - mastodon + - microsoft + - apple + - spotify + - twitch + extensions: + - io.quarkus:quarkus-oidc id: security-openid-connect-providers type: concepts url: /guides/security-openid-connect-providers @@ -183,6 +368,9 @@ types: filename: duplicated-context.adoc summary: "When using a traditional, blocking, and synchronous framework, processing of each request is performed in a dedicated thread." categories: "architecture, core" + topics: + - internals + - extensions id: duplicated-context type: concepts url: /guides/duplicated-context @@ -190,27 +378,54 @@ types: filename: security-identity-providers.adoc summary: "In the Quarkus Security framework, identity providers play a crucial role in authentication and authorization by verifying user identities." categories: security + topics: + - security + - identity-providers + extensions: + - io.quarkus:quarkus-elytron-security-jdbc + - io.quarkus:quarkus-elytron-security-ldap + - io.quarkus:quarkus-security-jpa-reactive id: security-identity-providers type: concepts url: /guides/security-identity-providers - title: OpenID Connect (OIDC) Bearer token authentication filename: security-oidc-bearer-token-authentication.adoc summary: Secure HTTP access to Jakarta REST (formerly known as JAX-RS) endpoints in your application with Bearer token authentication by using the Quarkus OpenID Connect (OIDC) extension. - categories: "web, security" + categories: "security, web" + topics: + - security + - oidc + - bearer-token + - keycloak + - authentication + extensions: + - io.quarkus:quarkus-oidc id: security-oidc-bearer-token-authentication type: concepts url: /guides/security-oidc-bearer-token-authentication - title: OpenID Connect authorization code flow mechanism for protecting web applications filename: security-oidc-code-flow-authentication.adoc summary: "To protect your web applications, you can use the industry-standard OpenID Connect (OIDC) Authorization Code Flow mechanism provided by the Quarkus OIDC extension." - categories: "web, security" + categories: "security, web" + topics: + - security + - oidc + - keycloak + - authentication + extensions: + - io.quarkus:quarkus-oidc id: security-oidc-code-flow-authentication type: concepts url: /guides/security-oidc-code-flow-authentication - title: Proactive authentication filename: security-proactive-authentication.adoc summary: Proactive authentication is enabled in Quarkus by default. - categories: "web, security" + categories: "security, web" + topics: + - security + - authentication + extensions: + - io.quarkus:quarkus-vertx-http id: security-proactive-authentication type: concepts url: /guides/security-proactive-authentication @@ -218,6 +433,8 @@ types: filename: security-architecture.adoc summary: The Quarkus Security architecture provides several built-in authentication mechanisms and is highly customizable. categories: security + topics: + - security id: security-architecture type: concepts url: /guides/security-architecture @@ -225,6 +442,8 @@ types: filename: security-overview.adoc summary: "Quarkus Security is a framework that provides the architecture, multiple authentication and authorization mechanisms, and other tools for you to build secure and production-quality Java applications." categories: security + topics: + - security id: security-overview type: concepts url: /guides/security-overview @@ -232,13 +451,19 @@ types: filename: doc-concept.adoc summary: "Quarkus documentation is structured into four distinct content types: concepts, how-tos, tutorials, and references." categories: contributing + topics: + - internals + - documentation id: doc-concept type: concepts url: /guides/doc-concept - title: Security vulnerability detection and reporting in Quarkus filename: security-vulnerability-detection.adoc summary: Most of the Quarkus tags are registered in the US National Vulnerability Database (NVD) in Common Platform Enumeration (CPE) name format. - categories: "security, contributing" + categories: "contributing, security" + topics: + - security + - vulnerability id: security-vulnerability-detection type: concepts url: /guides/security-vulnerability-detection @@ -247,6 +472,9 @@ types: filename: doc-contribute-docs-howto.adoc summary: "Contribute to the documentation by using the recommended diataxis content types, steps, workflow, and style guidance to ensure the content successfully renders on the Quarkus website portal." categories: contributing + topics: + - internals + - documentation id: doc-contribute-howto type: howto url: /guides/doc-contribute-docs-howto @@ -254,6 +482,16 @@ types: filename: security-basic-authentication-howto.adoc summary: Enable Basic authentication for your Quarkus project and allow users to authenticate with a username and password. categories: security + topics: + - security + - authentication + - basic-authentication + - http + extensions: + - io.quarkus:quarkus-vertx-http + - io.quarkus:quarkus-elytron-security-jdbc + - io.quarkus:quarkus-elytron-security-ldap + - io.quarkus:quarkus-security-jpa-reactive id: security-basic-authentication-howto type: howto url: /guides/security-basic-authentication-howto @@ -261,13 +499,26 @@ types: filename: update-quarkus.adoc summary: Learn how to upgrade your projects to the latest version of Quarkus categories: core + topics: + - tooling id: update-quarkus type: howto url: /guides/update-quarkus - title: Use virtual threads in REST applications filename: resteasy-reactive-virtual-threads.adoc summary: How to use virtual threads in a REST application - categories: "web, core" + categories: "core, web" + topics: + - rest + - resteasy-reactive + - virtual-threads + extensions: + - io.quarkus:quarkus-resteasy-reactive + - io.quarkus:quarkus-resteasy-reactive-jackson + - io.quarkus:quarkus-resteasy-reactive-jsonb + - io.quarkus:quarkus-rest-client-reactive + - io.quarkus:quarkus-rest-client-reactive-jackson + - io.quarkus:quarkus-rest-client-reactive-jsonb id: resteasy-reactive-virtual-threads type: howto url: /guides/resteasy-reactive-virtual-threads @@ -275,13 +526,26 @@ types: - title: Building a Native Executable filename: building-native-image.adoc summary: Build native executables with GraalVM or Mandrel. - categories: "native, getting-started" + categories: "getting-started, native" + topics: + - native + - graalvm + - mandrel + extensions: + - io.quarkus:quarkus-core type: tutorial url: /guides/building-native-image - title: Collect metrics using Micrometer filename: telemetry-micrometer-tutorial.adoc summary: "Create an application that uses the Micrometer metrics library to collect runtime, extension and application metrics and expose them as a Prometheus (OpenMetrics) endpoint." categories: observability + topics: + - observability + - micrometer + - prometheus + extensions: + - io.quarkus:quarkus-micrometer-registry-prometheus + - io.quarkus:quarkus-micrometer id: telemetry-micrometer-tutorial type: tutorial url: /guides/telemetry-micrometer-tutorial @@ -289,12 +553,17 @@ types: filename: getting-started.adoc summary: Discover how to create your first Quarkus application. categories: getting-started + topics: + - getting-started type: tutorial url: /guides/getting-started - title: Creating a tutorial filename: doc-create-tutorial.adoc summary: "Create a new tutorial that guides users through creating, running, and testing a Quarkus application that uses annotations from an imaginary extension." categories: contributing + topics: + - internals + - documentation id: doc-create-tutorial type: tutorial url: /guides/doc-create-tutorial @@ -302,19 +571,37 @@ types: filename: getting-started-reactive.adoc summary: Learn more about developing reactive applications with Quarkus. categories: getting-started + topics: + - getting-started + - reactive type: tutorial url: /guides/getting-started-reactive - title: Protect a service application by using OpenID Connect (OIDC) Bearer token authentication filename: security-oidc-bearer-token-authentication-tutorial.adoc summary: Use the Quarkus OpenID Connect (OIDC) extension to secure a Jakarta REST application with Bearer token authentication. categories: security + topics: + - security + - oidc + - bearer-token + - keycloak + - authentication + extensions: + - io.quarkus:quarkus-oidc id: security-oidc-bearer-token-authentication-tutorial type: tutorial url: /guides/security-oidc-bearer-token-authentication-tutorial - title: Protect a web application by using OpenID Connect (OIDC) authorization code flow filename: security-oidc-code-flow-authentication-tutorial.adoc summary: "With the Quarkus OpenID Connect (OIDC) extension, you can protect application HTTP endpoints by using the OIDC Authorization Code Flow mechanism." - categories: "web, security" + categories: "security, web" + topics: + - security + - oidc + - keycloak + - authorization + extensions: + - io.quarkus:quarkus-oidc id: security-oidc-code-flow-authentication-tutorial type: tutorial url: /guides/security-oidc-code-flow-authentication-tutorial @@ -322,12 +609,25 @@ types: filename: ide-tooling.adoc summary: Learn more about Quarkus integrations in IDEs. categories: getting-started + topics: + - ide + - tooling type: tutorial url: /guides/ide-tooling - title: Secure a Quarkus application with Basic authentication and Jakarta Persistence filename: security-basic-authentication-tutorial.adoc summary: Secure your Quarkus application endpoints by combining the built-in Quarkus Basic authentication with the Jakarta Persistence identity provider to enable role-based access control (RBAC). - categories: "security, getting-started" + categories: "getting-started, security" + topics: + - security + - authentication + - basic-authentication + - http + extensions: + - io.quarkus:quarkus-vertx-http + - io.quarkus:quarkus-elytron-security-jdbc + - io.quarkus:quarkus-elytron-security-ldap + - io.quarkus:quarkus-security-jpa-reactive id: security-basic-authentication-tutorial type: tutorial url: /guides/security-basic-authentication-tutorial @@ -335,12 +635,17 @@ types: filename: tooling.adoc summary: Explore the Quarkus developer toolchain which makes Quarkus development so fast and enjoyable. categories: getting-started + topics: + - tooling type: tutorial url: /guides/tooling - title: Your second Quarkus application filename: getting-started-dev-services.adoc summary: Discover some of the features that make developing with Quarkus a joyful experience. - categories: "data, core, getting-started" + categories: "core, data, getting-started" + topics: + - getting-started + - devservices id: getting-started-dev-services-tutorial type: tutorial url: /guides/getting-started-dev-services @@ -349,24 +654,54 @@ types: filename: aws-lambda.adoc summary: This guide explains how you can deploy Quarkus-based AWS Lambdas. categories: cloud + topics: + - aws + - lambda + - serverless + - function + - cloud + extensions: + - io.quarkus:quarkus-amazon-lambda type: guide url: /guides/aws-lambda - title: AWS Lambda SnapStart Configuration filename: aws-lambda-snapstart.adoc summary: This document explains how to optimize your AWS Lambda application for SnapStart categories: cloud + topics: + - aws + - lambda + - serverless + - function + - snapstart + - cloud type: guide url: /guides/aws-lambda-snapstart - title: "AWS Lambda with RESTEasy Reactive, Undertow, or Reactive Routes" filename: aws-lambda-http.adoc summary: "This guide explains how you can deploy Vert.x Web, Servlet, or RESTEasy microservices as an AWS Lambda." categories: cloud + topics: + - aws + - lambda + - serverless + - function + - cloud + extensions: + - io.quarkus:quarkus-amazon-lambda + - io.quarkus:quarkus-amazon-lambda-http type: guide url: /guides/aws-lambda-http - title: Accessing application properties with Spring Boot properties API filename: spring-boot-properties.adoc summary: Use Spring Boot's `@ConfigurationProperties` in place of MicroProfile Config annotations categories: compatibility + topics: + - spring + - configuration + - compatibility + extensions: + - io.quarkus:quarkus-spring-boot-properties type: guide url: /guides/spring-boot-properties - title: All configuration options @@ -379,30 +714,55 @@ types: filename: camel.adoc summary: This guide covers the systems integration with Apache Camel categories: integration + topics: + - camel + - integration type: guide url: /guides/camel - title: Apache Kafka Reference Guide filename: kafka.adoc summary: This reference guide provides an in-depth look on Apache Kafka and Smallrye Reactive Messaging framework. categories: messaging + topics: + - messaging + - kafka + - reactive-messaging + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-kafka type: guide url: /guides/kafka - title: Apache Pulsar Reference Guide filename: pulsar.adoc summary: This reference guide provides an in-depth look on Apache Pulsar and Smallrye Reactive Messaging framework. categories: messaging + topics: + - messaging + - reactive-messaging + - pulsar + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-pulsar type: guide url: /guides/pulsar - title: AppCDS filename: appcds.adoc summary: This reference guide explains how to enable AppCDS with Quarkus. - categories: "core, cloud" + categories: "cloud, core" + topics: + - appcds + - serverless + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/appcds - title: Application Data Caching filename: cache.adoc summary: This guide explains how to cache expensive method calls of your CDI beans using simple annotations. categories: data + topics: + - cache + - data + extensions: + - io.quarkus:quarkus-cache type: guide url: /guides/cache - title: Application Initialization and Termination @@ -410,24 +770,47 @@ types: summary: You often need to execute custom actions when the application starts and clean up everything when the application stops. keywords: lifecycle event categories: core + topics: + - lifecycle + - observers + extensions: + - io.quarkus:quarkus-core + - io.quarkus:quarkus-arc type: guide url: /guides/lifecycle - title: Automate Quarkus deployment with Ansible filename: ansible.adoc summary: Build and deploy your Quarkus App using Ansible categories: command-line + topics: + - ansible + - devops type: guide url: /guides/ansible - title: Azure Functions filename: azure-functions.adoc summary: Integrate Quarkus with the Microsoft Azure functions that you have written. categories: cloud + topics: + - azure + - serverless + - function + - cloud + extensions: + - io.quarkus:quarkus-azure-functions type: guide url: /guides/azure-functions - title: "Azure Functions with RESTEasy Reactive, Undertow, or Reactive Routes" filename: azure-functions-http.adoc summary: "Deploy Vert.x Web, Servlet, or RESTEasy microservices as a Microsoft Azure Function." categories: cloud + topics: + - azure + - serverless + - function + - cloud + extensions: + - io.quarkus:quarkus-azure-functions-http type: guide url: /guides/azure-functions-http - title: Build Items @@ -439,99 +822,189 @@ types: - title: Build analytics filename: build-analytics.adoc summary: This guide presents what build analytics is and how to configure it. + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/build-analytics - title: "Build, Sign and Encrypt JSON Web Tokens" filename: security-jwt-build.adoc summary: "According to RFC7519, JSON Web Token (JWT) is a compact, URL-safe means of representing claims which are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code(MAC) and/or encrypted." + categories: security + topics: + - security + - jwt + extensions: + - io.quarkus:quarkus-smallrye-jwt-build type: guide url: /guides/security-jwt-build - title: Building Quarkus apps with Quarkus Command Line Interface (CLI) filename: cli-tooling.adoc summary: "Use the Quarkus CLI to create, build, run, and manage extensions for Quarkus projects." categories: tooling + topics: + - cli + - tooling type: guide url: /guides/cli-tooling - title: Building my first extension filename: building-my-first-extension.adoc summary: Learn step by step how to build a simple extension. categories: writing-extensions + topics: + - extensions type: guide url: /guides/building-my-first-extension - title: CDI Integration Guide filename: cdi-integration.adoc summary: Learn how to integrate your extension with Quarkus' CDI container. categories: writing-extensions + topics: + - cdi + - arc + - injection + extensions: + - io.quarkus:quarkus-arc type: guide url: /guides/cdi-integration - title: "Centralized log management (Graylog, Logstash, Fluentd)" filename: centralized-log-management.adoc summary: This guide explains how to centralize your logs with Logstash or Fluentd using the Graylog Extended Log Format (GELF). categories: observability + topics: + - observability + - logging + extensions: + - io.quarkus:quarkus-logging-gelf type: guide url: /guides/centralized-log-management - title: Command Mode with Picocli filename: picocli.adoc summary: Simplify command line applications creation with the Picocli extension. categories: command-line + topics: + - command-line + - cli + - picocli + extensions: + - io.quarkus:quarkus-picocli type: guide url: /guides/picocli - title: Compressing native executables using UPX filename: upx.adoc summary: Ultimate Packer for eXecutables (UPX) is a compression tool reducing the size of executables. + categories: core + topics: + - tooling + - native + - compression + - upx type: guide url: /guides/upx - title: Conditional Extension Dependencies filename: conditional-extension-dependencies.adoc summary: Trigger the inclusion on additional extensions based on certain conditions. categories: writing-extensions + topics: + - extensions + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/conditional-extension-dependencies - title: Configuring Your Application filename: config.adoc summary: Hardcoded values in your code is a no go (even if we all did it at some point ;-)). categories: core + topics: + - configuration + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/config - title: Connecting to an Elasticsearch cluster filename: elasticsearch.adoc summary: This guide covers how to interact with an Elasticsearch cluster using the low level REST client or the Elasticsearch Java client. categories: data + topics: + - data + - search + - elasticsearch + - nosql + extensions: + - io.quarkus:quarkus-elasticsearch-java-client + - io.quarkus:quarkus-elasticsearch-rest-client type: guide url: /guides/elasticsearch - title: Consuming a gRPC Service filename: grpc-service-consumption.adoc summary: This guide explains how to consume gRPC services in your Quarkus application. categories: serialization + topics: + - grpc + extensions: + - io.quarkus:quarkus-grpc type: guide url: /guides/grpc-service-consumption - title: Container Images filename: container-image.adoc summary: "Learn how to build and push container images with Jib, OpenShift or Docker as part of the Quarkus build." categories: cloud + topics: + - devops + - cloud + extensions: + - io.quarkus:quarkus-container-image-openshift + - io.quarkus:quarkus-container-image-jib + - io.quarkus:quarkus-container-image-docker + - io.quarkus:quarkus-container-image-buildpack type: guide url: /guides/container-image - title: Context Propagation in Quarkus filename: context-propagation.adoc summary: Learn more about how you can pass contextual information with SmallRye Context Propagation. categories: core + topics: + - context-propagation + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/context-propagation - title: Continuous Testing filename: continuous-testing.adoc summary: Get early test feedback with Continuous Testing. categories: core + topics: + - testing + - dev-ui + - tooling + - devmode + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/continuous-testing - title: Cross-Site Request Forgery Prevention filename: security-csrf-prevention.adoc summary: Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they are currently authenticated. + categories: security + topics: + - security + - csrf + - http + extensions: + - io.quarkus:quarkus-csrf-reactive type: guide url: /guides/security-csrf-prevention - title: Deploying on OpenShift filename: deploying-to-openshift.adoc summary: This guide covers how to deploy a native application on OpenShift. categories: "cloud, native" + topics: + - devops + - kubernetes + - openshift + - cloud + - deployment + extensions: + - io.quarkus:quarkus-openshift id: deploy-openshift type: guide url: /guides/deploying-to-openshift @@ -539,30 +1012,57 @@ types: filename: deploying-to-google-cloud.adoc summary: This guide explains how to deploy a Quarkus application to Google Cloud. categories: cloud + topics: + - devops + - google + - gcp + - cloud + - deployment type: guide url: /guides/deploying-to-google-cloud - title: Deploying to Heroku filename: deploying-to-heroku.adoc summary: Deploy your Quarkus applications on Heroku. categories: cloud + topics: + - devops + - heroku + - cloud + - deployment type: guide url: /guides/deploying-to-heroku - title: Deploying to Microsoft Azure Cloud filename: deploying-to-azure-cloud.adoc summary: Deploy a Quarkus application to the Microsoft Azure cloud platform. categories: cloud + topics: + - devops + - azure + - cloud + - deployment type: guide url: /guides/deploying-to-azure-cloud - title: Deploying your gRPC Service in Kubernetes filename: grpc-kubernetes.adoc summary: This guide explains how to deploy your gRPC services in Quarkus to Kubernetes. categories: serialization + topics: + - grpc + - kubernetes + extensions: + - io.quarkus:quarkus-grpc + - io.quarkus:quarkus-kubernetes type: guide url: /guides/grpc-kubernetes - title: Dev Services Overview filename: dev-services.adoc summary: A list of all extensions that support Dev Services and their configuration options. categories: core + topics: + - devservices + - tooling + - testing + - devmode type: guide url: /guides/dev-services - title: Dev Services and UI for OpenID Connect (OIDC) @@ -570,229 +1070,544 @@ types: summary: Start Keycloak or other providers automatically in dev and test modes. keywords: sso oidc security keycloak categories: security + topics: + - security + - oidc + - keycloak + - devservices + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-oidc type: guide url: /guides/security-openid-connect-dev-services - title: Dev Services for AMQP filename: amqp-dev-services.adoc summary: Start AMQP automatically in dev and test modes. categories: messaging + topics: + - messaging + - amqp + - devservices + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-amqp type: guide url: /guides/amqp-dev-services - title: Dev Services for Apicurio Registry filename: apicurio-registry-dev-services.adoc summary: Start Apicurio Registry automatically in dev and test modes. categories: messaging + topics: + - messaging + - kafka + - apicurio + - registry + - devservices + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-apicurio-registry-avro + - io.quarkus:quarkus-smallrye-reactive-messaging-kafka type: guide url: /guides/apicurio-registry-dev-services - title: Dev Services for Databases filename: databases-dev-services.adoc summary: "When testing or running in dev mode Quarkus can provide you with a zero-config database out of the box, a feature we refer to as Dev Services." categories: "data, tooling" + topics: + - devservices + - data + - database + - datasource + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-agroal + - io.quarkus:quarkus-reactive-mysql-client + - io.quarkus:quarkus-reactive-oracle-client + - io.quarkus:quarkus-reactive-pg-client + - io.quarkus:quarkus-jdbc-db2 + - io.quarkus:quarkus-jdbc-derby + - io.quarkus:quarkus-jdbc-h2 + - io.quarkus:quarkus-jdbc-mariadb + - io.quarkus:quarkus-jdbc-mssql + - io.quarkus:quarkus-jdbc-mysql + - io.quarkus:quarkus-jdbc-oracle + - io.quarkus:quarkus-jdbc-postgresql type: guide url: /guides/databases-dev-services - title: Dev Services for Elasticsearch filename: elasticsearch-dev-services.adoc summary: Start Elasticsearch automatically in dev and test modes categories: data + topics: + - data + - search + - elasticsearch + - nosql + - devservices + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-elasticsearch-java-client + - io.quarkus:quarkus-elasticsearch-rest-client + - io.quarkus:quarkus-hibernate-search-orm-elasticsearch type: guide url: /guides/elasticsearch-dev-services - title: Dev Services for Infinispan filename: infinispan-dev-services.adoc summary: Start Infinispan automatically in dev and test modes. categories: data + topics: + - devservices + - data + - infinispan + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-infinispan-client type: guide url: /guides/infinispan-dev-services - title: Dev Services for Kafka filename: kafka-dev-services.adoc summary: Start Apache Kafka automatically in dev and test modes. categories: messaging + topics: + - messaging + - kafka + - devservices + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-kafka-client + - io.quarkus:quarkus-smallrye-reactive-messaging-kafka type: guide url: /guides/kafka-dev-services - title: Dev Services for Kubernetes filename: kubernetes-dev-services.adoc summary: Start a Kubernetes API server automatically in dev and test modes. categories: cloud + topics: + - devservices + - kubernetes + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-kubernetes-client type: guide url: /guides/kubernetes-dev-services - title: Dev Services for Pulsar filename: pulsar-dev-services.adoc summary: With Quarkus Smallrye Reactive Messaging Pulsar extension (quarkus-smallrye-reactive-messaging-pulsar) Dev Services for Pulsar automatically starts a Pulsar broker in dev mode and when running tests. + categories: messaging + topics: + - messaging + - reactive-messaging + - pulsar + - devservices + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-pulsar type: guide url: /guides/pulsar-dev-services - title: Dev Services for RabbitMQ filename: rabbitmq-dev-services.adoc summary: Dev Services for RabbitMQ automatically starts a RabbitMQ broker in dev mode and when running tests. + categories: messaging + topics: + - messaging + - reactive-messaging + - rabbitmq + - devservices + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-rabbitmq type: guide url: /guides/rabbitmq-dev-services - title: Dev Services for Redis filename: redis-dev-services.adoc summary: Start Redis automatically in dev and test modes. categories: data + topics: + - data + - redis + - nosql + - devservices + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-redis-client type: guide url: /guides/redis-dev-services - - title: Dev UI - filename: dev-ui-v2.adoc - summary: Learn how to get your extension to contribute features to the Dev UI (v2). - categories: writing-extensions - type: guide - url: /guides/dev-ui-v2 - title: Dev UI filename: dev-ui.adoc - summary: Learn how to get your extension contribute features to the Dev UI (v1). + summary: Learn how to get your extension to contribute features to the Dev UI (v2). categories: writing-extensions + topics: + - dev-ui + - tooling + - testing + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/dev-ui - title: Extending Configuration Support filename: config-extending-support.adoc summary: Extend and customize the Configuration. categories: core + topics: + - configuration + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/config-extending-support - title: Extension Capabilities filename: capabilities.adoc summary: How capabilities are implemented and used in Quarkus. categories: writing-extensions + topics: + - extensions + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/capabilities - title: Extension codestart filename: extension-codestart.adoc summary: Provide users with initial code for extensions when generating Quarkus applications on code.quarkus.io and all the Quarkus tooling. categories: writing-extensions + topics: + - extensions + - codestarts + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/extension-codestart - title: Extension for Spring Data API filename: spring-data-jpa.adoc summary: "While you are encouraged to use Hibernate ORM with Panache for your data layer, Quarkus provides a compatibility layer for Spring Data JPA in the form of the spring-data-jpa extension." categories: compatibility + topics: + - spring + - data + - hibernate-orm + - jpa + - compatibility + extensions: + - io.quarkus:quarkus-spring-data-jpa type: guide url: /guides/spring-data-jpa - title: Extension for Spring Data REST filename: spring-data-rest.adoc summary: Spring Data REST simplifies the creation of CRUD applications based on our Spring Data compatibility layer. categories: compatibility + topics: + - spring + - data + - hibernate-orm + - jpa + - rest + - compatibility + extensions: + - io.quarkus:quarkus-spring-data-rest type: guide url: /guides/spring-data-rest - title: Funqy filename: funqy.adoc summary: "This guide explains basics of the Funqy framework, a simple portable cross-provider cloud function API." categories: cloud + topics: + - serverless + - function + - cloud + - funqy type: guide url: /guides/funqy - title: Funqy AWS Lambda Binding filename: funqy-aws-lambda.adoc summary: This guide explains Funqy's AWS Lambda binding. categories: cloud + topics: + - aws + - lambda + - serverless + - function + - cloud + - funqy + extensions: + - io.quarkus:quarkus-funqy-amazon-lambda type: guide url: /guides/funqy-aws-lambda - title: Funqy Google Cloud Functions filename: funqy-gcp-functions.adoc summary: This guide explains Funqy's Google Cloud Platform Functions binding. categories: cloud + topics: + - google + - gcp + - serverless + - function + - cloud + - funqy + extensions: + - io.quarkus:quarkus-funqy-http + - io.quarkus:quarkus-funqy-google-cloud-functions type: guide url: /guides/funqy-gcp-functions - title: Funqy HTTP Binding (Standalone) filename: funqy-http.adoc summary: This guide explains Funqy's HTTP binding. categories: cloud + topics: + - serverless + - function + - cloud + - funqy + extensions: + - io.quarkus:quarkus-funqy-http type: guide url: /guides/funqy-http - title: Funqy HTTP Binding with AWS Lambda  filename: funqy-aws-lambda-http.adoc summary: This guide explains Funqy's AWS Lambda HTTP binding. categories: cloud + topics: + - aws + - lambda + - serverless + - function + - cloud + - funqy + extensions: + - io.quarkus:quarkus-funqy-http + - io.quarkus:quarkus-amazon-lambda-http type: guide url: /guides/funqy-aws-lambda-http - title: Funqy HTTP Binding with Azure Functions filename: funqy-azure-functions-http.adoc summary: Use Funqy HTTP binding with Microsoft Azure Functions to deploy your serverless Quarkus applications. categories: cloud + topics: + - azure + - serverless + - function + - cloud + - funqy + extensions: + - io.quarkus:quarkus-azure-functions-http type: guide url: /guides/funqy-azure-functions-http - title: Funqy HTTP Binding with Google Cloud Functions filename: funqy-gcp-functions-http.adoc summary: This guide explains Funqy's Google Cloud Platform Functions HTTP binding. categories: cloud + topics: + - google + - gcp + - serverless + - function + - cloud + - funqy + extensions: + - io.quarkus:quarkus-funqy-http + - io.quarkus:quarkus-google-cloud-functions-http type: guide url: /guides/funqy-gcp-functions-http - title: Funqy Knative Events Binding filename: funqy-knative-events.adoc summary: This guide explains Funqy's Knative Events binding. categories: cloud + topics: + - serverless + - function + - cloud + - funqy + extensions: + - io.quarkus:quarkus-funqy-knative-events type: guide url: /guides/funqy-knative-events - title: Generating Jakarta REST resources with Panache filename: rest-data-panache.adoc summary: Hibernate ORM REST Data with Panache simplifies the creation of CRUD applications based on Jakarta REST and Hibernate ORM. categories: web + topics: + - rest + - hibernate-orm + - panache + - mongodb + - sql + - jdbc + - nosql + extensions: + - io.quarkus:quarkus-hibernate-orm-rest-data-panache + - io.quarkus:quarkus-hibernate-reactive-rest-data-panache + - io.quarkus:quarkus-mongodb-rest-data-panache type: guide url: /guides/rest-data-panache - title: Getting Started to SmallRye Reactive Messaging with AMQP 1.0 filename: amqp.adoc summary: This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with AMQP. categories: messaging + topics: + - messaging + - amqp + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-amqp type: guide url: /guides/amqp - title: Getting Started to SmallRye Reactive Messaging with Apache Kafka filename: kafka-reactive-getting-started.adoc summary: This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with Apache Kafka. categories: messaging + topics: + - messaging + - kafka + - reactive-messaging + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-kafka type: guide url: /guides/kafka-reactive-getting-started - title: Getting Started to SmallRye Reactive Messaging with Apache Pulsar filename: pulsar-getting-started.adoc summary: This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with Apache Pulsar. categories: messaging + topics: + - messaging + - reactive-messaging + - pulsar + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-pulsar type: guide url: /guides/pulsar-getting-started - title: Getting Started to SmallRye Reactive Messaging with RabbitMQ filename: rabbitmq.adoc summary: This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with RabbitMQ. + categories: messaging + topics: + - messaging + - reactive-messaging + - rabbitmq + - devservices + - tooling + - testing + - devmode + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-rabbitmq type: guide url: /guides/rabbitmq - title: Getting Started with SmallRye Stork filename: stork.adoc summary: The essence of distributed systems resides in the interaction between services. + categories: cloud + topics: + - service-discovery + - load-balancing + - stork + extensions: + - io.quarkus:quarkus-smallrye-stork type: guide url: /guides/stork - title: Getting Started with gRPC filename: grpc-getting-started.adoc summary: This guide explains how to start using gRPC in your Quarkus application. categories: serialization + topics: + - grpc + extensions: + - io.quarkus:quarkus-grpc type: guide url: /guides/grpc-getting-started - title: Google Cloud Functions (Serverless) filename: gcp-functions.adoc summary: This guide explains how you can deploy Quarkus-based Google Cloud Functions. categories: cloud + topics: + - google + - gcp + - serverless + - function + - cloud + extensions: + - io.quarkus:quarkus-google-cloud-functions type: guide url: /guides/gcp-functions - title: "Google Cloud Functions (Serverless) with RESTEasy Reactive, Undertow, or Reactive Routes" filename: gcp-functions-http.adoc summary: "This guide explains how you can deploy Vert.x Web, Servlet, or RESTEasy microservices as a Google Cloud Function." categories: cloud + topics: + - google + - gcp + - serverless + - function + - cloud + extensions: + - io.quarkus:quarkus-google-cloud-functions-http type: guide url: /guides/gcp-functions-http - title: Hibernate Search guide filename: hibernate-search-orm-elasticsearch.adoc summary: Hibernate Search allows you to index your entities in an Elasticsearch cluster and easily offer full text search in all your Hibernate ORM-based applications. categories: data + topics: + - data + - hibernate-search + - elasticsearch + - search + - nosql + extensions: + - io.quarkus:quarkus-hibernate-search-orm-elasticsearch type: guide url: /guides/hibernate-search-orm-elasticsearch - title: How dev mode differs from a production application filename: dev-mode-differences.adoc summary: How dev mode differs from a production application categories: architecture + topics: + - internals + - devmode + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/dev-mode-differences - title: Implementing a gRPC Service filename: grpc-service-implementation.adoc summary: This guide explains how to implement gRPC services in your Quarkus application. categories: serialization + topics: + - grpc + extensions: + - io.quarkus:quarkus-grpc type: guide url: /guides/grpc-service-implementation - title: Initialization tasks filename: init-tasks.adoc summary: This reference guide explains how to configure initialization tasks + topics: + - init + - kubernetes + - openshift + - liquibase + - flyway + extensions: + - io.quarkus:quarkus-kubernetes + - io.quarkus:quarkus-openshift + - io.quarkus:quarkus-flyway + - io.quarkus:quarkus-liquibase type: guide url: /guides/init-tasks - title: Introduction to Contexts and Dependency Injection (CDI) @@ -800,30 +1615,66 @@ types: summary: "Quarkus DI solution is based on the [Jakarta Contexts and Dependency Injection 4.0](https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html) specification." keywords: qualifier event interceptor observer arc categories: core + topics: + - cdi + - arc + - injection + - interceptor + - observer + extensions: + - io.quarkus:quarkus-arc type: guide url: /guides/cdi - title: Kafka Dev UI filename: kafka-dev-ui.adoc summary: Dev UI extension for Apache Kafka for development purposes. categories: messaging + topics: + - messaging + - kafka + - dev-ui + - devmode + extensions: + - io.quarkus:quarkus-kafka-client + - io.quarkus:quarkus-smallrye-reactive-messaging-kafka type: guide url: /guides/kafka-dev-ui - title: Kubernetes Client filename: kubernetes-client.adoc summary: This guide demonstrates how to use the Fabric8 Kubernetes client to interact with your Kubernetes cluster. categories: cloud + topics: + - kubernetes + - openshift + - kubernetes-client + extensions: + - io.quarkus:quarkus-kubernetes-client type: guide url: /guides/kubernetes-client - title: Kubernetes Config filename: kubernetes-config.adoc summary: Use ConfigMaps as a configuration source for your Quarkus applications. categories: cloud + topics: + - kubernetes + - openshift + - configuration + - configmap + extensions: + - io.quarkus:quarkus-kubernetes-config type: guide url: /guides/kubernetes-config - title: Kubernetes extension filename: deploying-to-kubernetes.adoc summary: This guide covers how to deploy a native application on Kubernetes. categories: "cloud, native" + topics: + - devops + - kubernetes + - cloud + - deployment + extensions: + - io.quarkus:quarkus-kubernetes id: deploy-kubernetes type: guide url: /guides/deploying-to-kubernetes @@ -831,145 +1682,266 @@ types: filename: config-mappings.adoc summary: Group multiple configuration properties into an object. categories: core + topics: + - configuration + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/config-mappings - title: Measuring Performance filename: performance-measure.adoc summary: This guide explains how to best measure the footprint of a Quarkus application. categories: miscellaneous + topics: + - internals + - performance type: guide url: /guides/performance-measure - title: Measuring the coverage of your tests filename: tests-with-coverage.adoc summary: This guide explains how to measure the test coverage of your Quarkus application. categories: tooling + topics: + - tooling + - testing + - coverage + - jacoco + extensions: + - io.quarkus:quarkus-jacoco type: guide url: /guides/tests-with-coverage - title: Migrating to RESTEasy Reactive filename: resteasy-reactive-migration.adoc summary: "Migrating from RESTEasy Classic to RESTEasy Reactive is straightforward in most cases, however there are a few cases that require some attention." + categories: web + topics: + - rest + - rest-client + - resteasy-reactive + extensions: + - io.quarkus:quarkus-resteasy-reactive + - io.quarkus:quarkus-resteasy-reactive-jackson + - io.quarkus:quarkus-resteasy-reactive-jsonb + - io.quarkus:quarkus-rest-client-reactive + - io.quarkus:quarkus-rest-client-reactive-jackson + - io.quarkus:quarkus-rest-client-reactive-jsonb type: guide url: /guides/resteasy-reactive-migration - title: Mutiny - Async for bare mortal filename: mutiny-primer.adoc summary: "Mutiny is an intuitive, reactive programming library." + topics: + - mutiny + - reactive + extensions: + - io.quarkus:quarkus-mutiny type: guide url: /guides/mutiny-primer - title: Narayana LRA Participant Support filename: lra.adoc summary: This guides covers the usage of LRA to coordinate activities across services. categories: data + topics: + - data + - lra + - narayana + extensions: + - io.quarkus:quarkus-narayana-lra type: guide url: /guides/lra - title: OpenID Connect Client and Token Propagation Quickstart filename: security-openid-connect-client.adoc summary: "This guide explains how to use OpenID Connect and OAuth2 Client and Filters to acquire, refresh and propagate access tokens." categories: security + topics: + - security + - oidc + - client + extensions: + - io.quarkus:quarkus-oidc-client type: guide url: /guides/security-openid-connect-client - - title: OptaPlanner - Using AI to optimize a schedule with OptaPlanner - filename: optaplanner.adoc - summary: This guide walks you through the process of creating a Quarkus application with OptaPlanner's constraint solving Artificial Intelligence (AI). - categories: business-automation - type: guide - url: /guides/optaplanner - title: Packaging And Releasing With JReleaser filename: jreleaser.adoc summary: This guide covers packaging and releasing CLI applications using the JReleaser tool. categories: tooling + topics: + - tooling type: guide url: /guides/jreleaser - title: Platform filename: platform.adoc summary: Learn more about what we call a Platform in the Quarkus world. categories: architecture + topics: + - internals + - platform type: guide url: /guides/platform - title: Quarkus Base Runtime Image filename: quarkus-runtime-base-image.adoc summary: "To ease the containerization of native executables, Quarkus provides a base image providing the requirements to run these executables." + categories: tooling + topics: + - docker + - podman + - images type: guide url: /guides/quarkus-runtime-base-image - title: Quarkus Extension Metadata filename: extension-metadata.adoc summary: Quarkus extensions are distributed as Maven JAR artifacts that application and other libraries may depend on. + categories: writing-extensions + topics: + - extensions + - codestarts + extensions: + - io.quarkus:quarkus-core type: guide url: /guides/extension-metadata - title: Quarkus Extension Registry filename: extension-registry-user.adoc summary: Learn more about the notion of extension registry and how you can use your own. categories: architecture + topics: + - internals + - extensions type: guide url: /guides/extension-registry-user - title: Quarkus Extension for Spring Cache API filename: spring-cache.adoc summary: "While you are encouraged to use the Cache extension for your application-level caching, Quarkus provides a compatibility layer for Spring Cache in the form of the spring-cache extension." categories: compatibility + topics: + - spring + - cache + - compatibility + extensions: + - io.quarkus:quarkus-spring-cache type: guide url: /guides/spring-cache - title: Quarkus Extension for Spring DI API filename: spring-di.adoc summary: "While you are encouraged to use CDI annotations for injection, Quarkus provides a compatibility layer for Spring dependency injection in the form of the spring-di extension." categories: compatibility + topics: + - spring + - cdi + - injection + - compatibility + extensions: + - io.quarkus:quarkus-spring-di type: guide url: /guides/spring-di - title: Quarkus Extension for Spring Scheduling API filename: spring-scheduled.adoc summary: "While you are encouraged to use the Scheduler or Quartz extensions to schedule tasks, Quarkus provides a compatibility layer for Spring Scheduled in the form of the spring-scheduled extension." categories: compatibility + topics: + - spring + - scheduling + - compatibility + extensions: + - io.quarkus:quarkus-spring-scheduled type: guide url: /guides/spring-scheduled - title: Quarkus Extension for Spring Security API filename: spring-security.adoc summary: "While you are encouraged to use the Quarkus Security layer to secure your applications, Quarkus provides a compatibility layer for Spring Security in the form of the spring-security extension." categories: compatibility + topics: + - spring + - security + - compatibility + extensions: + - io.quarkus:quarkus-spring-security type: guide url: /guides/spring-security - title: Quarkus Extension for Spring Web API filename: spring-web.adoc summary: "While you are encouraged to use Jakarta REST annotations for defining REST endpoints, Quarkus provides a compatibility layer for Spring Web in the form of the spring-web extension." categories: compatibility + topics: + - spring + - rest + - compatibility + extensions: + - io.quarkus:quarkus-spring-web type: guide url: /guides/spring-web - title: Quarkus Maven Plugin filename: quarkus-maven-plugin.adoc summary: "The Quarkus Maven Plugin builds the Quarkus applications, and provides helpers to launch dev mode or build native executables." + topics: + - maven + - tooling type: guide url: /guides/quarkus-maven-plugin - title: Quarkus Reactive Architecture filename: quarkus-reactive-architecture.adoc summary: Learn more about Quarkus reactive architecture. categories: architecture + topics: + - internals + - reactive type: guide url: /guides/quarkus-reactive-architecture - title: Quarkus Security with Jakarta Persistence filename: security-jpa.adoc summary: "Quarkus provides a Jakarta Persistence (formerly known as JPA) identity provider, similar to the JDBC identity provider, suitable for use with the Basic and Form-based Quarkus Security mechanisms, which require a combination of username and password credentials." categories: security + topics: + - security + - identity-providers + - sql + - database + - jpa + - jdbc + extensions: + - io.quarkus:quarkus-security-jpa-reactive id: security-jpa type: guide url: /guides/security-jpa - title: Quarkus Virtual Thread support for gRPC services filename: grpc-virtual-threads.adoc summary: This guide explains how to benefit from Java virtual threads when implementing a gRPC service. + topics: + - grpc + - virtual-threads + extensions: + - io.quarkus:quarkus-grpc type: guide url: /guides/grpc-virtual-threads - title: Quarkus Virtual Thread support with Reactive Messaging filename: messaging-virtual-threads.adoc summary: This guide explains how to benefit from Java virtual threads when writing message processing applications in Quarkus. + categories: messaging + topics: + - messaging + - kafka + - reactive-messaging + - virtual-threads + extensions: + - io.quarkus:quarkus-smallrye-reactive-messaging-kafka type: guide url: /guides/messaging-virtual-threads - title: Quarkus and Gradle filename: gradle-tooling.adoc summary: Develop and build your Quarkus application with Gradle - categories: "tooling, native" + categories: "native, tooling" + topics: + - gradle + - tooling id: gradle-tooling type: guide url: /guides/gradle-tooling - title: Quarkus and Maven filename: maven-tooling.adoc summary: Develop and build your Quarkus application with Maven - categories: "tooling, native" + categories: "native, tooling" + topics: + - maven + - tooling id: maven-tooling type: guide url: /guides/maven-tooling @@ -977,146 +1949,303 @@ types: filename: qute.adoc summary: Learn more about how you can use templating in your applications with the Qute template engine. categories: miscellaneous + topics: + - templating + - qute + extensions: + - io.quarkus:quarkus-qute + - io.quarkus:quarkus-resteasy-qute + - io.quarkus:quarkus-resteasy-reactive-qute type: guide url: /guides/qute - title: RESTEasy Classic filename: resteasy.adoc + categories: web + topics: + - rest + - resteasy-classic + extensions: + - io.quarkus:quarkus-resteasy + - io.quarkus:quarkus-resteasy-jackson + - io.quarkus:quarkus-resteasy-jsonb type: guide url: /guides/resteasy - title: Re-augment a Quarkus Application filename: reaugmentation.adoc summary: Use mutable jars to rebuild your application with different build time configurations. categories: tooling + topics: + - mutable-jars + - tooling type: guide url: /guides/reaugmentation - title: Reactive SQL Clients filename: reactive-sql-clients.adoc summary: This guide covers how to use the Reactive SQL Clients in Quarkus. categories: data + topics: + - data + - database + - reactive + - sql + extensions: + - io.quarkus:quarkus-reactive-mysql-client + - io.quarkus:quarkus-reactive-oracle-client + - io.quarkus:quarkus-reactive-pg-client + - io.quarkus:quarkus-reactive-db2-client + - io.quarkus:quarkus-reactive-mssql-client type: guide url: /guides/reactive-sql-clients - title: Reading properties from Spring Cloud Config Server filename: spring-cloud-config-client.adoc summary: Quarkus provides a compatibility layer for Spring Cloud Config in the form of the spring-cloud-config-client extension. categories: compatibility + topics: + - spring + - cloud + - configuration + - compatibility + extensions: + - io.quarkus:quarkus-spring-cloud-config-client type: guide url: /guides/spring-cloud-config-client - title: Scheduling Periodic Tasks filename: scheduler.adoc summary: Modern applications often need to run specific tasks periodically. categories: miscellaneous + topics: + - scheduling + - cronjob + extensions: + - io.quarkus:quarkus-scheduler type: guide url: /guides/scheduler - title: Scheduling Periodic Tasks with Quartz filename: quartz.adoc summary: You need clustering support for your scheduled tasks? This guide explains how to use the Quartz extension for that. categories: miscellaneous + topics: + - scheduling + - cronjob + - quartz + extensions: + - io.quarkus:quarkus-quartz type: guide url: /guides/quartz - title: Scripting with Quarkus filename: scripting.adoc summary: Easy Quarkus-based scripting with jbang. categories: command-line + topics: + - scripting + - jbang type: guide url: /guides/scripting - title: Security Testing filename: security-testing.adoc summary: This document describes how to test Quarkus Security. + categories: security + topics: + - security + - testing + extensions: + - io.quarkus:quarkus-test-security type: guide url: /guides/security-testing - title: Security Tips and Tricks filename: security-customization.adoc + categories: security + topics: + - security + extensions: + - io.quarkus:quarkus-security type: guide url: /guides/security-customization - title: Sending emails using SMTP filename: mailer.adoc summary: Learn more about how you can send email from a Quarkus application with our reactive email client. categories: miscellaneous + topics: + - mail + - mailer + extensions: + - io.quarkus:quarkus-mailer type: guide url: /guides/mailer - title: Simplified Hibernate ORM with Panache filename: hibernate-orm-panache.adoc summary: Hibernate ORM is the de facto Jakarta Persistence implementation and offers you the full breadth of an Object Relational Mapper. categories: data + topics: + - data + - hibernate-orm + - panache + - sql + - jdbc + extensions: + - io.quarkus:quarkus-hibernate-orm-panache + - io.quarkus:quarkus-hibernate-orm type: guide url: /guides/hibernate-orm-panache - title: Simplified Hibernate ORM with Panache and Kotlin filename: hibernate-orm-panache-kotlin.adoc summary: This explains the specifics of using Hibernate ORM with Panache in a Kotlin project. - categories: "data, alt-languages" + categories: "alt-languages, data" + topics: + - data + - hibernate-orm + - panache + - kotlin + - sql + - jdbc + extensions: + - io.quarkus:quarkus-hibernate-orm-panache-kotlin + - io.quarkus:quarkus-hibernate-orm-panache + - io.quarkus:quarkus-hibernate-orm type: guide url: /guides/hibernate-orm-panache-kotlin - title: Simplified Hibernate Reactive with Panache filename: hibernate-reactive-panache.adoc summary: Simplified reactive ORM layer based on Hibernate Reactive. categories: data + topics: + - data + - hibernate-reactive + - panache + - sql + extensions: + - io.quarkus:quarkus-hibernate-reactive-panache + - io.quarkus:quarkus-hibernate-reactive type: guide url: /guides/hibernate-reactive-panache - title: Simplified MongoDB with Panache filename: mongodb-panache.adoc summary: This guide covers the usage of MongoDB using active records and repositories. categories: data + topics: + - data + - mongodb + - nosql + - panache + - kotlin + extensions: + - io.quarkus:quarkus-mongodb-panache + - io.quarkus:quarkus-mongodb-client type: guide url: /guides/mongodb-panache - title: Simplified MongoDB with Panache and Kotlin filename: mongodb-panache-kotlin.adoc summary: This guide covers the usage of MongoDB using active records and repositories in a Kotlin project. - categories: "data, alt-languages" + categories: "alt-languages, data" + topics: + - data + - mongodb + - nosql + - panache + - kotlin + extensions: + - io.quarkus:quarkus-mongodb-panache-kotlin + - io.quarkus:quarkus-mongodb-panache + - io.quarkus:quarkus-mongodb-client type: guide url: /guides/mongodb-panache-kotlin - title: SmallRye Fault Tolerance filename: smallrye-fault-tolerance.adoc summary: This guide demonstrates how your Quarkus application can utilize the SmallRye Fault Tolerance specification through the SmallRye Fault Tolerance extension. - categories: "web, observability" + categories: "observability, web" + topics: + - fault-tolerance + - resiliency + extensions: + - io.quarkus:quarkus-smallrye-fault-tolerance type: guide url: /guides/smallrye-fault-tolerance - title: SmallRye GraphQL filename: smallrye-graphql.adoc summary: This guide explains how to leverage SmallRye GraphQL to implement GraphQL services. categories: web + topics: + - graphql + extensions: + - io.quarkus:quarkus-smallrye-graphql type: guide url: /guides/smallrye-graphql - title: SmallRye GraphQL Client filename: smallrye-graphql-client.adoc summary: This guide explains how to leverage SmallRye GraphQL Client to consume GraphQL services. categories: web + topics: + - graphql + extensions: + - io.quarkus:quarkus-smallrye-graphql-client type: guide url: /guides/smallrye-graphql-client - title: SmallRye Health filename: smallrye-health.adoc summary: This guide demonstrates how your Quarkus application can utilize the SmallRye Health extension. categories: observability + topics: + - health + - observability + extensions: + - io.quarkus:quarkus-smallrye-health type: guide url: /guides/smallrye-health - title: SmallRye Metrics filename: smallrye-metrics.adoc summary: This guide demonstrates how your Quarkus application can utilize the SmallRye Metrics extension. categories: observability + topics: + - metrics + - observability + extensions: + - io.quarkus:quarkus-smallrye-metrics type: guide url: /guides/smallrye-metrics - title: Testing Your Application filename: getting-started-testing.adoc summary: "This guide covers testing in JVM mode, native mode, and injection of resources into tests" - categories: "tooling, core, native" + categories: "core, native, tooling" + topics: + - getting-started + - testing + - tooling id: testing type: guide url: /guides/getting-started-testing - title: Tips for writing native applications filename: writing-native-applications-tips.adoc summary: This guide is a collection of tips to help you solve the problems you encounter when compiling applications to native executable. - categories: "core, writing-extensions, native" + categories: "core, native, writing-extensions" + topics: + - native + - extensions type: guide url: /guides/writing-native-applications-tips - title: Using Apache Kafka Streams filename: kafka-streams.adoc summary: This guide demonstrates how your Quarkus application can utilize the Apache Kafka Streams API to implement stream processing applications based on Apache Kafka. categories: messaging + topics: + - messaging + - kafka + - kafka-streams + extensions: + - io.quarkus:quarkus-kafka-streams type: guide url: /guides/kafka-streams - title: Using Apache Kafka with Schema Registry and Avro filename: kafka-schema-registry-avro.adoc summary: "Use Apache Kafka, Avro serialized records, and connect to a schema registry." categories: messaging + topics: + - messaging + - kafka + - apicurio + - registry + extensions: + - io.quarkus:quarkus-apicurio-registry-avro + - io.quarkus:quarkus-smallrye-reactive-messaging-kafka type: guide url: /guides/kafka-schema-registry-avro - title: Using Blaze-Persistence @@ -1135,29 +2264,64 @@ types: filename: flyway.adoc summary: This guide covers how to use the Flyway extension to manage your schema migrations. categories: data + topics: + - flyway + - data + - schema-migration + - database + extensions: + - io.quarkus:quarkus-flyway type: guide url: /guides/flyway - title: Using Hibernate ORM and Jakarta Persistence filename: hibernate-orm.adoc summary: Hibernate ORM is the de facto Jakarta Persistence implementation and offers you the full breath of an Object Relational Mapper. categories: data + topics: + - data + - hibernate-orm + - sql + - jdbc + extensions: + - io.quarkus:quarkus-hibernate-orm type: guide url: /guides/hibernate-orm - title: Using Hibernate Reactive filename: hibernate-reactive.adoc summary: "Hibernate Reactive is a reactive API for Hibernate ORM, supporting non-blocking database drivers and a reactive style of interaction with the database." + topics: + - data + - hibernate-reactive + - sql + extensions: + - io.quarkus:quarkus-hibernate-reactive-panache + - io.quarkus:quarkus-hibernate-reactive type: guide url: /guides/hibernate-reactive - title: Using JMS filename: jms.adoc summary: "This guide demonstrates how your Quarkus application can use JMS messaging with AMQP 1.0 using Apache Qpid JMS, or using Apache ActiveMQ Artemis JMS." categories: messaging + topics: + - messaging + - jms + - artemis + - qpid + - activemq + extensions: + - org.amqphub.quarkus:quarkus-qpid-jms + - io.quarkiverse.artemis:quarkus-artemis-jms type: guide url: /guides/jms - title: Using JWT RBAC filename: security-jwt.adoc summary: This guide explains how your application can utilize SmallRye JWT to provide secured access to the Jakarta REST endpoints. categories: security + topics: + - security + - jwt + extensions: + - io.quarkus:quarkus-smallrye-jwt id: security-jwt type: guide url: /guides/security-jwt @@ -1166,23 +2330,50 @@ types: summary: The Quarkus Keycloak Admin Client and its reactive twin support Keycloak Admin Client which can be used to configure a running Keycloak server. keywords: sso oidc security keycloak categories: security + topics: + - security + - authentication + - authorization + - keycloak + - sso + extensions: + - io.quarkus:quarkus-keycloak-admin-client-reactive + - io.quarkus:quarkus-keycloak-admin-client type: guide url: /guides/security-keycloak-admin-client - title: Using Kotlin filename: kotlin.adoc summary: This guide explains how to use Kotlin. categories: alt-languages + topics: + - kotlin + extensions: + - io.quarkus:quarkus-kotlin type: guide url: /guides/kotlin - title: Using Liquibase filename: liquibase.adoc summary: This guide covers how to use the Liquibase extension to manage your schema migrations. categories: data + topics: + - data + - schema-migration + - liquibase + extensions: + - io.quarkus:quarkus-liquibase type: guide url: /guides/liquibase - title: Using Liquibase MongoDB filename: liquibase-mongodb.adoc summary: "Liquibase is an open source tool for database schema change management, it allows managing MongoDB databases via it’s MongoDB Extension." + categories: data + topics: + - data + - schema-migration + - liquibase + - mongodb + extensions: + - io.quarkus:quarkus-liquibase-mongodb type: guide url: /guides/liquibase-mongodb - title: Using OAuth2 RBAC @@ -1190,12 +2381,25 @@ types: summary: This guide explains how your Quarkus application can utilize OAuth2 tokens to provide secured access to the Jakarta REST endpoints. keywords: oauth categories: security + topics: + - security + - oauth2 + - identity-providers + extensions: + - io.quarkus:quarkus-elytron-security-oauth2 type: guide url: /guides/security-oauth2 - title: Using OpenAPI and Swagger UI filename: openapi-swaggerui.adoc summary: This guide explains how to use the OpenAPI extension to generate an OpenAPI descriptor and get a Swagger UI frontend to test your REST endpoints. categories: web + topics: + - rest + - openapi + - swagger-ui + - dev-ui + extensions: + - io.quarkus:quarkus-smallrye-openapi type: guide url: /guides/openapi-swaggerui - title: Using OpenID Connect (OIDC) Multi-Tenancy @@ -1203,6 +2407,12 @@ types: summary: This guide demonstrates how your OpenID Connect application can support multi-tenancy so that you can serve multiple tenants from a single application. keywords: sso oidc oauth2 security categories: security + topics: + - security + - oidc + - multitenancy + extensions: + - io.quarkus:quarkus-oidc type: guide url: /guides/security-openid-connect-multitenancy - title: Using OpenID Connect (OIDC) and Keycloak to Centralize Authorization @@ -1210,52 +2420,106 @@ types: summary: This guide demonstrates how your Quarkus application can authorize access to protected resources using Keycloak Authorization Services. keywords: sso oidc security keycloak categories: security + topics: + - security + - authentication + - authorization + - keycloak + - sso + - oidc + extensions: + - io.quarkus:quarkus-oidc + - io.quarkus:quarkus-keycloak-authorization type: guide url: /guides/security-keycloak-authorization - title: Using OpenTelemetry filename: opentelemetry.adoc summary: This guide explains how your Quarkus application can utilize OpenTelemetry to provide distributed tracing for interactive web applications. categories: observability + topics: + - observability + - opentelemetry + extensions: + - io.quarkus:quarkus-opentelemetry type: guide url: /guides/opentelemetry - title: Using OpenTracing filename: opentracing.adoc summary: This guide explains how your Quarkus application can utilize OpenTracing to provide distributed tracing for interactive web applications. categories: observability + topics: + - observability + - opentracing + extensions: + - io.quarkus:quarkus-smallrye-opentracing type: guide url: /guides/opentracing - title: Using Podman with Quarkus filename: podman.adoc summary: "Podman is a daemonless and rootless container engine for developing, managing, and running OCI Containers on your Linux system or other OS." + categories: tooling + topics: + - podman + - devops + - tooling type: guide url: /guides/podman - title: Using Reactive Routes filename: reactive-routes.adoc summary: This guide demonstrates how to use reactive routes. categories: web + topics: + - http + - web + - routing + extensions: + - io.quarkus:quarkus-reactive-routes type: guide url: /guides/reactive-routes - title: Using SSL With Native Executables filename: native-and-ssl.adoc summary: "In this guide, we will discuss how you can get your native images to support SSL, as native images don't support it out of the box." - categories: "security, core, native" + categories: "core, native, security" + topics: + - native + - ssl type: guide url: /guides/native-and-ssl - title: Using Security with .properties File filename: security-properties.adoc summary: This guide demonstrates how your Quarkus application can use a .properties file to store your user identities. categories: security + topics: + - security + - identity-providers + extensions: + - io.quarkus:quarkus-elytron-security-properties-file type: guide url: /guides/security-properties - title: Using Security with JDBC filename: security-jdbc.adoc summary: This guide demonstrates how your Quarkus application can use a database to store your user identities. categories: security + topics: + - security + - identity-providers + - jdbc + - sql + - database + extensions: + - io.quarkus:quarkus-elytron-security-jdbc type: guide url: /guides/security-jdbc - title: Using Security with WebAuthn filename: security-webauthn.adoc summary: This guide demonstrates how your Quarkus application can use WebAuthn authentication instead of passwords. + categories: security + topics: + - security + - webauthn + - authorization + extensions: + - io.quarkus:quarkus-security-webauthn id: security-webauthn type: guide url: /guides/security-webauthn @@ -1263,125 +2527,254 @@ types: filename: security-ldap.adoc summary: This guide demonstrates how your Quarkus application can use a LDAP directory to store your user identities. categories: security + topics: + - security + - identity-providers + - ldap + extensions: + - io.quarkus:quarkus-elytron-security-ldap type: guide url: /guides/security-ldap - title: Using Software Transactional Memory in Quarkus filename: software-transactional-memory.adoc summary: This guides covers the usage of Software Transactional Memory (STM). categories: data + topics: + - narayana + - stm + - transactions + extensions: + - io.quarkus:quarkus-narayana-stm type: guide url: /guides/software-transactional-memory - title: Using Stork with Kubernetes filename: stork-kubernetes.adoc summary: This guide explains how to use Stork with Kubernetes for service discovery and load balancing. + categories: cloud + topics: + - service-discovery + - load-balancing + - stork + - kubernetes + extensions: + - io.quarkus:quarkus-kubernetes + - io.quarkus:quarkus-smallrye-stork type: guide url: /guides/stork-kubernetes - title: Using Transactions in Quarkus filename: transaction.adoc summary: Quarkus comes with a Transaction Manager and uses it to coordinate and expose transactions to your applications. categories: data + topics: + - data + - jpa + - jta + - transactions + - narayana + extensions: + - io.quarkus:quarkus-narayana-jta type: guide url: /guides/transaction - title: Using WebSockets filename: websockets.adoc summary: This guide explains how your Quarkus application can utilize web sockets to create interactive web applications. categories: web + topics: + - web + - websockets + extensions: + - io.quarkus:quarkus-websockets + - io.quarkus:quarkus-websockets-client type: guide url: /guides/websockets - title: Using a Credentials Provider filename: credentials-provider.adoc summary: This guides explains how to use the Vault credentials provider or implement your own custom one. categories: security + topics: + - security + - credentials type: guide url: /guides/credentials-provider - title: Using the Cassandra Client filename: cassandra.adoc summary: This guide covers how to use the Apache Cassandra NoSQL database in Quarkus. categories: data + topics: + - data + - cassandra type: guide url: /guides/cassandra - title: Using the Infinispan Client filename: infinispan-client.adoc summary: This guide covers how to use Infinispan with Quarkus. categories: data + topics: + - data + - infinispan + extensions: + - io.quarkus:quarkus-infinispan-client type: guide url: /guides/infinispan-client - title: Using the MongoDB Client filename: mongodb.adoc summary: This guide covers how to use MongoDB in Quarkus. categories: data + topics: + - data + - mongodb + - nosql + extensions: + - io.quarkus:quarkus-mongodb-client type: guide url: /guides/mongodb - title: Using the REST Client filename: rest-client-reactive.adoc summary: This guide explains how to use the RESTEasy Reactive REST Client. categories: web + topics: + - rest + - rest-client + - resteasy-reactive + extensions: + - io.quarkus:quarkus-rest-client-reactive + - io.quarkus:quarkus-rest-client-reactive-jackson + - io.quarkus:quarkus-rest-client-reactive-jsonb type: guide url: /guides/rest-client-reactive - title: Using the Redis Client filename: redis.adoc summary: This guide covers how to use a Redis datastore in Quarkus. categories: data + topics: + - data + - redis + - nosql + extensions: + - io.quarkus:quarkus-redis-client type: guide url: /guides/redis - title: Using the event bus filename: reactive-event-bus.adoc summary: This guide explains how different beans can interact using the event bus. categories: messaging + topics: + - messaging + - event-bus + - vert.x + extensions: + - io.quarkus:quarkus-vertx type: guide url: /guides/reactive-event-bus - title: Using the legacy REST Client filename: rest-client.adoc - summary: This guide explains how to use the RESTEasy REST Client in order to interact with REST APIs (JSON and other) with very little effort. + summary: This guide explains how to use the RESTEasy Classic REST Client in order to interact with REST APIs (JSON and other) with very little effort. categories: web + topics: + - rest + - rest-client + - resteasy-classic + extensions: + - io.quarkus:quarkus-rest-client + - io.quarkus:quarkus-rest-client-jackson + - io.quarkus:quarkus-rest-client-jsonb type: guide url: /guides/rest-client - title: Using the legacy REST Client with Multipart filename: rest-client-multipart.adoc - summary: "This guide explains how to use the RESTEasy REST Client to send multipart REST requests, typically to upload documents." + summary: "This guide explains how to use the RESTEasy Classic REST Client to send multipart REST requests, typically to upload documents." categories: web + topics: + - rest + - rest-client + - multipart + - resteasy-classic + extensions: + - io.quarkus:quarkus-rest-client + - io.quarkus:quarkus-resteasy-multipart type: guide url: /guides/rest-client-multipart - title: Using xDS gRPC filename: grpc-xds.adoc summary: This page explains how to enable xDS gRPC usage in your Quarkus application. categories: serialization + topics: + - grpc + - xds + extensions: + - io.quarkus:quarkus-grpc-xds type: guide url: /guides/grpc-xds - title: Validation with Hibernate Validator filename: validation.adoc summary: This guide covers how to use Hibernate Validator/Bean Validation in your REST services. - categories: "web, data" + categories: "data, web" + topics: + - bean-validation + - hibernate-validator + - validation + extensions: + - io.quarkus:quarkus-hibernate-validator type: guide url: /guides/validation - title: Writing JSON REST Services filename: rest-json.adoc summary: JSON is now the lingua franca between microservices. - categories: "web, serialization" + categories: "serialization, web" + topics: + - rest + - json + - resteasy-reactive + extensions: + - io.quarkus:quarkus-resteasy-reactive-jackson + - io.quarkus:quarkus-resteasy-reactive-jsonb + - io.quarkus:quarkus-resteasy-reactive type: guide url: /guides/rest-json - title: Writing REST Services with RESTEasy Reactive filename: resteasy-reactive.adoc summary: Discover how to develop highly scalable reactive REST services with Jakarta REST and RESTEasy Reactive. categories: web + topics: + - rest + - resteasy-reactive + - virtual-threads + extensions: + - io.quarkus:quarkus-resteasy-reactive + - io.quarkus:quarkus-resteasy-reactive-jackson + - io.quarkus:quarkus-resteasy-reactive-jsonb + - io.quarkus:quarkus-rest-client-reactive + - io.quarkus:quarkus-rest-client-reactive-jackson + - io.quarkus:quarkus-rest-client-reactive-jsonb type: guide url: /guides/resteasy-reactive - title: Writing Your Own Extension filename: writing-extensions.adoc summary: Quarkus extensions optimize your applications by pushing as much work as possible to the build operation. categories: writing-extensions + topics: + - extensions type: guide url: /guides/writing-extensions - title: YAML Configuration filename: config-yaml.adoc summary: YAML as a Configuration Source. categories: core + topics: + - configuration + extensions: + - io.quarkus:quarkus-config-yaml type: guide url: /guides/config-yaml - title: gRPC filename: grpc.adoc summary: Entry point for everything gRPC. categories: serialization + topics: + - grpc + extensions: + - io.quarkus:quarkus-grpc + - io.quarkus:quarkus-grpc-xds type: guide url: /guides/grpc categories: diff --git a/_data/versions.yaml b/_data/versions.yaml index 72508a87e2..74d7c2a57f 100644 --- a/_data/versions.yaml +++ b/_data/versions.yaml @@ -1,6 +1,6 @@ quarkus: - version: 3.4.2 - announce: /blog/quarkus-3-4-2-released/ + version: 3.4.3 + announce: /blog/quarkus-3-4-3-released/ graalvm: '23.0' jdk: "11+" maven: 3.8.2+ diff --git a/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.oidc.client.graphql.runtime.OidcClientGraphQLConfig b/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.oidc.client.graphql.runtime.OidcClientGraphQLConfig new file mode 100644 index 0000000000..956088a305 --- /dev/null +++ b/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.oidc.client.graphql.runtime.OidcClientGraphQLConfig @@ -0,0 +1 @@ +[{"configDocKey":{"type":"string","key":"quarkus.oidc-client-graphql.client-name","additionalKeys":[],"configDoc":"Name of the configured OidcClient used by GraphQL clients. You can override this configuration for typesafe clients with the `io.quarkus.oidc.client.filter.OidcClientFilter` annotation.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"client-name","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.oidc-client-graphql","enum":false}}] \ No newline at end of file diff --git a/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLConfig b/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLConfig index d054ab1910..9a918c2528 100644 --- a/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLConfig +++ b/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLConfig @@ -1 +1 @@ -[{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.root-path","additionalKeys":[],"configDoc":"The rootPath under which queries will be served. Default to graphql By default, this value will be resolved as a path relative to `$++{++quarkus.http.root-path++}++`.","withinAMap":false,"defaultValue":"graphql","javaDocSiteLink":"","docMapKey":"root-path","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.federation.enabled","additionalKeys":[],"configDoc":"Enable Apollo Federation. If this value is unspecified, then federation will be enabled automatically if any GraphQL Federation annotations are detected in the application.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"federation-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.metrics.enabled","additionalKeys":[],"configDoc":"Enable metrics. By default, this is false. If set to true, a metrics extension is required.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"metrics-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.tracing.enabled","additionalKeys":[],"configDoc":"Enable tracing. By default, this will be enabled if the tracing extension is added.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"tracing-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.events.enabled","additionalKeys":[],"configDoc":"Enable eventing. Allow you to receive events on bootstrap and execution.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"events-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.nonblocking.enabled","additionalKeys":[],"configDoc":"Enable non-blocking support. Default is true.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"non-blocking-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.http.get.enabled","additionalKeys":[],"configDoc":"Enable GET Requests. Allow queries via HTTP GET.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"http-get-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.http.post.queryparameters.enabled","additionalKeys":[],"configDoc":"Enable Query parameter on POST Requests. Allow POST request to override or supply values in a query parameter.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"http-post-query-parameters-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"io.smallrye.graphql.schema.helper.TypeAutoNameStrategy","key":"quarkus.smallrye-graphql.auto-name-strategy","additionalKeys":[],"configDoc":"Change the type naming strategy.","withinAMap":false,"defaultValue":"default","javaDocSiteLink":"","docMapKey":"auto-name-strategy","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":["`default`","`merge-inner-class`","`full`"],"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":true}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.error-extension-fields","additionalKeys":[],"configDoc":"List of extension fields that should be included in the error response. By default, none will be included. Examples of valid values include ++[++exception,classification,code,description,validationErrorType,queryPath++]++","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"error-extension-fields","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.show-runtime-exception-message","additionalKeys":[],"configDoc":"List of Runtime Exceptions class names that should show the error message. By default, Runtime Exception messages will be hidden and a generic `Server Error` message will be returned.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"show-runtime-exception-message","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.hide-checked-exception-message","additionalKeys":[],"configDoc":"List of Checked Exceptions class names that should hide the error message. By default, Checked Exception messages will show the exception message.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"hide-checked-exception-message","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.default-error-message","additionalKeys":[],"configDoc":"The default error message that will be used for hidden exception messages. Defaults to \"Server Error\"","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"default-error-message","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.print-data-fetcher-exception","additionalKeys":[],"configDoc":"Print the data fetcher exception to the log file. Default `true` in dev and test mode, default `false` in prod.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"print-data-fetcher-exception","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.schema-available","additionalKeys":[],"configDoc":"Make the schema available over HTTP.","withinAMap":false,"defaultValue":"true","javaDocSiteLink":"","docMapKey":"schema-available","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.schema-include-scalars","additionalKeys":[],"configDoc":"Include the Scalar definitions in the schema.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"schema-include-scalars","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.schema-include-schema-definition","additionalKeys":[],"configDoc":"Include the schema internal definition in the schema.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"schema-include-schema-definition","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.schema-include-directives","additionalKeys":[],"configDoc":"Include Directives in the schema.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"schema-include-directives","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.schema-include-introspection-types","additionalKeys":[],"configDoc":"Include Introspection Types in the schema.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"schema-include-introspection-types","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"io.smallrye.graphql.spi.config.LogPayloadOption","key":"quarkus.smallrye-graphql.log-payload","additionalKeys":[],"configDoc":"Log the payload (and optionally variables) to System out.","withinAMap":false,"defaultValue":"off","javaDocSiteLink":"","docMapKey":"log-payload","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":["`off`","`query-only`","`query-and-variables`"],"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":true}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.field-visibility","additionalKeys":[],"configDoc":"Set the Field visibility.","withinAMap":false,"defaultValue":"default","javaDocSiteLink":"","docMapKey":"field-visibility","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.unwrap-exceptions","additionalKeys":[],"configDoc":"Exceptions that should be unwrapped (class names).","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"unwrap-exceptions","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.websocket-subprotocols","additionalKeys":[],"configDoc":"Subprotocols that should be supported by the server for graphql-over-websocket use cases. Allowed subprotocols are \"graphql-ws\" and \"graphql-transport-ws\". By default, both are enabled.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"websocket-subprotocols","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.parser-capture-ignored-chars","additionalKeys":[],"configDoc":"Set to true if ignored chars should be captured as AST nodes. Default to false","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"parser-capture-ignored-chars","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.parser-capture-line-comments","additionalKeys":[],"configDoc":"Set to true if `graphql.language.Comment`s should be captured as AST nodes","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"parser-capture-line-comments","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.parser-capture-source-location","additionalKeys":[],"configDoc":"Set to true true if `graphql.language.SourceLocation`s should be captured as AST nodes. Default to true","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"parser-capture-source-location","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Integer","key":"quarkus.smallrye-graphql.parser-max-tokens","additionalKeys":[],"configDoc":"The maximum number of raw tokens the parser will accept, after which an exception will be thrown. Default to 15000","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"parser-max-tokens","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Integer","key":"quarkus.smallrye-graphql.parser-max-whitespace-tokens","additionalKeys":[],"configDoc":"The maximum number of raw whitespace tokens the parser will accept, after which an exception will be thrown. Default to 200000","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"parser-max-whitespace-tokens","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Integer","key":"quarkus.smallrye-graphql.instrumentation-query-complexity","additionalKeys":[],"configDoc":"Abort a query if the total number of data fields queried exceeds the defined limit. Default to no limit","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"instrumentation-query-complexity","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Integer","key":"quarkus.smallrye-graphql.instrumentation-query-depth","additionalKeys":[],"configDoc":"Abort a query if the total depth of the query exceeds the defined limit. Default to no limit","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"instrumentation-query-depth","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocSection":{"name":"quarkus.smallrye-graphql.ui","optional":false,"withinAMap":false,"sectionDetails":"= SmallRye GraphQL UI configuration","sectionDetailsTitle":"SmallRye GraphQL UI configuration","configPhase":"BUILD_AND_RUN_TIME_FIXED","topLevelGrouping":"quarkus.smallrye-graphql","configGroupType":"io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLUIConfig","showSection":true,"configDocItems":[{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.ui.root-path","additionalKeys":[],"configDoc":"The path where GraphQL UI is available. The value `/` is not allowed as it blocks the application from serving anything else. By default, this URL will be resolved as a path relative to `$++{++quarkus.http.non-application-root-path++}++`.","withinAMap":false,"defaultValue":"graphql-ui","javaDocSiteLink":"","docMapKey":"root-path","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":true,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.ui.always-include","additionalKeys":[],"configDoc":"Always include the UI. By default, this will only be included in dev and test. Setting this to true will also include the UI in Prod","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"always-include","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":true,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}}],"anchorPrefix":null}}] \ No newline at end of file +[{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.root-path","additionalKeys":[],"configDoc":"The rootPath under which queries will be served. Default to graphql By default, this value will be resolved as a path relative to `$++{++quarkus.http.root-path++}++`.","withinAMap":false,"defaultValue":"graphql","javaDocSiteLink":"","docMapKey":"root-path","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.federation.enabled","additionalKeys":[],"configDoc":"Enable Apollo Federation. If this value is unspecified, then federation will be enabled automatically if any GraphQL Federation annotations are detected in the application.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"federation-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.federation.batch-resolving-enabled","additionalKeys":[],"configDoc":"Enable batch resolving for federation. Disabled by default.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"federation-batch-resolving-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.metrics.enabled","additionalKeys":[],"configDoc":"Enable metrics. By default, this is false. If set to true, a metrics extension is required.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"metrics-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.tracing.enabled","additionalKeys":[],"configDoc":"Enable tracing. By default, this will be enabled if the tracing extension is added.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"tracing-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.events.enabled","additionalKeys":[],"configDoc":"Enable eventing. Allow you to receive events on bootstrap and execution.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"events-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.nonblocking.enabled","additionalKeys":[],"configDoc":"Enable non-blocking support. Default is true.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"non-blocking-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.http.get.enabled","additionalKeys":[],"configDoc":"Enable GET Requests. Allow queries via HTTP GET.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"http-get-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.http.post.queryparameters.enabled","additionalKeys":[],"configDoc":"Enable Query parameter on POST Requests. Allow POST request to override or supply values in a query parameter.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"http-post-query-parameters-enabled","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"io.smallrye.graphql.schema.helper.TypeAutoNameStrategy","key":"quarkus.smallrye-graphql.auto-name-strategy","additionalKeys":[],"configDoc":"Change the type naming strategy.","withinAMap":false,"defaultValue":"default","javaDocSiteLink":"","docMapKey":"auto-name-strategy","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":["`default`","`merge-inner-class`","`full`"],"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":true}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.error-extension-fields","additionalKeys":[],"configDoc":"List of extension fields that should be included in the error response. By default, none will be included. Examples of valid values include ++[++exception,classification,code,description,validationErrorType,queryPath++]++","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"error-extension-fields","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.show-runtime-exception-message","additionalKeys":[],"configDoc":"List of Runtime Exceptions class names that should show the error message. By default, Runtime Exception messages will be hidden and a generic `Server Error` message will be returned.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"show-runtime-exception-message","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.hide-checked-exception-message","additionalKeys":[],"configDoc":"List of Checked Exceptions class names that should hide the error message. By default, Checked Exception messages will show the exception message.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"hide-checked-exception-message","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.default-error-message","additionalKeys":[],"configDoc":"The default error message that will be used for hidden exception messages. Defaults to \"Server Error\"","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"default-error-message","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.print-data-fetcher-exception","additionalKeys":[],"configDoc":"Print the data fetcher exception to the log file. Default `true` in dev and test mode, default `false` in prod.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"print-data-fetcher-exception","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.schema-available","additionalKeys":[],"configDoc":"Make the schema available over HTTP.","withinAMap":false,"defaultValue":"true","javaDocSiteLink":"","docMapKey":"schema-available","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.schema-include-scalars","additionalKeys":[],"configDoc":"Include the Scalar definitions in the schema.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"schema-include-scalars","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.schema-include-schema-definition","additionalKeys":[],"configDoc":"Include the schema internal definition in the schema.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"schema-include-schema-definition","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.schema-include-directives","additionalKeys":[],"configDoc":"Include Directives in the schema.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"schema-include-directives","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.schema-include-introspection-types","additionalKeys":[],"configDoc":"Include Introspection Types in the schema.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"schema-include-introspection-types","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"io.smallrye.graphql.spi.config.LogPayloadOption","key":"quarkus.smallrye-graphql.log-payload","additionalKeys":[],"configDoc":"Log the payload (and optionally variables) to System out.","withinAMap":false,"defaultValue":"off","javaDocSiteLink":"","docMapKey":"log-payload","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":["`off`","`query-only`","`query-and-variables`"],"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":true}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.field-visibility","additionalKeys":[],"configDoc":"Set the Field visibility.","withinAMap":false,"defaultValue":"default","javaDocSiteLink":"","docMapKey":"field-visibility","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.unwrap-exceptions","additionalKeys":[],"configDoc":"Exceptions that should be unwrapped (class names).","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"unwrap-exceptions","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.websocket-subprotocols","additionalKeys":[],"configDoc":"Subprotocols that should be supported by the server for graphql-over-websocket use cases. Allowed subprotocols are \"graphql-ws\" and \"graphql-transport-ws\". By default, both are enabled.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"websocket-subprotocols","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.parser-capture-ignored-chars","additionalKeys":[],"configDoc":"Set to true if ignored chars should be captured as AST nodes. Default to false","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"parser-capture-ignored-chars","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.parser-capture-line-comments","additionalKeys":[],"configDoc":"Set to true if `graphql.language.Comment`s should be captured as AST nodes","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"parser-capture-line-comments","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Boolean","key":"quarkus.smallrye-graphql.parser-capture-source-location","additionalKeys":[],"configDoc":"Set to true true if `graphql.language.SourceLocation`s should be captured as AST nodes. Default to true","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"parser-capture-source-location","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Integer","key":"quarkus.smallrye-graphql.parser-max-tokens","additionalKeys":[],"configDoc":"The maximum number of raw tokens the parser will accept, after which an exception will be thrown. Default to 15000","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"parser-max-tokens","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Integer","key":"quarkus.smallrye-graphql.parser-max-whitespace-tokens","additionalKeys":[],"configDoc":"The maximum number of raw whitespace tokens the parser will accept, after which an exception will be thrown. Default to 200000","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"parser-max-whitespace-tokens","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Integer","key":"quarkus.smallrye-graphql.instrumentation-query-complexity","additionalKeys":[],"configDoc":"Abort a query if the total number of data fields queried exceeds the defined limit. Default to no limit","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"instrumentation-query-complexity","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"java.lang.Integer","key":"quarkus.smallrye-graphql.instrumentation-query-depth","additionalKeys":[],"configDoc":"Abort a query if the total depth of the query exceeds the defined limit. Default to no limit","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"instrumentation-query-depth","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocSection":{"name":"quarkus.smallrye-graphql.ui","optional":false,"withinAMap":false,"sectionDetails":"= SmallRye GraphQL UI configuration","sectionDetailsTitle":"SmallRye GraphQL UI configuration","configPhase":"BUILD_AND_RUN_TIME_FIXED","topLevelGrouping":"quarkus.smallrye-graphql","configGroupType":"io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLUIConfig","showSection":true,"configDocItems":[{"configDocKey":{"type":"string","key":"quarkus.smallrye-graphql.ui.root-path","additionalKeys":[],"configDoc":"The path where GraphQL UI is available. The value `/` is not allowed as it blocks the application from serving anything else. By default, this URL will be resolved as a path relative to `$++{++quarkus.http.non-application-root-path++}++`.","withinAMap":false,"defaultValue":"graphql-ui","javaDocSiteLink":"","docMapKey":"root-path","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":true,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.smallrye-graphql.ui.always-include","additionalKeys":[],"configDoc":"Always include the UI. By default, this will only be included in dev and test. Setting this to true will also include the UI in Prod","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"always-include","configPhase":"BUILD_AND_RUN_TIME_FIXED","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":true,"topLevelGrouping":"quarkus.smallrye-graphql","enum":false}}],"anchorPrefix":null}}] \ No newline at end of file diff --git a/_generated-doc/main/config/extensions-configuration-roots-list/quarkus-oidc-client-graphql.adoc/io.quarkus.oidc.client.graphql.runtime.OidcClientGraphQLConfig b/_generated-doc/main/config/extensions-configuration-roots-list/quarkus-oidc-client-graphql.adoc/io.quarkus.oidc.client.graphql.runtime.OidcClientGraphQLConfig new file mode 100644 index 0000000000..5e1c979878 --- /dev/null +++ b/_generated-doc/main/config/extensions-configuration-roots-list/quarkus-oidc-client-graphql.adoc/io.quarkus.oidc.client.graphql.runtime.OidcClientGraphQLConfig @@ -0,0 +1 @@ +io.quarkus.oidc.client.graphql.runtime.OidcClientGraphQLConfig \ No newline at end of file diff --git a/_generated-doc/main/config/quarkus-all-build-items.adoc b/_generated-doc/main/config/quarkus-all-build-items.adoc index 87cac451dd..1558e6f840 100644 --- a/_generated-doc/main/config/quarkus-all-build-items.adoc +++ b/_generated-doc/main/config/quarkus-all-build-items.adoc @@ -2277,6 +2277,9 @@ a| `Supplier vertx` :: +++No Javadoc found+++ a| https://github.com/quarkusio/quarkus/blob/main/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/core/deployment/EventLoopCountBuildItem.java[`io.quarkus.vertx.core.deployment.EventLoopCountBuildItem`, window="_blank"] :: +++A build item that can be used to retrieve the number of events loops that have been configured/calculated+++ a| `Supplier eventLoopCount` :: +++No Javadoc found+++ +a| https://github.com/quarkusio/quarkus/blob/main/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/LocalCodecSelectorTypesBuildItem.java[`io.quarkus.vertx.deployment.LocalCodecSelectorTypesBuildItem`, window="_blank"] :: +++Carries all types for which the should be selected automatically.+++ +a| `Set types` :: +++No Javadoc found+++ + a| https://github.com/quarkusio/quarkus/blob/main/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/MessageCodecBuildItem.java[`io.quarkus.vertx.deployment.MessageCodecBuildItem`, window="_blank"] :: +++No Javadoc found+++ a| `String type` :: +++No Javadoc found+++ `String codec` :: +++No Javadoc found+++ diff --git a/_generated-doc/main/config/quarkus-all-config.adoc b/_generated-doc/main/config/quarkus-all-config.adoc index 2d3c442171..cfe37c5f67 100644 --- a/_generated-doc/main/config/quarkus-all-config.adoc +++ b/_generated-doc/main/config/quarkus-all-config.adoc @@ -50575,6 +50575,28 @@ endif::add-copy-button-to-env-var[] | +h|[[quarkus-oidc-client-graphql_quarkus-oidc-client-graphql-openid-connect-client-integration-for-graphql-client]]link:#quarkus-oidc-client-graphql_quarkus-oidc-client-graphql-openid-connect-client-integration-for-graphql-client[OpenID Connect Client integration for GraphQL client] + +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-oidc-client-graphql_quarkus.oidc-client-graphql.client-name]]`link:#quarkus-oidc-client-graphql_quarkus.oidc-client-graphql.client-name[quarkus.oidc-client-graphql.client-name]` + + +[.description] +-- +Name of the configured OidcClient used by GraphQL clients. You can override this configuration for typesafe clients with the `io.quarkus.oidc.client.filter.OidcClientFilter` annotation. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_OIDC_CLIENT_GRAPHQL_CLIENT_NAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_OIDC_CLIENT_GRAPHQL_CLIENT_NAME+++` +endif::add-copy-button-to-env-var[] +--|string +| + + h|[[quarkus-oidc-db-token-state-manager_quarkus-oidc-db-token-state-manager-openid-connect-database-token-state-manager]]link:#quarkus-oidc-db-token-state-manager_quarkus-oidc-db-token-state-manager-openid-connect-database-token-state-manager[OpenID Connect Database Token State Manager] h|Type @@ -63749,6 +63771,23 @@ endif::add-copy-button-to-env-var[] | +a|icon:lock[title=Fixed at build time] [[quarkus-smallrye-graphql_quarkus.smallrye-graphql.federation.batch-resolving-enabled]]`link:#quarkus-smallrye-graphql_quarkus.smallrye-graphql.federation.batch-resolving-enabled[quarkus.smallrye-graphql.federation.batch-resolving-enabled]` + + +[.description] +-- +Enable batch resolving for federation. Disabled by default. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_SMALLRYE_GRAPHQL_FEDERATION_BATCH_RESOLVING_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_SMALLRYE_GRAPHQL_FEDERATION_BATCH_RESOLVING_ENABLED+++` +endif::add-copy-button-to-env-var[] +--|boolean +| + + a|icon:lock[title=Fixed at build time] [[quarkus-smallrye-graphql_quarkus.smallrye-graphql.metrics.enabled]]`link:#quarkus-smallrye-graphql_quarkus.smallrye-graphql.metrics.enabled[quarkus.smallrye-graphql.metrics.enabled]` diff --git a/_generated-doc/main/config/quarkus-oidc-client-graphql-oidc-client-graph-ql-config.adoc b/_generated-doc/main/config/quarkus-oidc-client-graphql-oidc-client-graph-ql-config.adoc new file mode 100644 index 0000000000..c693cda35a --- /dev/null +++ b/_generated-doc/main/config/quarkus-oidc-client-graphql-oidc-client-graph-ql-config.adoc @@ -0,0 +1,29 @@ + +:summaryTableId: quarkus-oidc-client-graphql-oidc-client-graph-ql-config +[.configuration-legend] +icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime +[.configuration-reference, cols="80,.^10,.^10"] +|=== + +h|[[quarkus-oidc-client-graphql-oidc-client-graph-ql-config_configuration]]link:#quarkus-oidc-client-graphql-oidc-client-graph-ql-config_configuration[Configuration property] + +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-oidc-client-graphql-oidc-client-graph-ql-config_quarkus.oidc-client-graphql.client-name]]`link:#quarkus-oidc-client-graphql-oidc-client-graph-ql-config_quarkus.oidc-client-graphql.client-name[quarkus.oidc-client-graphql.client-name]` + + +[.description] +-- +Name of the configured OidcClient used by GraphQL clients. You can override this configuration for typesafe clients with the `io.quarkus.oidc.client.filter.OidcClientFilter` annotation. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_OIDC_CLIENT_GRAPHQL_CLIENT_NAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_OIDC_CLIENT_GRAPHQL_CLIENT_NAME+++` +endif::add-copy-button-to-env-var[] +--|string +| + +|=== \ No newline at end of file diff --git a/_generated-doc/main/config/quarkus-oidc-client-graphql.adoc b/_generated-doc/main/config/quarkus-oidc-client-graphql.adoc new file mode 100644 index 0000000000..159cda6689 --- /dev/null +++ b/_generated-doc/main/config/quarkus-oidc-client-graphql.adoc @@ -0,0 +1,29 @@ + +:summaryTableId: quarkus-oidc-client-graphql +[.configuration-legend] +icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime +[.configuration-reference.searchable, cols="80,.^10,.^10"] +|=== + +h|[[quarkus-oidc-client-graphql_configuration]]link:#quarkus-oidc-client-graphql_configuration[Configuration property] + +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-oidc-client-graphql_quarkus.oidc-client-graphql.client-name]]`link:#quarkus-oidc-client-graphql_quarkus.oidc-client-graphql.client-name[quarkus.oidc-client-graphql.client-name]` + + +[.description] +-- +Name of the configured OidcClient used by GraphQL clients. You can override this configuration for typesafe clients with the `io.quarkus.oidc.client.filter.OidcClientFilter` annotation. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_OIDC_CLIENT_GRAPHQL_CLIENT_NAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_OIDC_CLIENT_GRAPHQL_CLIENT_NAME+++` +endif::add-copy-button-to-env-var[] +--|string +| + +|=== \ No newline at end of file diff --git a/_generated-doc/main/config/quarkus-smallrye-graphql-small-rye-graph-ql-config.adoc b/_generated-doc/main/config/quarkus-smallrye-graphql-small-rye-graph-ql-config.adoc index af6127b17c..4d6cbd2f76 100644 --- a/_generated-doc/main/config/quarkus-smallrye-graphql-small-rye-graph-ql-config.adoc +++ b/_generated-doc/main/config/quarkus-smallrye-graphql-small-rye-graph-ql-config.adoc @@ -44,6 +44,23 @@ endif::add-copy-button-to-env-var[] | +a|icon:lock[title=Fixed at build time] [[quarkus-smallrye-graphql-small-rye-graph-ql-config_quarkus.smallrye-graphql.federation.batch-resolving-enabled]]`link:#quarkus-smallrye-graphql-small-rye-graph-ql-config_quarkus.smallrye-graphql.federation.batch-resolving-enabled[quarkus.smallrye-graphql.federation.batch-resolving-enabled]` + + +[.description] +-- +Enable batch resolving for federation. Disabled by default. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_SMALLRYE_GRAPHQL_FEDERATION_BATCH_RESOLVING_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_SMALLRYE_GRAPHQL_FEDERATION_BATCH_RESOLVING_ENABLED+++` +endif::add-copy-button-to-env-var[] +--|boolean +| + + a|icon:lock[title=Fixed at build time] [[quarkus-smallrye-graphql-small-rye-graph-ql-config_quarkus.smallrye-graphql.metrics.enabled]]`link:#quarkus-smallrye-graphql-small-rye-graph-ql-config_quarkus.smallrye-graphql.metrics.enabled[quarkus.smallrye-graphql.metrics.enabled]` diff --git a/_generated-doc/main/config/quarkus-smallrye-graphql.adoc b/_generated-doc/main/config/quarkus-smallrye-graphql.adoc index b211f6544a..465f3d83e0 100644 --- a/_generated-doc/main/config/quarkus-smallrye-graphql.adoc +++ b/_generated-doc/main/config/quarkus-smallrye-graphql.adoc @@ -44,6 +44,23 @@ endif::add-copy-button-to-env-var[] | +a|icon:lock[title=Fixed at build time] [[quarkus-smallrye-graphql_quarkus.smallrye-graphql.federation.batch-resolving-enabled]]`link:#quarkus-smallrye-graphql_quarkus.smallrye-graphql.federation.batch-resolving-enabled[quarkus.smallrye-graphql.federation.batch-resolving-enabled]` + + +[.description] +-- +Enable batch resolving for federation. Disabled by default. + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_SMALLRYE_GRAPHQL_FEDERATION_BATCH_RESOLVING_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_SMALLRYE_GRAPHQL_FEDERATION_BATCH_RESOLVING_ENABLED+++` +endif::add-copy-button-to-env-var[] +--|boolean +| + + a|icon:lock[title=Fixed at build time] [[quarkus-smallrye-graphql_quarkus.smallrye-graphql.metrics.enabled]]`link:#quarkus-smallrye-graphql_quarkus.smallrye-graphql.metrics.enabled[quarkus.smallrye-graphql.metrics.enabled]` diff --git a/_guides/_attributes.adoc b/_guides/_attributes.adoc index 8c0f64c040..3197297e32 100644 --- a/_guides/_attributes.adoc +++ b/_guides/_attributes.adoc @@ -1,7 +1,7 @@ // Common attributes. // --> No blank lines (it ends the document header) :project-name: Quarkus -:quarkus-version: 3.4.2 +:quarkus-version: 3.4.3 :quarkus-platform-groupid: io.quarkus.platform // . :maven-version: 3.9.3 diff --git a/_guides/ansible.adoc b/_guides/ansible.adoc index 476cd7c5fd..696d5d4bed 100644 --- a/_guides/ansible.adoc +++ b/_guides/ansible.adoc @@ -1,3 +1,8 @@ +//// +This guide is maintained in the main Quarkus repository +and pull requests should be submitted there: +https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc +//// = Automate Quarkus deployment with Ansible include::_attributes.adoc[] :categories: command-line diff --git a/_guides/cdi-reference.adoc b/_guides/cdi-reference.adoc index 3a462496c9..3e38617e2b 100644 --- a/_guides/cdi-reference.adoc +++ b/_guides/cdi-reference.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Contexts and Dependency Injection include::_attributes.adoc[] :categories: core +:keywords: arc :summary: Go more in depth into the Quarkus implementation of CDI. :numbered: :sectnums: diff --git a/_guides/cdi.adoc b/_guides/cdi.adoc index f6e0645e24..2d5a259f04 100644 --- a/_guides/cdi.adoc +++ b/_guides/cdi.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Introduction to Contexts and Dependency Injection (CDI) include::_attributes.adoc[] :categories: core +:keywords: qualifier event interceptor observer arc :summary: Quarkus DI solution is based on the [Jakarta Contexts and Dependency Injection 4.0](https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html) specification. This guide explains the basics of CDI. :numbered: :sectnums: @@ -28,7 +29,7 @@ It creates and destroys the instances of beans, associates the instances with a An application developer can focus on the business logic rather than finding out "where and how" to obtain a fully initialized component with all of its dependencies. -NOTE: You've probably heard of the _inversion of control_ (IoC) programming principle. Dependency injection is one of the implementation techniques of IoC. +NOTE: You've probably heard of the _inversion of control_ (IoC) programming principle. Dependency injection is one of the implementation techniques of IoC. == What does a bean look like? @@ -47,9 +48,9 @@ public class Translator { @Inject Dictionary dictionary; <2> - + @Counted <3> - String translate(String sentence) { + String translate(String sentence) { // ... } } @@ -86,8 +87,8 @@ public class Translator { @Inject Instance dictionaries; <1> - - String translate(String sentence) { + + String translate(String sentence) { for (Dictionary dict : dictionaries) { <2> // ... } @@ -122,11 +123,11 @@ public class Translator { } } ---- -<1> This is a constructor injection. -In fact, this code would not work in regular CDI implementations where a bean with a normal scope must always declare a no-args constructor and the bean constructor must be annotated with `@Inject`. +<1> This is a constructor injection. +In fact, this code would not work in regular CDI implementations where a bean with a normal scope must always declare a no-args constructor and the bean constructor must be annotated with `@Inject`. However, in Quarkus we detect the absence of no-args constructor and "add" it directly in the bytecode. It's also not necessary to add `@Inject` if there is only one constructor present. -<2> An initializer method must be annotated with `@Inject`. +<2> An initializer method must be annotated with `@Inject`. <3> An initializer may accept multiple parameters - each one is an injection point. == You talked about some qualifiers? @@ -155,7 +156,7 @@ The qualifiers of a bean are declared by annotating the bean class or producer m @ApplicationScoped public class SuperiorTranslator extends Translator { - String translate(String sentence) { + String translate(String sentence) { // ... } } @@ -180,11 +181,11 @@ You can use all the built-in scopes mentioned by the specification except for `j [options="header",cols="1,1"] |=== -|Annotation |Description +|Annotation |Description //---------------------- -|`@jakarta.enterprise.context.ApplicationScoped` | A single bean instance is used for the application and shared among all injection points. The instance is created lazily, i.e. once a method is invoked upon the xref:client_proxies[client proxy]. +|`@jakarta.enterprise.context.ApplicationScoped` | A single bean instance is used for the application and shared among all injection points. The instance is created lazily, i.e. once a method is invoked upon the xref:client_proxies[client proxy]. |`@jakarta.inject.Singleton` | Just like `@ApplicationScoped` except that no client proxy is used. The instance is created when an injection point that resolves to a @Singleton bean is being injected. -|`@jakarta.enterprise.context.RequestScoped` | The bean instance is associated with the current _request_ (usually an HTTP request). +|`@jakarta.enterprise.context.RequestScoped` | The bean instance is associated with the current _request_ (usually an HTTP request). |`@jakarta.enterprise.context.Dependent` | This is a pseudo-scope. The instances are not shared and every injection point spawns a new instance of the dependent bean. The lifecycle of dependent bean is bound to the bean injecting it - it will be created and destroyed along with the bean injecting it. |`@jakarta.enterprise.context.SessionScoped` | This scope is backed by a `jakarta.servlet.http.HttpSession` object. It's only available if the `quarkus-undertow` extension is used. |=== @@ -217,7 +218,7 @@ Indeed, the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html# A client proxy is basically an object that delegates all method invocations to a target bean instance. It's a container construct that implements `io.quarkus.arc.ClientProxy` and extends the bean class. -IMPORTANT: Client proxies only delegate method invocations. So never read or write a field of a normal scoped bean, otherwise you will work with non-contextual or stale data. +IMPORTANT: Client proxies only delegate method invocations. So never read or write a field of a normal scoped bean, otherwise you will work with non-contextual or stale data. .Generated Client Proxy Example [source,java] @@ -225,7 +226,7 @@ IMPORTANT: Client proxies only delegate method invocations. So never read or wri @ApplicationScoped class Translator { - String translate(String sentence) { + String translate(String sentence) { // ... } } @@ -233,7 +234,7 @@ class Translator { // The client proxy class is generated and looks like... class Translator_ClientProxy extends Translator { <1> - String translate(String sentence) { + String translate(String sentence) { // Find the correct translator instance... Translator translator = getTranslatorInstanceFromTheApplicationContext(); // And delegate the method invocation... @@ -247,10 +248,10 @@ Client proxies allow for: * Lazy instantiation - the instance is created once a method is invoked upon the proxy. * Ability to inject a bean with "narrower" scope to a bean with "wider" scope; i.e. you can inject a `@RequestScoped` bean into an `@ApplicationScoped` bean. -* Circular dependencies in the dependency graph. Having circular dependencies is often an indication that a redesign should be considered, but sometimes it's inevitable. +* Circular dependencies in the dependency graph. Having circular dependencies is often an indication that a redesign should be considered, but sometimes it's inevitable. * In rare cases it's practical to destroy the beans manually. A direct injected reference would lead to a stale bean instance. - - + + == OK. You said that there are several kinds of beans? Yes. In general, we distinguish: @@ -273,7 +274,7 @@ public class Producers { @Produces <1> double pi = Math.PI; <2> - + @Produces <3> List names() { List names = new ArrayList<>(); @@ -289,26 +290,26 @@ public class Consumer { @Inject double pi; - + @Inject List names; - - // ... -} + + // ... +} ---- <1> The container analyses the field annotations to build a bean metadata. -The _type_ is used to build the set of bean types. +The _type_ is used to build the set of bean types. In this case, it will be `double` and `java.lang.Object`. No scope annotation is declared and so it's defaulted to `@Dependent`. <2> The container will read this field when creating the bean instance. <3> The container analyses the method annotations to build a bean metadata. -The _return type_ is used to build the set of bean types. +The _return type_ is used to build the set of bean types. In this case, it will be `List`, `Collection`, `Iterable` and `java.lang.Object`. No scope annotation is declared and so it's defaulted to `@Dependent`. <4> The container will call this method when creating the bean instance. -There's more about producers. -You can declare qualifiers, inject dependencies into the producer methods parameters, etc. +There's more about producers. +You can declare qualifiers, inject dependencies into the producer methods parameters, etc. You can read more about producers for example in the https://docs.jboss.org/weld/reference/latest/en-US/html/producermethods.html[Weld docs, window="_blank"]. == OK, injection looks cool. What other services are provided? @@ -330,7 +331,7 @@ public class Translator { void init() { // ... } - + @PreDestroy <2> void destroy() { // ... @@ -345,7 +346,7 @@ TIP: It's a good practice to keep the logic in the callbacks "without side effec [[interceptors]] === Interceptors -Interceptors are used to separate cross-cutting concerns from business logic. +Interceptors are used to separate cross-cutting concerns from business logic. There is a separate specification - Java Interceptors - that defines the basic programming model and semantics. .Simple Interceptor Binding Example @@ -392,11 +393,11 @@ public class LoggingInterceptor { // ...log after return ret; } - + } ---- <1> The interceptor binding annotation is used to bind our interceptor to a bean. Simply annotate a bean class with `@Logged`, as in the following example. -<2> `Priority` enables the interceptor and affects the interceptor ordering. Interceptors with smaller priority values are called first. +<2> `Priority` enables the interceptor and affects the interceptor ordering. Interceptors with smaller priority values are called first. <3> Marks an interceptor component. <4> An interceptor may inject dependencies. <5> `AroundInvoke` denotes a method that interposes on business methods. @@ -448,7 +449,7 @@ public class LargeTxAccount implements Account { <3> @Any @Delegate Account delegate; <4> - + @Inject LogService logService; <5> @@ -458,10 +459,10 @@ public class LargeTxAccount implements Account { <3> logService.logWithdrawal(delegate, amount); } } - + } ---- -<1> `@Priority` enables the decorator. Decorators with smaller priority values are called first. +<1> `@Priority` enables the decorator. Decorators with smaller priority values are called first. <2> `@Decorator` marks a decorator component. <3> The set of decorated types includes all bean types which are Java interfaces, except for `java.io.Serializable`. <4> Each decorator must declare exactly one _delegate injection point_. The decorator applies to beans that are assignable to this delegate injection point. @@ -471,7 +472,7 @@ public class LargeTxAccount implements Account { <3> NOTE: Instances of decorators are dependent objects of the bean instance they intercept, i.e. a new decorator instance is created for each intercepted bean. === Events and Observers - + Beans may also produce and consume events to interact in a completely decoupled fashion. Any Java object can serve as an event payload. The optional qualifiers act as topic selectors. diff --git a/_guides/extension-metadata.adoc b/_guides/extension-metadata.adoc index dcbdb6106e..d48bad282b 100644 --- a/_guides/extension-metadata.adoc +++ b/_guides/extension-metadata.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Quarkus Extension Metadata - include::_attributes.adoc[] Quarkus extensions are distributed as Maven JAR artifacts that application and other libraries may depend on. When a Quarkus application project is built, tested or edited using the Quarkus dev tools, Quarkus extension JAR artifacts will be identified on the application classpath by the presence of the Quarkus extension metadata files in them. @@ -127,11 +126,11 @@ The following properties may appear in this file: | `parent-first-artifacts` | Optional -| Comma-separated list of artifact keys (`groupId:artifactId:classifier:type`) that are to be loaded in a parent first manner. This can be used to work around issues where a given class needs to be loaded by the system ClassLoader. +| Comma-separated list of artifact keys (`groupId:artifactId:classifier:type`) that are to be loaded in a parent first manner. This can be used to work around issues where a given class needs to be loaded by the system ClassLoader. | `runner-parent-first-artifacts` | Optional -| Comma-separated list of artifact keys that are to be loaded in a parent first manner in addition to those configured with `parent-first-artifacts` when an application is launched from a production binary package. This can be used to work around issues where a given class needs to be loaded by the system ClassLoader. +| Comma-separated list of artifact keys that are to be loaded in a parent first manner in addition to those configured with `parent-first-artifacts` when an application is launched from a production binary package. This can be used to work around issues where a given class needs to be loaded by the system ClassLoader. | `excluded-artifacts` | Optional @@ -143,7 +142,7 @@ The following properties may appear in this file: | `removed-resources.*` | Optional -| Resources that should be removed/hidden from dependencies. This allows for classes and other resources to be removed from dependencies, so they are not accessible to the application. This is a map of artifact key to a comma-separated list of resources to be removed. When running in dev and test mode these resources are hidden from the ClassLoader, when running in production mode these files are removed from the jars that contain them. Note that if you want to remove a class you need to specify the class file name. e.g. to remove com.acme.Foo you would specify com/acme/Foo.class. +| Resources that should be removed/hidden from dependencies. This allows for classes and other resources to be removed from dependencies, so they are not accessible to the application. This is a map of artifact key to a comma-separated list of resources to be removed. When running in dev and test mode these resources are hidden from the ClassLoader, when running in production mode these files are removed from the jars that contain them. Note that if you want to remove a class you need to specify the class file name. e.g. to remove com.acme.Foo you would specify com/acme/Foo.class. | `provides-capabilities` | Optional diff --git a/_guides/grpc-virtual-threads.adoc b/_guides/grpc-virtual-threads.adoc index 44bb3f4e5f..cfd6c9f618 100644 --- a/_guides/grpc-virtual-threads.adoc +++ b/_guides/grpc-virtual-threads.adoc @@ -1,5 +1,9 @@ +//// +This guide is maintained in the main Quarkus repository +and pull requests should be submitted there: +https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc +//// = Quarkus Virtual Thread support for gRPC services - include::_attributes.adoc[] :runonvthread: https://javadoc.io/doc/io.smallrye.common/smallrye-common-annotation/latest/io/smallrye/common/annotation/RunOnVirtualThread.html :blocking_annotation: https://javadoc.io/doc/io.smallrye.reactive/smallrye-reactive-messaging-api/latest/io/smallrye/reactive/messaging/annotations/Blocking.html diff --git a/_guides/lifecycle.adoc b/_guides/lifecycle.adoc index 57a2d0e779..d1ce9c795e 100644 --- a/_guides/lifecycle.adoc +++ b/_guides/lifecycle.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Application Initialization and Termination include::_attributes.adoc[] :categories: core +:keywords: lifecycle event :summary: You often need to execute custom actions when the application starts and clean up everything when the application stops. This guide explains how to be notified when an application stops or starts. You often need to execute custom actions when the application starts and clean up everything when the application stops. @@ -175,7 +176,7 @@ NOTE: The methods can access injected beans. Check the link:{quickstarts-blob-ur === What is the difference from `@Initialized(ApplicationScoped.class)` and `@Destroyed(ApplicationScoped.class)` -In the JVM mode, there is no real difference, except that `StartupEvent` is always fired *after* `@Initialized(ApplicationScoped.class)` and `ShutdownEvent` is fired *before* `@Destroyed(ApplicationScoped.class)`. +In the JVM mode, there is no real difference, except that `StartupEvent` is always fired *after* `@Initialized(ApplicationScoped.class)` and `ShutdownEvent` is fired *before* `@Destroyed(ApplicationScoped.class)`. For a native executable build, however, `@Initialized(ApplicationScoped.class)` is fired as *part of the native build process*, whereas `StartupEvent` is fired when the native image is executed. See xref:writing-extensions.adoc#bootstrap-three-phases[Three Phases of Bootstrap and Quarkus Philosophy] for more details. @@ -192,10 +193,10 @@ package org.acme.lifecycle; import jakarta.enterprise.context.ApplicationScoped; -@Startup // <1> +@Startup // <1> @ApplicationScoped public class EagerAppBean { - + private final String name; EagerAppBean(NameGenerator generator) { // <2> diff --git a/_guides/liquibase-mongodb.adoc b/_guides/liquibase-mongodb.adoc index 9e92484258..dce4d2d1fc 100644 --- a/_guides/liquibase-mongodb.adoc +++ b/_guides/liquibase-mongodb.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Using Liquibase MongoDB - include::_attributes.adoc[] :change-log: src/main/resources/db/changeLog.xml :config-file: application.properties diff --git a/_guides/messaging-virtual-threads.adoc b/_guides/messaging-virtual-threads.adoc index 8b633f0d3a..ccf8a9f0b6 100644 --- a/_guides/messaging-virtual-threads.adoc +++ b/_guides/messaging-virtual-threads.adoc @@ -1,5 +1,9 @@ +//// +This guide is maintained in the main Quarkus repository +and pull requests should be submitted there: +https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc +//// = Quarkus Virtual Thread support with Reactive Messaging - include::_attributes.adoc[] :runonvthread: https://javadoc.io/doc/io.smallrye.common/smallrye-common-annotation/latest/io/smallrye/common/annotation/RunOnVirtualThread.html :rm_blocking_annotation: https://javadoc.io/doc/io.smallrye.reactive/smallrye-reactive-messaging-api/latest/io/smallrye/reactive/messaging/annotations/Blocking.html diff --git a/_guides/mutiny-primer.adoc b/_guides/mutiny-primer.adoc index 6e76490f4a..88966385f0 100644 --- a/_guides/mutiny-primer.adoc +++ b/_guides/mutiny-primer.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Mutiny - Async for bare mortal - include::_attributes.adoc[] https://smallrye.io/smallrye-mutiny[Mutiny] is an intuitive, reactive programming library. diff --git a/_guides/pulsar-dev-services.adoc b/_guides/pulsar-dev-services.adoc index e8e3d8ac1c..3a40ab216d 100644 --- a/_guides/pulsar-dev-services.adoc +++ b/_guides/pulsar-dev-services.adoc @@ -62,6 +62,6 @@ The following example enables transaction support: [source, properties] ---- -quarkus.pulsar.devservices.broker-config.transactionCoordinatorEnabled=true -quarkus.pulsar.devservices.broker-config.systemTopicEnabled=true +quarkus.pulsar.devservices.broker-config.transaction-coordinator-enabled=true +quarkus.pulsar.devservices.broker-config.system-topic-enabled=true ---- diff --git a/_guides/quarkus-maven-plugin.adoc b/_guides/quarkus-maven-plugin.adoc index aadebc85ea..ae1c766b26 100644 --- a/_guides/quarkus-maven-plugin.adoc +++ b/_guides/quarkus-maven-plugin.adoc @@ -4,12 +4,11 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Quarkus Maven Plugin +include::_attributes.adoc[] The Quarkus Maven Plugin builds the Quarkus applications, and provides helpers to launch dev mode or build native executables. For more information about how to use the Quarkus Maven Plugin, please refer to the xref:maven-tooling.adoc[Maven Tooling guide]. -include::_attributes.adoc[] - == Discover Maven goals Like most Maven plugins, the Quarkus Maven Plugin has a `help` goal that prints the description of the plugin, listing all available goals as well as their description. diff --git a/_guides/quarkus-runtime-base-image.adoc b/_guides/quarkus-runtime-base-image.adoc index c8c767b41f..9cbb93d08e 100644 --- a/_guides/quarkus-runtime-base-image.adoc +++ b/_guides/quarkus-runtime-base-image.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Quarkus Base Runtime Image - include::_attributes.adoc[] To ease the containerization of native executables, Quarkus provides a base image providing the requirements to run these executables. diff --git a/_guides/rabbitmq-dev-services.adoc b/_guides/rabbitmq-dev-services.adoc index bbcdef597b..8454327bd5 100644 --- a/_guides/rabbitmq-dev-services.adoc +++ b/_guides/rabbitmq-dev-services.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Dev Services for RabbitMQ - include::_attributes.adoc[] Dev Services for RabbitMQ automatically starts a RabbitMQ broker in dev mode and when running tests. diff --git a/_guides/rabbitmq-reference.adoc b/_guides/rabbitmq-reference.adoc index 105a674eb4..84271eff31 100644 --- a/_guides/rabbitmq-reference.adoc +++ b/_guides/rabbitmq-reference.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Reactive Messaging RabbitMQ Connector Reference Documentation - include::_attributes.adoc[] This guide is the companion from the xref:rabbitmq.adoc[Getting Started with RabbitMQ]. diff --git a/_guides/redis-reference.adoc b/_guides/redis-reference.adoc index fc58509310..7b43a51a12 100644 --- a/_guides/redis-reference.adoc +++ b/_guides/redis-reference.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Redis Extension Reference Guide - :extension-status: preview include::_attributes.adoc[] :numbered: diff --git a/_guides/resteasy.adoc b/_guides/resteasy.adoc index 39ac40d3b2..7d608174e0 100644 --- a/_guides/resteasy.adoc +++ b/_guides/resteasy.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = RESTEasy Classic - include::_attributes.adoc[] [WARNING] @@ -210,7 +209,7 @@ public class RegisterCustomModuleCustomizer implements ObjectMapperCustomizer { Users can even provide their own `ObjectMapper` bean if they so choose. If this is done, it is very important to manually inject and apply all `io.quarkus.jackson.ObjectMapperCustomizer` beans in the CDI producer that produces `ObjectMapper`. -Failure to do so will prevent Jackson specific customizations provided by various extensions from being applied. +Failure to do so will prevent Jackson specific customizations provided by various extensions from being applied. [source,java] ---- @@ -293,7 +292,7 @@ public class CustomJsonbConfig { [[links]] === JSON Hypertext Application Language (HAL) support -The https://tools.ietf.org/id/draft-kelly-json-hal-01.html[HAL] standard is a simple format to represent web links. +The https://tools.ietf.org/id/draft-kelly-json-hal-01.html[HAL] standard is a simple format to represent web links. To enable the HAL support, add the `quarkus-hal` extension to your project. Also, as HAL needs JSON support, you need to add either the `quarkus-resteasy-jsonb` or the `quarkus-resteasy-jackson` extension. @@ -330,7 +329,7 @@ public class RecordsResource { } ---- -Now, the endpoints `/records` and `/records/first` will accept the media type both `json` and `hal+json` to print the records in Hal format. +Now, the endpoints `/records` and `/records/first` will accept the media type both `json` and `hal+json` to print the records in Hal format. For example, if we invoke the `/records` endpoint using curl to return a list of records, the HAL format will look like as follows: diff --git a/_guides/security-authentication-mechanisms.adoc b/_guides/security-authentication-mechanisms.adoc index 50113d51a5..64d144f783 100644 --- a/_guides/security-authentication-mechanisms.adoc +++ b/_guides/security-authentication-mechanisms.adoc @@ -1,3 +1,8 @@ +//// +This document is maintained in the main Quarkus repository +and pull requests should be submitted there: +https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc +//// [id="security-authentication-mechanisms"] = Authentication mechanisms in Quarkus include::_attributes.adoc[] diff --git a/_guides/security-basic-authentication-howto.adoc b/_guides/security-basic-authentication-howto.adoc index 2f620a217c..f298a74372 100644 --- a/_guides/security-basic-authentication-howto.adoc +++ b/_guides/security-basic-authentication-howto.adoc @@ -1,3 +1,8 @@ +//// +This document is maintained in the main Quarkus repository +and pull requests should be submitted there: +https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc +//// [id="security-basic-authentication-howto"] = Enable Basic authentication include::_attributes.adoc[] diff --git a/_guides/security-basic-authentication-tutorial.adoc b/_guides/security-basic-authentication-tutorial.adoc index 1b62aecee6..b89c9fdcb3 100644 --- a/_guides/security-basic-authentication-tutorial.adoc +++ b/_guides/security-basic-authentication-tutorial.adoc @@ -1,3 +1,8 @@ +//// +This document is maintained in the main Quarkus repository +and pull requests should be submitted there: +https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc +//// [id="security-basic-authentication-tutorial"] = Secure a Quarkus application with Basic authentication and Jakarta Persistence include::_attributes.adoc[] diff --git a/_guides/security-basic-authentication.adoc b/_guides/security-basic-authentication.adoc index 99c3a392ee..5962a78d6b 100644 --- a/_guides/security-basic-authentication.adoc +++ b/_guides/security-basic-authentication.adoc @@ -1,3 +1,8 @@ +//// +This document is maintained in the main Quarkus repository +and pull requests should be submitted there: +https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc +//// [id="security-basic-authentication"] = Basic authentication include::_attributes.adoc[] diff --git a/_guides/security-csrf-prevention.adoc b/_guides/security-csrf-prevention.adoc index 76e22280dc..a417f5f086 100644 --- a/_guides/security-csrf-prevention.adoc +++ b/_guides/security-csrf-prevention.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Cross-Site Request Forgery Prevention - include::_attributes.adoc[] https://owasp.org/www-community/attacks/csrf[Cross-Site Request Forgery (CSRF)] is an attack that forces an end user to execute unwanted actions on a web application in which they are currently authenticated. @@ -58,14 +57,14 @@ Next, let's add a `csrfToken.html` Qute template producing an HTML form in the ` -User Name Input +User Name Input

User Name Input

<1> - +

Your Name:

diff --git a/_guides/security-customization.adoc b/_guides/security-customization.adoc index ab7faf8f9f..fedc190135 100644 --- a/_guides/security-customization.adoc +++ b/_guides/security-customization.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Security Tips and Tricks - include::_attributes.adoc[] == Quarkus Security Dependency @@ -621,6 +620,6 @@ xref:context-propagation.adoc[Context Propagation Guide]. == References * xref:security-overview.adoc[Quarkus Security overview] -* xref:security-architecture.adoc[Quarkus Security architecture] +* xref:security-architecture.adoc[Quarkus Security architecture] * xref:security-authentication-mechanisms.adoc#other-supported-authentication-mechanisms[Authentication mechanisms in Quarkus] * xref:security-identity-providers.adoc[Identity providers] diff --git a/_guides/security-jpa.adoc b/_guides/security-jpa.adoc index eb5faa68d4..8a5eaf4d13 100644 --- a/_guides/security-jpa.adoc +++ b/_guides/security-jpa.adoc @@ -1,3 +1,8 @@ +//// +This document is maintained in the main Quarkus repository +and pull requests should be submitted there: +https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc +//// [id="security-jpa"] = Quarkus Security with Jakarta Persistence include::_attributes.adoc[] diff --git a/_guides/security-jwt-build.adoc b/_guides/security-jwt-build.adoc index 9348c4629d..d96d1c1c8f 100644 --- a/_guides/security-jwt-build.adoc +++ b/_guides/security-jwt-build.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Build, Sign and Encrypt JSON Web Tokens - include::_attributes.adoc[] According to link:https://datatracker.ietf.org/doc/html/rfc7519[RFC7519], JSON Web Token (JWT) is a compact, URL-safe means of representing claims which are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code(MAC) and/or encrypted. diff --git a/_guides/security-keycloak-admin-client.adoc b/_guides/security-keycloak-admin-client.adoc index c27caf445b..7a82118a0c 100644 --- a/_guides/security-keycloak-admin-client.adoc +++ b/_guides/security-keycloak-admin-client.adoc @@ -4,8 +4,9 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Using Keycloak Admin Client - include::_attributes.adoc[] +:categories: security +:keywords: sso oidc security keycloak The Quarkus Keycloak Admin Client and its reactive twin support Keycloak Admin Client which can be used to configure a running Keycloak server. diff --git a/_guides/security-keycloak-authorization.adoc b/_guides/security-keycloak-authorization.adoc index 9a2ca199c9..f8b5024e74 100644 --- a/_guides/security-keycloak-authorization.adoc +++ b/_guides/security-keycloak-authorization.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Using OpenID Connect (OIDC) and Keycloak to Centralize Authorization include::_attributes.adoc[] :categories: security +:keywords: sso oidc security keycloak :summary: This guide demonstrates how your Quarkus application can authorize access to protected resources using Keycloak Authorization Services. This guide demonstrates how your Quarkus application can authorize a bearer token access to protected resources using https://www.keycloak.org/docs/latest/authorization_services/index.html[Keycloak Authorization Services]. diff --git a/_guides/security-oauth2.adoc b/_guides/security-oauth2.adoc index 9778c6883f..47b4199a03 100644 --- a/_guides/security-oauth2.adoc +++ b/_guides/security-oauth2.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Using OAuth2 RBAC include::_attributes.adoc[] :categories: security +:keywords: oauth :summary: This guide explains how your Quarkus application can utilize OAuth2 tokens to provide secured access to the Jakarta REST endpoints. :extension-name: Elytron Security OAuth2 diff --git a/_guides/security-oidc-code-flow-authentication-tutorial.adoc b/_guides/security-oidc-code-flow-authentication-tutorial.adoc index 3d7e1a525f..a6c8df4355 100644 --- a/_guides/security-oidc-code-flow-authentication-tutorial.adoc +++ b/_guides/security-oidc-code-flow-authentication-tutorial.adoc @@ -1,3 +1,8 @@ +//// +This document is maintained in the main Quarkus repository +and pull requests should be submitted there: +https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc +//// [id="security-oidc-code-flow-authentication-tutorial"] = Protect a web application by using OpenID Connect (OIDC) authorization code flow include::_attributes.adoc[] diff --git a/_guides/security-openid-connect-client-reference.adoc b/_guides/security-openid-connect-client-reference.adoc index f62ed9e681..2012fe9d79 100644 --- a/_guides/security-openid-connect-client-reference.adoc +++ b/_guides/security-openid-connect-client-reference.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = OpenID Connect (OIDC) and OAuth2 Client and Filters Reference Guide - include::_attributes.adoc[] This reference guide explains how to use: diff --git a/_guides/security-openid-connect-dev-services.adoc b/_guides/security-openid-connect-dev-services.adoc index 442c8a663b..2e8f93d2b2 100644 --- a/_guides/security-openid-connect-dev-services.adoc +++ b/_guides/security-openid-connect-dev-services.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Dev Services and UI for OpenID Connect (OIDC) include::_attributes.adoc[] :categories: security +:keywords: sso oidc security keycloak :summary: Start Keycloak or other providers automatically in dev and test modes. This guide covers the Dev Services and UI for OpenID Connect (OIDC) Keycloak provider and explains how to support Dev Services and UI for other OpenID Connect providers. diff --git a/_guides/security-openid-connect-multitenancy.adoc b/_guides/security-openid-connect-multitenancy.adoc index e9d0d0e48a..bd444ef9f9 100644 --- a/_guides/security-openid-connect-multitenancy.adoc +++ b/_guides/security-openid-connect-multitenancy.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Using OpenID Connect (OIDC) Multi-Tenancy include::_attributes.adoc[] :categories: security +:keywords: sso oidc oauth2 security :summary: This guide demonstrates how your OpenID Connect application can support multi-tenancy so that you can serve multiple tenants from a single application. This guide demonstrates how your OpenID Connect (OIDC) application can support multi-tenancy so that you can serve multiple tenants from a single application. Tenants can be distinct realms or security domains within the same OpenID Provider or even distinct OpenID Providers. @@ -590,9 +591,9 @@ To configure the resolution of the tenant identifier, use one of the following o [[default-tenant-resolver]] === Default resolution -The default resolution for a tenant identifier is convention based, whereby the authentication request must include the tenant identifier in the last segment of the request path. +The default resolution for a tenant identifier is convention based, whereby the authentication request must include the tenant identifier in the last segment of the request path. -The following `application.properties` example shows how you can configure two tenants named `google` and `github`: +The following `application.properties` example shows how you can configure two tenants named `google` and `github`: [source,properties] ---- @@ -609,7 +610,7 @@ quarkus.oidc.github.credentials.secret=${github-client-secret} quarkus.oidc.github.authentication.redirect-path=/signed-in ---- -In this example, both tenants configure OIDC `web-app` applications to use an authorization code flow to authenticate users and also require session cookies to get generated after the authentication has taken place. +In this example, both tenants configure OIDC `web-app` applications to use an authorization code flow to authenticate users and also require session cookies to get generated after the authentication has taken place. After either Google or GitHub authenticates the current user, the user gets returned to the `/signed-in` area for authenticated users, for example, a secured resource path on the JAX-RS endpoint. Finally, to complete the default tenant resolution, set the following configuration property: @@ -620,8 +621,8 @@ quarkus.http.auth.permission.login.paths=/google,/github quarkus.http.auth.permission.login.policy=authenticated ---- -If the endpoint is running on `http://localhost:8080`, you can also provide UI options for users to log in to either `http://localhost:8080/google` or `http://localhost:8080/github`, without having to add specific`/google` or `/github` JAX-RS resource paths. -Tenant identifiers are also recorded in the session cookie names after the authentication is completed. +If the endpoint is running on `http://localhost:8080`, you can also provide UI options for users to log in to either `http://localhost:8080/google` or `http://localhost:8080/github`, without having to add specific`/google` or `/github` JAX-RS resource paths. +Tenant identifiers are also recorded in the session cookie names after the authentication is completed. Therefore, authenticated users can access the secured application area without requiring either the `google` or `github` path values to be included in the secured URL. Default resolution can also work for Bearer token authentication but it might be less practical in this case because a tenant identifier will always need to be set as the last path segment value. @@ -629,7 +630,7 @@ Default resolution can also work for Bearer token authentication but it might be [[tenant-resolver]] === Resolve with `TenantResolver` -The following `application.properties` example shows how you can resolve the tenant identifier of two tenants named `a` and `b` by using the `TenantResolver` method: +The following `application.properties` example shows how you can resolve the tenant identifier of two tenants named `a` and `b` by using the `TenantResolver` method: [source,properties] ---- diff --git a/_guides/security-openid-connect-providers.adoc b/_guides/security-openid-connect-providers.adoc index eb204a6111..266d22c53c 100644 --- a/_guides/security-openid-connect-providers.adoc +++ b/_guides/security-openid-connect-providers.adoc @@ -8,6 +8,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: concept :categories: security,web +:keywords: oidc github twitter google facebook mastodon microsoft apple spotify twitch :toclevels: 3 This document explains how to configure well-known social OIDC and OAuth2 providers. @@ -178,7 +179,7 @@ quarkus.oidc.token.customizer-name=azure-access-token-customizer [[apple]] === Apple -In order to set up OIDC for Apple you need to create a developer account, and sign up for the 99€/year program, but you cannot test your application on `localhost` like most other OIDC providers: +In order to set up OIDC for Apple you need to create a developer account, and sign up for the 99€/year program, but you cannot test your application on `localhost` like most other OIDC providers: you will need to run it over `https` and make it publicly accessible, so for development purposes you may want to use a service such as https://ngrok.com. @@ -287,7 +288,7 @@ quarkus.oidc.credentials.jwt.subject= === Twitch Create a https://dev.twitch.tv/console/apps[Twitch application]: - + image::oidc-twitch-1.png[role="thumb"] You can now configure your `application.properties`: @@ -486,7 +487,7 @@ For more information, see the Quarkus xref:security-openid-connect-multitenancy. Sometimes, only authenticating users with a social provider is not enough. A provider-specific service also needs to be accessed for the Quarkus OIDC `web-app` application to fetch or update data from the provider service on behalf of the currently authenticated user. -As mentioned in the xref:security-oidc-code-flow-authentication.adoc[OIDC code flow mechanism for protecting web applications] guide, ID and access tokens are returned after the authorization code flow has been completed, with some providers like `GitHub` returning an access token only. +As mentioned in the xref:security-oidc-code-flow-authentication.adoc[OIDC code flow mechanism for protecting web applications] guide, ID and access tokens are returned after the authorization code flow has been completed, with some providers like `GitHub` returning an access token only. It is this access token that has to be propagated to services such as `Google Calendar`, or `Spotify Playlists` for the currently authenticated user to be able to use such services. You do not have to bring provider-specific libraries in order to achieve this, but instead you can use a reactive `Token Propagation` filter, which can be bound to a given REST client with a simple annotation. diff --git a/_guides/security-overview.adoc b/_guides/security-overview.adoc index 3a48aee911..1b59fc285c 100644 --- a/_guides/security-overview.adoc +++ b/_guides/security-overview.adoc @@ -1,3 +1,8 @@ +//// +This document is maintained in the main Quarkus repository +and pull requests should be submitted there: +https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc +//// [id="security-overview"] = Quarkus Security overview include::_attributes.adoc[] diff --git a/_guides/security-testing.adoc b/_guides/security-testing.adoc index b034619dde..629f9f3cd8 100644 --- a/_guides/security-testing.adoc +++ b/_guides/security-testing.adoc @@ -4,7 +4,6 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Security Testing - include::_attributes.adoc[] This document describes how to test Quarkus Security. diff --git a/_guides/smallrye-metrics.adoc b/_guides/smallrye-metrics.adoc index 36dd60967b..cbcf2f2237 100644 --- a/_guides/smallrye-metrics.adoc +++ b/_guides/smallrye-metrics.adoc @@ -3,7 +3,6 @@ This guide is maintained in the main Quarkus repository and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// - = SmallRye Metrics :extension-status: deprecated include::_attributes.adoc[] @@ -177,7 +176,7 @@ The application will respond that 350 is not a prime number because it can be di curl localhost:8080/629521085409773 ---- + -The application will respond that 629521085409773 is a prime number. +The application will respond that 629521085409773 is a prime number. .. Perform additional calls with numbers of your choice. diff --git a/_guides/stork-kubernetes.adoc b/_guides/stork-kubernetes.adoc index dce9a2509f..47d9cdd41b 100644 --- a/_guides/stork-kubernetes.adoc +++ b/_guides/stork-kubernetes.adoc @@ -5,7 +5,6 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Using Stork with Kubernetes :extension-status: preview - include::_attributes.adoc[] This guide explains how to use Stork with Kubernetes for service discovery and load balancing. diff --git a/_guides/stork-reference.adoc b/_guides/stork-reference.adoc index 0b1b477171..b91c726ee0 100644 --- a/_guides/stork-reference.adoc +++ b/_guides/stork-reference.adoc @@ -5,7 +5,6 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Stork Reference Guide :extension-status: preview - include::_attributes.adoc[] This guide is the companion from the xref:stork.adoc[Stork Getting Started Guide]. diff --git a/_guides/stork.adoc b/_guides/stork.adoc index b280b34f92..daf837aa4c 100644 --- a/_guides/stork.adoc +++ b/_guides/stork.adoc @@ -5,7 +5,6 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Getting Started with SmallRye Stork :extension-status: preview - include::_attributes.adoc[] The essence of distributed systems resides in the interaction between services. diff --git a/_guides/writing-extensions.adoc b/_guides/writing-extensions.adoc index 57be6822f4..0b55a3de31 100644 --- a/_guides/writing-extensions.adoc +++ b/_guides/writing-extensions.adoc @@ -1899,7 +1899,7 @@ The Jackson extension will then use the produced build item to register a module If you need more customization capabilities than registering a module, you can produce a CDI bean that implements `io.quarkus.jackson.ObjectMapperCustomizer` via an `AdditionalBeanBuildItem`. -More info about customizing Jackson can be found on the JSON guide xref:rest-json.adoc#configuring-json-support[Configuring JSON support] +More info about customizing Jackson can be found on the JSON guide xref:rest-json.adoc#json[Configuring JSON support] ==== Customizing JSON-B First, add an *optional* dependency to `quarkus-jsonb` on your extension's runtime module. diff --git a/_posts/2023-10-13-quarkus-3-4-3-released.adoc b/_posts/2023-10-13-quarkus-3-4-3-released.adoc new file mode 100644 index 0000000000..fc6a746bc9 --- /dev/null +++ b/_posts/2023-10-13-quarkus-3-4-3-released.adoc @@ -0,0 +1,45 @@ +--- +layout: post +title: 'Quarkus 3.4.3 released - Maintenance release' +date: 2023-10-13 +tags: release +synopsis: 'We released Quarkus 3.4.3, our second maintenance release for our 3.4 release train.' +author: gsmet +--- + +Today, we released Quarkus 3.4.3, our second maintenance release for our 3.4 release train (we skipped 3.4.0). + +It upgrades Netty to 4.1.100.Final, fixing CVE-2023-44487. +It also includes a bunch of bugfixes, together with documentation improvements. + +More releases are planned in the following days/weeks to address the issue in other maintained branches. + +== Update + +To update to Quarkus 3.4.3, we recommend updating to the latest version of the Quarkus CLI and run: + +[source,bash] +---- +quarkus update +---- + +To migrate from 3.3, please refer to https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.4[our migration guide]. + +If you are not already using 3.x, please refer to the https://quarkus.io/blog/quarkus-3-0-final-released/[3.0 announcement] for all the details. +You can also refer to https://quarkus.io/blog/quarkus-3-upgrade/[this blog post] for additional details. +Once you upgraded to 3.0, also have a look at the https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.1[3.1], https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.2[3.2], and https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.3[3.3] migration guides. + +== Full changelog + +You can get https://github.com/quarkusio/quarkus/releases/tag/3.4.3[the full changelog of 3.4.3 on GitHub]. + +== Come Join Us + +We value your feedback a lot so please report bugs, ask for improvements... Let's build something great together! + +If you are a Quarkus user or just curious, don't be shy and join our welcoming community: + + * provide feedback on https://github.com/quarkusio/quarkus/issues[GitHub]; + * craft some code and https://github.com/quarkusio/quarkus/pulls[push a PR]; + * discuss with us on https://quarkusio.zulipchat.com/[Zulip] and on the https://groups.google.com/d/forum/quarkus-dev[mailing list]; + * ask your questions on https://stackoverflow.com/questions/tagged/quarkus[Stack Overflow]. diff --git a/_versions/main/guides/_attributes.adoc b/_versions/main/guides/_attributes.adoc index d96d1a4f23..861bf4a7f6 100644 --- a/_versions/main/guides/_attributes.adoc +++ b/_versions/main/guides/_attributes.adoc @@ -4,7 +4,7 @@ :quarkus-version: 999-SNAPSHOT :quarkus-platform-groupid: io.quarkus.platform // . -:maven-version: 3.9.3 +:maven-version: 3.9.5 :graalvm-version: for JDK 17 :graalvm-docs-version: jdk17 :graalvm-flavor: jdk-17 diff --git a/_versions/main/guides/amqp-dev-services.adoc b/_versions/main/guides/amqp-dev-services.adoc index 09ce87e511..2c1bb488b3 100644 --- a/_versions/main/guides/amqp-dev-services.adoc +++ b/_versions/main/guides/amqp-dev-services.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: messaging :summary: Start AMQP automatically in dev and test modes. +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-amqp +:topics: messaging,amqp,devservices,tooling,testing,devmode Dev Services for AMQP automatically starts an AMQP 1.0 broker in dev mode and when running tests. So, you don't have to start a broker manually. diff --git a/_versions/main/guides/amqp-reference.adoc b/_versions/main/guides/amqp-reference.adoc index c67a951685..e09035b0ac 100644 --- a/_versions/main/guides/amqp-reference.adoc +++ b/_versions/main/guides/amqp-reference.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Reactive Messaging AMQP 1.0 Connector Reference Documentation include::_attributes.adoc[] +:categories: messaging +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-amqp +:topics: messaging,amqp This guide is the companion from the xref:amqp.adoc[Getting Started with AMQP 1.0]. It explains in more details the configuration and usage of the AMQP connector for reactive messaging. diff --git a/_versions/main/guides/amqp.adoc b/_versions/main/guides/amqp.adoc index 4c4f048302..7aa090e3aa 100644 --- a/_versions/main/guides/amqp.adoc +++ b/_versions/main/guides/amqp.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: messaging :summary: This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with AMQP. +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-amqp +:topics: messaging,amqp This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with AMQP 1.0. diff --git a/_versions/main/guides/ansible.adoc b/_versions/main/guides/ansible.adoc index 696d5d4bed..a2708dec90 100644 --- a/_versions/main/guides/ansible.adoc +++ b/_versions/main/guides/ansible.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: command-line :summary: Build and deploy your Quarkus App using Ansible +:topics: ansible,devops Let’s see how to build and deploy a Quarkus app using https://docs.ansible.com/ansible/latest/index.html[Ansible]. We’ll see how we can automate the entire process, from the code checkout to the application compilation using Maven and then its deployment and start of the service, as a https://systemd.io/[systemd service], on the target system using Ansible and its collection for Quarkus. diff --git a/_versions/main/guides/apicurio-registry-dev-services.adoc b/_versions/main/guides/apicurio-registry-dev-services.adoc index cc6020d803..0eb728d1d8 100644 --- a/_versions/main/guides/apicurio-registry-dev-services.adoc +++ b/_versions/main/guides/apicurio-registry-dev-services.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: messaging :summary: Start Apicurio Registry automatically in dev and test modes. +:topics: messaging,kafka,apicurio,registry,devservices,tooling,testing,devmode +:extensions: io.quarkus:quarkus-apicurio-registry-avro,io.quarkus:quarkus-smallrye-reactive-messaging-kafka If an extension for schema registry, such as `quarkus-apicurio-registry-avro` or `quarkus-confluent-registry-avro`, is present, Dev Services for Apicurio Registry automatically starts an Apicurio Registry instance in dev mode and when running tests. Also, all Kafka channels in SmallRye Reactive Messaging are automatically configured to use this registry. diff --git a/_versions/main/guides/appcds.adoc b/_versions/main/guides/appcds.adoc index 5811801c47..543d7da0c8 100644 --- a/_versions/main/guides/appcds.adoc +++ b/_versions/main/guides/appcds.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: core, cloud :summary: This reference guide explains how to enable AppCDS with Quarkus. +:topics: appcds,serverless +:extensions: io.quarkus:quarkus-core This reference guide explains how to enable Application Class Data Sharing in your Quarkus applications. diff --git a/_versions/main/guides/aws-lambda-http.adoc b/_versions/main/guides/aws-lambda-http.adoc index ccddd58c3e..969d448df5 100644 --- a/_versions/main/guides/aws-lambda-http.adoc +++ b/_versions/main/guides/aws-lambda-http.adoc @@ -9,6 +9,8 @@ include::_attributes.adoc[] :categories: cloud :summary: This guide explains how you can deploy Vert.x Web, Servlet, or RESTEasy microservices as an AWS Lambda. :devtools-no-gradle: +:topics: aws,lambda,serverless,function,cloud +:extensions: io.quarkus:quarkus-amazon-lambda,io.quarkus:quarkus-amazon-lambda-http With Quarkus you can deploy your favorite Java HTTP frameworks as AWS Lambda's using either the https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html[AWS Gateway HTTP API] or https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html[AWS Gateway REST API]. This means that you can deploy your microservices written with RESTEasy Reactive (our Jakarta REST implementation), diff --git a/_versions/main/guides/aws-lambda-snapstart.adoc b/_versions/main/guides/aws-lambda-snapstart.adoc index 735ece2efd..96a05da272 100644 --- a/_versions/main/guides/aws-lambda-snapstart.adoc +++ b/_versions/main/guides/aws-lambda-snapstart.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: This document explains how to optimize your AWS Lambda application for SnapStart +:topics: aws,lambda,serverless,function,snapstart,cloud https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html[SnapStart] is a snapshotting and restore mechanism reducing drastically the cold startup time of Java functions on AWS. This document explains the various settings you can use to leverage this feature. diff --git a/_versions/main/guides/aws-lambda.adoc b/_versions/main/guides/aws-lambda.adoc index b6756b6189..30fa81ee02 100644 --- a/_versions/main/guides/aws-lambda.adoc +++ b/_versions/main/guides/aws-lambda.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: This guide explains how you can deploy Quarkus-based AWS Lambdas. +:topics: aws,lambda,serverless,function,cloud +:extensions: io.quarkus:quarkus-amazon-lambda The `quarkus-amazon-lambda` extension allows you to use Quarkus to build your AWS Lambdas. Your lambdas can use injection annotations from CDI or Spring and other Quarkus facilities as you need them. diff --git a/_versions/main/guides/azure-functions-http.adoc b/_versions/main/guides/azure-functions-http.adoc index 4316d91605..a02be3bfb5 100644 --- a/_versions/main/guides/azure-functions-http.adoc +++ b/_versions/main/guides/azure-functions-http.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: Deploy Vert.x Web, Servlet, or RESTEasy microservices as a Microsoft Azure Function. +:topics: azure,serverless,function,cloud +:extensions: io.quarkus:quarkus-azure-functions-http The `quarkus-azure-functions-http` extension allows you to write microservices with RESTEasy Reactive (our Jakarta REST implementation), Undertow (servlet), Reactive Routes, or xref:funqy-http.adoc[Funqy HTTP] and make these microservices deployable to the Azure Functions runtime. diff --git a/_versions/main/guides/azure-functions.adoc b/_versions/main/guides/azure-functions.adoc index c58f6ece1d..743c9b867e 100644 --- a/_versions/main/guides/azure-functions.adoc +++ b/_versions/main/guides/azure-functions.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: Integrate Quarkus with the Microsoft Azure functions that you have written. +:topics: azure,serverless,function,cloud +:extensions: io.quarkus:quarkus-azure-functions The `quarkus-azure-functions` extension is a simple integration point between Azure Functions and Quarkus. It interacts with Azure Functions runtime to bootstrap quarkus and turns any diff --git a/_versions/main/guides/build-analytics.adoc b/_versions/main/guides/build-analytics.adoc index e14fedd57c..105c20cc95 100644 --- a/_versions/main/guides/build-analytics.adoc +++ b/_versions/main/guides/build-analytics.adoc @@ -6,6 +6,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Build analytics :categories: analytics :summary: This guide presents what build analytics is and how to configure it. +:extensions: io.quarkus:quarkus-core The Quarkus team has limited knowledge, from Maven download numbers, of the remarkable growth of Quarkus and the number of users reporting issues/concerns. Still, we need more insight into the platforms, operating system, Java combinations, and build tools our users employ. The build analytics tool aims to provide us with this information. diff --git a/_versions/main/guides/building-my-first-extension.adoc b/_versions/main/guides/building-my-first-extension.adoc index 3cc1d82011..e3a4f2d30a 100644 --- a/_versions/main/guides/building-my-first-extension.adoc +++ b/_versions/main/guides/building-my-first-extension.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: writing-extensions :summary: Learn step by step how to build a simple extension. +:topics: extensions Quarkus extensions enhance your application just as projects dependencies do. The role of the extensions is to leverage Quarkus paradigms to integrate seamlessly a library into Quarkus architecture - e.g. do more things at build time. diff --git a/_versions/main/guides/building-native-image.adoc b/_versions/main/guides/building-native-image.adoc index fac3dde559..f57ac2ed6c 100644 --- a/_versions/main/guides/building-native-image.adoc +++ b/_versions/main/guides/building-native-image.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: getting-started, native :summary: Build native executables with GraalVM or Mandrel. +:topics: native,graalvm,mandrel +:extensions: io.quarkus:quarkus-core This guide covers: diff --git a/_versions/main/guides/cache-redis-reference.adoc b/_versions/main/guides/cache-redis-reference.adoc index 917c8f8cf8..9adb78fb05 100644 --- a/_versions/main/guides/cache-redis-reference.adoc +++ b/_versions/main/guides/cache-redis-reference.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: Use Redis as the Quarkus cache backend +:topics: redis,cache,data +:extensions: io.quarkus:quarkus-redis-cache,io.quarkus:quarkus-redis-client By default, Quarkus Cache uses Caffeine as backend. It's possible to use Redis instead. diff --git a/_versions/main/guides/cache.adoc b/_versions/main/guides/cache.adoc index be9250f7a7..2325692686 100644 --- a/_versions/main/guides/cache.adoc +++ b/_versions/main/guides/cache.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: This guide explains how to cache expensive method calls of your CDI beans using simple annotations. +:topics: cache,data +:extensions: io.quarkus:quarkus-cache In this guide, you will learn how to enable application data caching in any CDI managed bean of your Quarkus application. diff --git a/_versions/main/guides/camel.adoc b/_versions/main/guides/camel.adoc index 23342f625f..823d5d830c 100644 --- a/_versions/main/guides/camel.adoc +++ b/_versions/main/guides/camel.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: integration :summary: This guide covers the systems integration with Apache Camel +:topics: camel,integration https://camel.apache.org/[Apache Camel] is the Swiss knife of integrating heterogeneous systems with more than a decade of history and a lively community of users and developers. diff --git a/_versions/main/guides/capabilities.adoc b/_versions/main/guides/capabilities.adoc index d98bef7068..6ef79dbf6a 100644 --- a/_versions/main/guides/capabilities.adoc +++ b/_versions/main/guides/capabilities.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: writing-extensions :summary: How capabilities are implemented and used in Quarkus. +:topics: extensions +:extensions: io.quarkus:quarkus-core Quarkus extensions may provide certain capabilities and require certain capabilities to be provided by other extensions in an application to function properly. @@ -146,7 +148,7 @@ quarkusExtension { NOTE: It is possible to specify `onlyIfNot` conditions as well. . Conditions can also be set for required capabilities. **** -In this case, `io.quarkus.container.image.openshift.deployment.OpenshiftBuild` should be included in one of the extension deployment dependencies and implement `java.util.function.BooleanSupplier`. At build time, the Quarkus bootstrap will create an instance of it and register `io.quarkus.container.image.openshift` capability only if its `getAsBoolean()` method returns true. +In this case, `io.quarkus.container.image.openshift.deployment.OpenshiftBuild` should be included in one of the extension deployment dependencies and implement `java.util.function.BooleanSupplier`. At build time, the Quarkus bootstrap will create an instance of it and register `io.quarkus.container.image.openshift` capability only if its `getAsBoolean()` method returns true. An implementation of the `OpenshiftBuild` could look like this: [source,java] diff --git a/_versions/main/guides/cassandra.adoc b/_versions/main/guides/cassandra.adoc index e68ada8b38..6889ff5feb 100644 --- a/_versions/main/guides/cassandra.adoc +++ b/_versions/main/guides/cassandra.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: This guide covers how to use the Apache Cassandra NoSQL database in Quarkus. +:topics: data,cassandra Apache Cassandra® is a free and open-source, distributed, wide column store, NoSQL database management system designed to handle large amounts of data across many commodity servers, providing diff --git a/_versions/main/guides/cdi-integration.adoc b/_versions/main/guides/cdi-integration.adoc index 0f5452d45f..844cd4208c 100644 --- a/_versions/main/guides/cdi-integration.adoc +++ b/_versions/main/guides/cdi-integration.adoc @@ -9,6 +9,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :numbered: :toclevels: 2 +:topics: cdi,arc,injection +:extensions: io.quarkus:quarkus-arc ArC, the CDI container in Quarkus, is bootstrapped at build time. To integrate with the container, https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#spi_lite[CDI Build Compatible Extensions, window="_blank"] can be used, as well as a Quarkus-specific extension API. @@ -19,7 +21,7 @@ The container is bootstrapped in multiple phases. From a high level perspective these phases go as follows: 1. Initialization -2. Bean discovery +2. Bean discovery 3. Registration of synthetic components 4. Validation @@ -40,7 +42,7 @@ In the following sections we will describe all the relevant build items and comm Classes and annotations are the primary source of bean-level metadata. The initial metadata are read from the _bean archive index_, an immutable https://github.com/wildfly/jandex[Jandex index, window="_blank"] which is built from various sources during xref:cdi-reference.adoc#bean_discovery[bean discovery]. However, extensions can add, remove or transform the metadata at certain stages of the bootstrap. -Moreover, extensions can also register xref:synthetic_beans[synthetic components]. +Moreover, extensions can also register xref:synthetic_beans[synthetic components]. This is an important aspect to realize when integrating CDI components in Quarkus. This way, extensions can turn classes, that would be otherwise ignored, into beans and vice versa. @@ -57,14 +59,14 @@ There are several reasons why a class is not recognized and also several ways to In the first step we should identify the _reason_. [[additional_bean_build_item]] -=== _Reason 1_: Class Is Not discovered +=== _Reason 1_: Class Is Not discovered Quarkus has a xref:cdi-reference.adoc#bean_discovery[simplified discovery]. It might happen that the class is not part of the application index. For example, classes from the _runtime module_ of a Quarkus extension are not indexed automatically. -_Solution_: Use the `AdditionalBeanBuildItem`. -This build item can be used to specify one or more additional classes to be analyzed during the discovery. +_Solution_: Use the `AdditionalBeanBuildItem`. +This build item can be used to specify one or more additional classes to be analyzed during the discovery. Additional bean classes are transparently added to the application index processed by the container. IMPORTANT: It is not possible to conditionally enable/disable additional beans via the `@IfBuildProfile`, `@UnlessBuildProfile`, `@IfBuildProperty` and `@UnlessBuildProperty` annotations as described in xref:cdi-reference.adoc#enable_build_profile[Enabling Beans for Quarkus Build Profile] and xref:cdi-reference.adoc#enable_build_properties[Enabling Beans for Quarkus Build Properties]. Extensions should inspect the configuration or the current profile and only produce an `AdditionalBeanBuildItem` if really needed. @@ -85,7 +87,7 @@ However, you can use `AdditionalBeanBuildItem.Builder.setUnremovable()` method t See also xref:cdi-reference.adoc#remove_unused_beans[Removing Unused Beans] and xref:unremovable_builditem[_Reason 3_: Class Was Discovered and Has a Bean Defining Annotation but Was Removed] for more details. It is aso possible to set the default scope via `AdditionalBeanBuildItem.Builder#setDefaultScope()`. -The default scope is only used if there is no scope declared on the bean class. +The default scope is only used if there is no scope declared on the bean class. NOTE: If no default scope is specified the `@Dependent` pseudo-scope is used. @@ -127,7 +129,7 @@ However, you can change the default behavior. See also xref:cdi-reference.adoc#remove_unused_beans[Removing Unused Beans] and xref:unremovable_builditem[_Reason 3_: Class Was Discovered and Has a Bean Defining Annotation but Was Removed] for more details. It is also possible to specify the default scope. -The default scope is only used if there is no scope declared on the bean class. +The default scope is only used if there is no scope declared on the bean class. NOTE: If no default scope is specified the `@Dependent` pseudo-scope is used. @@ -136,7 +138,7 @@ NOTE: If no default scope is specified the `@Dependent` pseudo-scope is used. The container attempts to xref:cdi-reference.adoc#remove_unused_beans[remove all unused beans] during the build by default. This optimization allows for _framework-level dead code elimination_. -In few special cases, it's not possible to correctly identify an unused bean. +In few special cases, it's not possible to correctly identify an unused bean. In particular, Quarkus is not able to detect the usage of the `CDI.current()` static method yet. Extensions can eliminate possible false positives by producing an `UnremovableBeanBuildItem`. @@ -155,7 +157,7 @@ UnremovableBeanBuildItem unremovableBeans() { It is likely that the annotation class is not part of the application index. For example, classes from the _runtime module_ of a Quarkus extension are not indexed automatically. -_Solution_: Use the `AdditionalBeanBuildItem` as described in xref:additional_bean_build_item[_Reason 1_: Class Is Not discovered]. +_Solution_: Use the `AdditionalBeanBuildItem` as described in xref:additional_bean_build_item[_Reason 1_: Class Is Not discovered]. [[annotations_transformer_build_item]] == Use Case - I Need To Transform Annotation Metadata @@ -297,8 +299,8 @@ SyntheticBeanBuildItem syntheticBean() { ---- <1> Generate the bytecode of the `jakarta.enterprise.context.spi.Contextual#create(CreationalContext)` implementation. -The output of a bean configurator is recorded as bytecode. -Therefore, there are some limitations in how a synthetic bean instance is created at runtime. +The output of a bean configurator is recorded as bytecode. +Therefore, there are some limitations in how a synthetic bean instance is created at runtime. You can: 1. Generate the bytecode of the `Contextual#create(CreationalContext)` method directly via `ExtendedBeanConfigurator.creator(Consumer)`. @@ -344,7 +346,7 @@ Synthetic beans initialized during `RUNTIME_INIT` must not be accessed during `S [source,java] ---- @BuildStep -@Record(RUNTIME_INIT) +@Record(RUNTIME_INIT) @Consume(SyntheticBeansRuntimeInitBuildItem.class) <1> void accessFoo(TestRecorder recorder) { recorder.foo(); <2> @@ -411,7 +413,7 @@ IMPORTANT: A build step that consumes the `ObserverRegistrationPhaseBuildItem` s ---- @BuildStep void syntheticObserver(ObserverRegistrationPhaseBuildItem observerRegistrationPhase, - BuildProducer myBuildItem, + BuildProducer myBuildItem, BuildProducer observerConfigurationRegistry) { observerConfigurationRegistry.produce(new ObserverConfiguratorBuildItem(observerRegistrationPhase.getContext() .configure() @@ -424,8 +426,8 @@ void syntheticObserver(ObserverRegistrationPhaseBuildItem observerRegistrationPh } ---- -The output of a `ObserverConfigurator` is recorded as bytecode. -Therefore, there are some limitations in how a synthetic observer is invoked at runtime. +The output of a `ObserverConfigurator` is recorded as bytecode. +Therefore, there are some limitations in how a synthetic observer is invoked at runtime. Currently, you must generate the bytecode of the method body directly. [[generated_beans]] @@ -462,7 +464,7 @@ IMPORTANT: A build step that consumes the `ValidationPhaseBuildItem` should alwa ---- @BuildStep void validate(ValidationPhaseBuildItem validationPhase, - BuildProducer myBuildItem, + BuildProducer myBuildItem, BuildProducer errors) { if (someCondition) { errors.produce(new ValidationErrorBuildItem(new IllegalStateException())); @@ -606,7 +608,7 @@ NOTE: In theory, you can use xref:annotations_transformer_build_item[an `Annotat == Use Case - Resource Annotations and Injection The `ResourceAnnotationBuildItem` can be used to specify resource annotations that make it possible to resolve non-CDI injection points, such as Jakarta EE resources. -An integrator must also provide a corresponding `io.quarkus.arc.ResourceReferenceProvider` service provider implementation. +An integrator must also provide a corresponding `io.quarkus.arc.ResourceReferenceProvider` service provider implementation. .`ResourceAnnotationBuildItem` Example [source,java] diff --git a/_versions/main/guides/cdi-reference.adoc b/_versions/main/guides/cdi-reference.adoc index 5b8b6d8234..6252d94271 100644 --- a/_versions/main/guides/cdi-reference.adoc +++ b/_versions/main/guides/cdi-reference.adoc @@ -11,6 +11,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: cdi,arc,injection,interceptor,observer +:extensions: io.quarkus:quarkus-arc Quarkus DI solution (also called ArC) is based on the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html[Jakarta Contexts and Dependency Injection 4.0, window="_blank"] specification. It implements the CDI Lite specification, with selected improvements on top, and passes the CDI Lite TCK. diff --git a/_versions/main/guides/cdi.adoc b/_versions/main/guides/cdi.adoc index 2d5a259f04..2b64bbb968 100644 --- a/_versions/main/guides/cdi.adoc +++ b/_versions/main/guides/cdi.adoc @@ -11,6 +11,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: cdi,arc,injection,interceptor,observer +:extensions: io.quarkus:quarkus-arc In this guide we're going to describe the basic principles of the Quarkus programming model that is based on the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html[Jakarta Contexts and Dependency Injection 4.0, window="_blank"] specification. diff --git a/_versions/main/guides/centralized-log-management.adoc b/_versions/main/guides/centralized-log-management.adoc index cd640e7289..d023932671 100644 --- a/_versions/main/guides/centralized-log-management.adoc +++ b/_versions/main/guides/centralized-log-management.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: observability :summary: This guide explains how to centralize your logs with Logstash or Fluentd using the Graylog Extended Log Format (GELF). +:topics: observability,logging +:extensions: io.quarkus:quarkus-logging-gelf This guide explains how you can send your logs to a centralized log management system like Graylog, Logstash (inside the Elastic Stack or ELK - Elasticsearch, Logstash, Kibana) or Fluentd (inside EFK - Elasticsearch, Fluentd, Kibana). diff --git a/_versions/main/guides/class-loading-reference.adoc b/_versions/main/guides/class-loading-reference.adoc index c0ec0659df..65cd0c98e5 100644 --- a/_versions/main/guides/class-loading-reference.adoc +++ b/_versions/main/guides/class-loading-reference.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: architecture :summary: Learn more about Quarkus class loading infrastructure. +:topics: internals,extensions +:extensions: io.quarkus:quarkus-core This document explains the Quarkus class loading architecture. It is intended for extension authors and advanced users who want to understand exactly how Quarkus works. @@ -70,7 +72,7 @@ image::classloader-hierarchy.png[alt=Quarkus ClassLoader hierarchy,role="center" Here are the roles of each ClassLoader: -Base ClassLoader:: +Base ClassLoader:: This is usually the normal JVM System ClassLoader. In some environments such as Maven it may be different. This ClassLoader is used to load the bootstrap classes, and other ClassLoader instances will delegate the loading of JDK classes to it. diff --git a/_versions/main/guides/cli-tooling.adoc b/_versions/main/guides/cli-tooling.adoc index 5f276455e4..c5a4351b6a 100644 --- a/_versions/main/guides/cli-tooling.adoc +++ b/_versions/main/guides/cli-tooling.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: tooling :summary: Use the Quarkus CLI to create, build, run, and manage extensions for Quarkus projects. +:topics: cli,tooling The `quarkus` command lets you create projects, manage extensions and do essential build and development tasks using the underlying project build tool. diff --git a/_versions/main/guides/command-mode-reference.adoc b/_versions/main/guides/command-mode-reference.adoc index 6874ce971c..7fc9b2a7ec 100644 --- a/_versions/main/guides/command-mode-reference.adoc +++ b/_versions/main/guides/command-mode-reference.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: core, command-line :summary: This reference guide explains how to develop command line applications with Quarkus. +:topics: command-line,cli +:extensions: io.quarkus:quarkus-core This reference covers how to write applications that run and then exit. @@ -163,7 +165,7 @@ quarkus dev '--help' ./gradlew quarkusDev --quarkus-args='--help' ---- -You should see the following down the bottom of the screen after the application is stopped: +You should see the following down the bottom of the screen after the application is stopped: [source] ---- diff --git a/_versions/main/guides/conditional-extension-dependencies.adoc b/_versions/main/guides/conditional-extension-dependencies.adoc index db3bbfad4c..1aec001d92 100644 --- a/_versions/main/guides/conditional-extension-dependencies.adoc +++ b/_versions/main/guides/conditional-extension-dependencies.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: writing-extensions :summary: Trigger the inclusion on additional extensions based on certain conditions. +:topics: extensions +:extensions: io.quarkus:quarkus-core Quarkus extension dependencies are usually configured in the same way as any other project dependencies in the project's build file, e.g. the Maven `pom.xml` or the Gradle build scripts. However, there are dependency types that aren't yet supported out-of-the-box by Maven and Gradle. What we refer here to as "conditional dependencies" is one example. @@ -37,7 +39,7 @@ The condition which triggers activation of an extension is configured in the ext - + io.quarkus quarkus-extension-maven-plugin @@ -148,7 +150,7 @@ Conditional dependencies can also be configured in the Quarkus extension descrip - + io.quarkus quarkus-extension-maven-plugin diff --git a/_versions/main/guides/config-extending-support.adoc b/_versions/main/guides/config-extending-support.adoc index 80a84b2fa5..aca5e13344 100644 --- a/_versions/main/guides/config-extending-support.adoc +++ b/_versions/main/guides/config-extending-support.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: configuration +:extensions: io.quarkus:quarkus-core [[custom-config-source]] == Custom `ConfigSource` diff --git a/_versions/main/guides/config-mappings.adoc b/_versions/main/guides/config-mappings.adoc index f7822cc0bd..89d8265828 100644 --- a/_versions/main/guides/config-mappings.adoc +++ b/_versions/main/guides/config-mappings.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: configuration +:extensions: io.quarkus:quarkus-core With config mappings it is possible to group multiple configuration properties in a single interface that share the same prefix. diff --git a/_versions/main/guides/config-reference.adoc b/_versions/main/guides/config-reference.adoc index e2e46992bb..d484468896 100644 --- a/_versions/main/guides/config-reference.adoc +++ b/_versions/main/guides/config-reference.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: configuration +:extensions: io.quarkus:quarkus-core IMPORTANT: The content of this guide has been revised and split into additional topics. Please check the xref:additional-information[Additional Information] section. @@ -704,6 +706,68 @@ options exposed by a `org.eclipse.microprofile.config.Config` instance. Which me build configuration options since MicroProfile Config specification allows configuration sources not to expose all the property names they provide to users. ==== +== Config property values injected during static intialization phase + +Quarkus collects the config property values injected in CDI beans during xref:writing-extensions.adoc#bootstrap-three-phases[static intialization phase]. +The collected values are then compared with their runtime initialization counterparts and if a mismatch is detected the application startup fails. +How can it happen? +For example, let's have a CDI bean `org.acme.MyBean`. +`MyBean` injects a `@ConfigProperty` of name `foo` and is initialized during the native build. +The config property does not exist during the native build and so the default value `bar` is used. +But later, when the application is started the property is defined with a system property: `-Dfoo=baz`. +This would lead to inconsistent state and unexpected behavior. +Therefore, Quarkus would fail in this situation by default. + +[source,java] +---- +package org.acme; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.event.Observes; +import jakarta.enterprise.context.Initialized; +import org.eclipse.microprofile.config.inject.ConfigProperty; + +@ApplicationScoped +public class MyBean { + + @ConfigProperty(name = "foo", defaultValue = "bar") <1> + String foo; + + void onInit(@Observes @Initialized(ApplicationScoped.class) Object event) { <2> + // this observer method is notified during STATIC_INIT... + } +} +---- +<1> The config property is injected when the bean is created and the value is fixed. +<2> In this particular case, the observer `@Initialized(ApplicationScoped.class)` caused the initialization of the bean. However, there are other possibilities. For example, some extensions initialize components during static intialization phase. + +You can annotate an injected field/parameter with `@io.quarkus.runtime.annotations.StaticInitSafe` to mark the injected configuration object as safe to be initialized during the static intialization phase. + +[source,java] +---- +package org.acme; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.event.Observes; +import jakarta.enterprise.context.Initialized; +import org.eclipse.microprofile.config.inject.ConfigProperty; +import io.quarkus.runtime.annotations.StaticInitSafe; + +@ApplicationScoped +public class MyBeanNoFailure { + + @StaticInitSafe <1> + @ConfigProperty(name = "foo", defaultValue = "bar") + String foo; + + void onInit(@Observes @Initialized(ApplicationScoped.class) Object event) { + // this observer method is notified during STATIC_INIT... + } +} +---- +<1> Instructs Quarkus not to fail if a mismatch is detected. + + [[additional-information]] == Additional Information diff --git a/_versions/main/guides/config-yaml.adoc b/_versions/main/guides/config-yaml.adoc index 33109f1b38..4755ae64e3 100644 --- a/_versions/main/guides/config-yaml.adoc +++ b/_versions/main/guides/config-yaml.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: core :summary: YAML as a Configuration Source. +:topics: configuration +:extensions: io.quarkus:quarkus-config-yaml https://en.wikipedia.org/wiki/YAML[YAML] is a very popular format. Kubernetes relies heavily on the YAML format to write the various resource descriptors. diff --git a/_versions/main/guides/config.adoc b/_versions/main/guides/config.adoc index 93f6d1a2f1..9bd5cfa17b 100644 --- a/_versions/main/guides/config.adoc +++ b/_versions/main/guides/config.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: core :summary: Hardcoded values in your code is a no go (even if we all did it at some point ;-)). In this guide, we learn how to configure your application. +:topics: configuration +:extensions: io.quarkus:quarkus-core IMPORTANT: The content of this guide and been revised and split into additional topics. Please check the xref:additional-information[Additional Information] section. diff --git a/_versions/main/guides/container-image.adoc b/_versions/main/guides/container-image.adoc index 8c88f65f82..ef81467add 100644 --- a/_versions/main/guides/container-image.adoc +++ b/_versions/main/guides/container-image.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: Learn how to build and push container images with Jib, OpenShift or Docker as part of the Quarkus build. +:topics: devops,cloud +:extensions: io.quarkus:quarkus-container-image-openshift,io.quarkus:quarkus-container-image-jib,io.quarkus:quarkus-container-image-docker,io.quarkus:quarkus-container-image-buildpack Quarkus provides extensions for building (and pushing) container images. Currently, it supports: @@ -138,7 +140,7 @@ The creation of such objects is being taken care of by the Quarkus Kubernetes ex [#buildpack] === Buildpack -The extension `quarkus-container-image-buildpack` is using buildpacks in order to perform container image builds. +The extension `quarkus-container-image-buildpack` is using buildpacks in order to perform container image builds. Under the hood buildpacks will use a Docker daemon for the actual build. While buildpacks support alternatives to Docker, this extension will only work with Docker. diff --git a/_versions/main/guides/context-propagation.adoc b/_versions/main/guides/context-propagation.adoc index d3ebafa9ce..deffd04652 100644 --- a/_versions/main/guides/context-propagation.adoc +++ b/_versions/main/guides/context-propagation.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: core :summary: Learn more about how you can pass contextual information with SmallRye Context Propagation. +:topics: context-propagation +:extensions: io.quarkus:quarkus-core Traditional blocking code uses link:https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ThreadLocal.html[`ThreadLocal`] variables to store contextual objects in order to avoid diff --git a/_versions/main/guides/continuous-testing.adoc b/_versions/main/guides/continuous-testing.adoc index ab794ab3a6..6be909bc95 100644 --- a/_versions/main/guides/continuous-testing.adoc +++ b/_versions/main/guides/continuous-testing.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: testing,dev-ui,tooling,devmode +:extensions: io.quarkus:quarkus-core Learn how to use continuous testing in your Quarkus Application. diff --git a/_versions/main/guides/credentials-provider.adoc b/_versions/main/guides/credentials-provider.adoc index 7a5c745b60..579ea95715 100644 --- a/_versions/main/guides/credentials-provider.adoc +++ b/_versions/main/guides/credentials-provider.adoc @@ -8,6 +8,7 @@ include::_attributes.adoc[] :categories: security :summary: This guides explains how to use the Vault credentials provider or implement your own custom one. :extension-status: preview +:topics: security,credentials Interacting with a datastore typically implies first connecting using credentials. Those credentials will allow the client to be identified, authenticated and eventually authorized. @@ -147,14 +148,14 @@ Here is a simple example: @Unremovable public class MyCredentialsProvider implements CredentialsProvider { - @Override - public Map getCredentials(String credentialsProviderName) { + @Override + public Map getCredentials(String credentialsProviderName) { - Map properties = new HashMap<>(); - properties.put(USER_PROPERTY_NAME, "hibernate_orm_test"); - properties.put(PASSWORD_PROPERTY_NAME, "hibernate_orm_test"); - return properties; - } + Map properties = new HashMap<>(); + properties.put(USER_PROPERTY_NAME, "hibernate_orm_test"); + properties.put(PASSWORD_PROPERTY_NAME, "hibernate_orm_test"); + return properties; + } } ---- @@ -189,6 +190,7 @@ public Map getCredentials(String credentialsProviderName) { System.out.println("MyCredentialsProvider called with foo=" + config.getValue(credentialsProviderName + ".foo", String.class)); ... +} ---- == New Credentials Provider extension diff --git a/_versions/main/guides/databases-dev-services.adoc b/_versions/main/guides/databases-dev-services.adoc index 2bb6a154a1..740727c581 100644 --- a/_versions/main/guides/databases-dev-services.adoc +++ b/_versions/main/guides/databases-dev-services.adoc @@ -6,6 +6,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Dev Services for Databases :categories: data, tooling include::_attributes.adoc[] +:topics: devservices,data,database,datasource,tooling,testing,devmode +:extensions: io.quarkus:quarkus-agroal,io.quarkus:quarkus-reactive-mysql-client,io.quarkus:quarkus-reactive-oracle-client,io.quarkus:quarkus-reactive-pg-client,io.quarkus:quarkus-jdbc-db2,io.quarkus:quarkus-jdbc-derby,io.quarkus:quarkus-jdbc-h2,io.quarkus:quarkus-jdbc-mariadb,io.quarkus:quarkus-jdbc-mssql,io.quarkus:quarkus-jdbc-mysql,io.quarkus:quarkus-jdbc-oracle,io.quarkus:quarkus-jdbc-postgresql When testing or running in dev mode Quarkus can provide you with a zero-config database out of the box, a feature we refer to as Dev Services. Depending on your database type you may need Docker installed in order to use this feature. diff --git a/_versions/main/guides/datasource.adoc b/_versions/main/guides/datasource.adoc index 709236d59b..e969afdc82 100644 --- a/_versions/main/guides/datasource.adoc +++ b/_versions/main/guides/datasource.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: reference :categories: data,getting-started,reactive +:topics: data,database,datasource,sql,jdbc,reactive +:extensions: io.quarkus:quarkus-agroal,io.quarkus:quarkus-reactive-mysql-client,io.quarkus:quarkus-reactive-oracle-client,io.quarkus:quarkus-reactive-pg-client,io.quarkus:quarkus-reactive-db2-client,io.quarkus:quarkus-reactive-pg-client,io.quarkus:quarkus-reactive-mssql-client,io.quarkus:quarkus-jdbc-db2,io.quarkus:quarkus-jdbc-derby,io.quarkus:quarkus-jdbc-h2,io.quarkus:quarkus-jdbc-mariadb,io.quarkus:quarkus-jdbc-mssql,io.quarkus:quarkus-jdbc-mysql,io.quarkus:quarkus-jdbc-oracle,io.quarkus:quarkus-jdbc-postgresql Use a unified configuration model to define data sources for Java Database Connectivity (JDBC) and Reactive drivers. diff --git a/_versions/main/guides/deploying-to-azure-cloud.adoc b/_versions/main/guides/deploying-to-azure-cloud.adoc index c611f4e7e3..138ab12b8a 100644 --- a/_versions/main/guides/deploying-to-azure-cloud.adoc +++ b/_versions/main/guides/deploying-to-azure-cloud.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: Deploy a Quarkus application to the Microsoft Azure cloud platform. +:topics: devops,azure,cloud,deployment This guide covers: diff --git a/_versions/main/guides/deploying-to-google-cloud.adoc b/_versions/main/guides/deploying-to-google-cloud.adoc index 9bc36ffa2f..534901043c 100644 --- a/_versions/main/guides/deploying-to-google-cloud.adoc +++ b/_versions/main/guides/deploying-to-google-cloud.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: This guide explains how to deploy a Quarkus application to Google Cloud. +:topics: devops,google,gcp,cloud,deployment This guide covers: diff --git a/_versions/main/guides/deploying-to-heroku.adoc b/_versions/main/guides/deploying-to-heroku.adoc index e9c7feeabd..73637d12be 100644 --- a/_versions/main/guides/deploying-to-heroku.adoc +++ b/_versions/main/guides/deploying-to-heroku.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: Deploy your Quarkus applications on Heroku. +:topics: devops,heroku,cloud,deployment In this guide you will learn how to deploy a Quarkus based web application as a web-dyno to Heroku. @@ -152,7 +153,7 @@ git add pom.xml git commit -am "Add container-image-docker extension." ---- -The image we are going to build needs to be named accordingly to work with Heroku's registry and deployment. +The image we are going to build needs to be named accordingly to work with Heroku's registry and deployment. We get the generated name via `heroku info` and pass it on to the (local) build: [source,bash] diff --git a/_versions/main/guides/deploying-to-kubernetes.adoc b/_versions/main/guides/deploying-to-kubernetes.adoc index ef4d73afed..988d717e3b 100644 --- a/_versions/main/guides/deploying-to-kubernetes.adoc +++ b/_versions/main/guides/deploying-to-kubernetes.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud, native :summary: This guide covers how to deploy a native application on Kubernetes. +:topics: devops,kubernetes,cloud,deployment +:extensions: io.quarkus:quarkus-kubernetes Quarkus offers the ability to automatically generate Kubernetes resources based on sane defaults and user-supplied configuration using https://github.com/dekorateio/dekorate/[dekorate]. It currently supports generating resources for vanilla xref:kubernetes[Kubernetes], xref:openshift[OpenShift] and xref:knative[Knative]. @@ -191,7 +193,7 @@ spec: ... ---- -The `app.quarkus.io/commit-id`, `app.quarkus.io/build-timestamp` labels and the `app.kubernetes.io/version` annotation might change every time we re-build the Kubernetes manifests which can be problematic when we want to deploy these resources using a Git-Ops tool (because these tools will detect differences and hence will perform a re-deployment). +The `app.quarkus.io/commit-id`, `app.quarkus.io/build-timestamp` labels and the `app.kubernetes.io/version` annotation might change every time we re-build the Kubernetes manifests which can be problematic when we want to deploy these resources using a Git-Ops tool (because these tools will detect differences and hence will perform a re-deployment). To make the generated resources Git-Ops friendly and only produce idempotent resources (resources that won't change every time we build the sources), we need to add the following property: @@ -209,7 +211,7 @@ quarkus.kubernetes.output-directory=target/kubernetes-with-idempotent [NOTE] ==== -Note that the property `quarkus.kubernetes.output-directory` is relative to the current project location. +Note that the property `quarkus.kubernetes.output-directory` is relative to the current project location. ==== === Changing the generated deployment resource @@ -266,7 +268,7 @@ To specify the namespace in your manifest customize with the following property [source,properties] ---- -quarkus.kubernetes.namespace=mynamespace +quarkus.kubernetes.namespace=mynamespace ---- === Defining a Docker registry @@ -895,7 +897,7 @@ implementation("io.quarkus:quarkus-kubernetes-client") ---- To access the API server from within a Kubernetes cluster, some RBAC related resources are required (e.g. a ServiceAccount, a RoleBinding). -To ease the usage of the `kubernetes-client` extension, the `kubernetes` extension is going to generate a RoleBinding resource that binds a cluster role named "view" to the application ServiceAccount resource. It's important to note that the cluster role "view" won't be generated automatically, so it's expected that you have this cluster role with name "view" already installed in your cluster. +To ease the usage of the `kubernetes-client` extension, the `kubernetes` extension is going to generate a RoleBinding resource that binds a cluster role named "view" to the application ServiceAccount resource. It's important to note that the cluster role "view" won't be generated automatically, so it's expected that you have this cluster role with name "view" already installed in your cluster. On the other hand, you can fully customize the roles, subjects and role bindings to generate using the properties under `quarkus.kubernetes.rbac.role-bindings`, and if present, the `kubernetes-client` extension will use it and hence won't generate any RoleBinding resource. @@ -918,7 +920,7 @@ quarkus.kubernetes.rbac.roles.my-role.policy-rules.0.verbs=list <1> In this example, the role "my-role" will be generated with a policy rule to get the list of deployments. -By default, if one role is configured, a RoleBinding resource will be generated as well to link this role with the ServiceAccount resource. +By default, if one role is configured, a RoleBinding resource will be generated as well to link this role with the ServiceAccount resource. Moreover, you can have more control over the RBAC resources to be generated: @@ -940,9 +942,9 @@ quarkus.kubernetes.rbac.role-bindings.my-role-binding.role-name=my-role <1> In this example, the role "my-role" will be generated with the specified policy rules. <2> Also, the service account "my-service-account" will be generated. -<3> And we can configure the generated RoleBinding resource by selecting the role to be used and the subject. +<3> And we can configure the generated RoleBinding resource by selecting the role to be used and the subject. -Finally, we can also generate the cluster wide role resource of "ClusterRole" kind and a "ClusterRoleBinding" resource as follows: +Finally, we can also generate the cluster wide role resource of "ClusterRole" kind and a "ClusterRoleBinding" resource as follows: [source,properties] ---- @@ -1094,7 +1096,7 @@ quarkus extension remove kubernetes,jib quarkus extension add openshift oc new-project quarkus-project -quarkus build -Dquarkus.container-image.build=true +quarkus build -Dquarkus.container-image.build=true oc new-app --name=greeting quarkus-project/kubernetes-quickstart:1.0.0-SNAPSHOT oc expose svc/greeting @@ -1109,7 +1111,7 @@ curl /greeting ./mvnw quarkus:add-extension -Dextensions="openshift" oc new-project quarkus-project -./mvnw clean package -Dquarkus.container-image.build=true +./mvnw clean package -Dquarkus.container-image.build=true oc new-app --name=greeting quarkus-project/kubernetes-quickstart:1.0.0-SNAPSHOT oc expose svc/greeting @@ -1124,7 +1126,7 @@ curl /greeting ./gradlew addExtension --extensions="openshift" oc new-project quarkus-project -./gradlew build -Dquarkus.container-image.build=true +./gradlew build -Dquarkus.container-image.build=true oc new-app --name=greeting quarkus-project/kubernetes-quickstart:1.0.0-SNAPSHOT oc expose svc/greeting @@ -1382,7 +1384,7 @@ Finally, all you need to do is to configure your favorite IDE to attach the java Sometimes it's desirable to either provide additional resources (e.g. a ConfigMap, a Secret, a Deployment for a database) or provide custom ones that will be used as a `base` for the generation process. Those resources can be added under `src/main/kubernetes` directory and can be named after the target environment (e.g. kubernetes.json, openshift.json, knative.json, or the yml equivalents). The correlation between provided and generated files is done by file name. -So, a `kubernetes.json`/`kubernetes.yml` file added in `src/main/kubernetes` will only affect the generated `kubernetes.json`/`kubernetes.yml`. An `openshift.json`/`openshift.yml` file added in `src/main/kubernetes` will only affect the generated `openshift.json`/`openshift.yml`. +So, a `kubernetes.json`/`kubernetes.yml` file added in `src/main/kubernetes` will only affect the generated `kubernetes.json`/`kubernetes.yml`. An `openshift.json`/`openshift.yml` file added in `src/main/kubernetes` will only affect the generated `openshift.json`/`openshift.yml`. A `knative.json`/`knative.yml` file added in `src/main/kubernetes` will only affect the generated `knative.json`/`knative.yml` and so on. The provided file may be either in json or yaml format and may contain one or more resources. These resources will end up in both generated formats (json and yaml). For example, a secret added in `src/main/kubernetes/kubernetes.yml` will be added to both the generated `kubernetes.yml` and `kubernetes.json`. Note: At the time of writing there is no mechanism in place that allows a one-to-many relationship between provided and generated files. Minikube is not an exception to the rule above, so if you want to customize the generated minikube manifests, the file placed under `src/main/kubernetes` will have to be named `minikube.json` or `minikube.yml` (naming it `kubernetes.yml` or `kubernetes.json` will result in having only the generated `kubernetes.yml` and `kubernetes.json` affected). @@ -1521,13 +1523,13 @@ To enable Service Binding for supported extensions, add the `quarkus-kubernetes- Workload Projection is a process of obtaining the configuration for services from the Kubernetes cluster. This configuration takes the form of directory structures that follow certain conventions and is attached to an application or to a service as a mounted volume. The `kubernetes-service-binding` extension uses this directory structure to create configuration sources, which allows you to configure additional modules, such as databases or message brokers. -During application development, users can use workload projection to connect their application to a development database, or other locally-run services, without changing the actual application code or configuration. +During application development, users can use workload projection to connect their application to a development database, or other locally-run services, without changing the actual application code or configuration. For an example of a workload projection where the directory structure is included in the test resources and passed to integration test, see the link:https://github.com/quarkusio/quarkus/tree/e7efe6b3efba91b9c4ae26f9318f8397e23e7505/integration-tests/kubernetes-service-binding-jdbc/src/test/resources/k8s-sb[Kubernetes Service Binding datasource] GitHub repository. [NOTE] ==== -* The `k8s-sb` directory is the root of all service bindings. In this example, only one database called `fruit-db` is intended to be bound. This binding database has the `type` file, that indicates `postgresql` as the database type, while the other files in the directory provide the necessary information to establish the connection. +* The `k8s-sb` directory is the root of all service bindings. In this example, only one database called `fruit-db` is intended to be bound. This binding database has the `type` file, that indicates `postgresql` as the database type, while the other files in the directory provide the necessary information to establish the connection. * After your Quarkus project obtains information from `SERVICE_BINDING_ROOT` environment variables that are set by OpenShift, you can locate generated configuration files that are present in the file system and use them to map the configuration-file values to properties of certain extensions. ==== @@ -1620,10 +1622,10 @@ NOTE: Automatic service binding can be generated for a limited number of service .Operators that support the service auto-binding [%autowidth,%noheader,stripes=even] |==== -| | Operator | API Version | Kind -| `postgresql` | link:https://operatorhub.io/operator/postgresql[CrunchyData Postgres] | postgres-operator.crunchydata.com/v1beta1 | PostgresCluster -| `mysql` | link:https://operatorhub.io/operator/percona-xtradb-cluster-operator[Percona XtraDB Cluster] | pxc.percona.com/v1-9-0 | PerconaXtraDBCluster -| `mongo` | link:https://operatorhub.io/operator/percona-server-mongodb-operator[Percona Mongo] | psmdb.percona.com/v1-9-0 | PerconaServerMongoDB +| | Operator | API Version | Kind +| `postgresql` | link:https://operatorhub.io/operator/postgresql[CrunchyData Postgres] | postgres-operator.crunchydata.com/v1beta1 | PostgresCluster +| `mysql` | link:https://operatorhub.io/operator/percona-xtradb-cluster-operator[Percona XtraDB Cluster] | pxc.percona.com/v1-9-0 | PerconaXtraDBCluster +| `mongo` | link:https://operatorhub.io/operator/percona-server-mongodb-operator[Percona Mongo] | psmdb.percona.com/v1-9-0 | PerconaServerMongoDB |==== @@ -1730,7 +1732,7 @@ The following example shows that for a named datasource, the datasource name is quarkus.datasource.fruits-db.db-kind=postgresql ---- -This has the same effect as the following configuration: +This has the same effect as the following configuration: [source,properties] ---- diff --git a/_versions/main/guides/deploying-to-openshift.adoc b/_versions/main/guides/deploying-to-openshift.adoc index 266464c1b2..54f30d4c9b 100644 --- a/_versions/main/guides/deploying-to-openshift.adoc +++ b/_versions/main/guides/deploying-to-openshift.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud, native :summary: This guide covers how to deploy a native application on OpenShift. +:topics: devops,kubernetes,openshift,cloud,deployment +:extensions: io.quarkus:quarkus-openshift This guide covers generating and deploying OpenShift resources based on sane default and user supplied configuration. diff --git a/_versions/main/guides/dev-mode-differences.adoc b/_versions/main/guides/dev-mode-differences.adoc index ddb7cc1cd6..ceb8c94b7f 100644 --- a/_versions/main/guides/dev-mode-differences.adoc +++ b/_versions/main/guides/dev-mode-differences.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: architecture :summary: How dev mode differs from a production application +:topics: internals,devmode +:extensions: io.quarkus:quarkus-core This document explains how the dev mode in Quarkus differs from a production application. diff --git a/_versions/main/guides/dev-services.adoc b/_versions/main/guides/dev-services.adoc index a2f76497e2..6e8517de9f 100644 --- a/_versions/main/guides/dev-services.adoc +++ b/_versions/main/guides/dev-services.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: core :summary: A list of all extensions that support Dev Services and their configuration options. +:topics: devservices,tooling,testing,devmode Quarkus supports the automatic provisioning of unconfigured services in development and test mode. We refer to this capability as Dev Services. From a developer's perspective this means that if you include an extension and don't configure it then @@ -77,7 +78,7 @@ include::{generated-dir}/config/quarkus-keycloak-devservices-keycloak-keycloak-b == Kubernetes -The Kubernetes Dev Service will be enabled when `kubernetes-client` extension is present in your application, and +The Kubernetes Dev Service will be enabled when `kubernetes-client` extension is present in your application, and the API server address has not been explicitly configured. More information can be found in the xref:kubernetes-dev-services.adoc[Kubernetes Dev Services Guide]. diff --git a/_versions/main/guides/dev-ui-v2.adoc b/_versions/main/guides/dev-ui-v2.adoc deleted file mode 100644 index 44f978939d..0000000000 --- a/_versions/main/guides/dev-ui-v2.adoc +++ /dev/null @@ -1,1240 +0,0 @@ -//// -This guide is maintained in the main Quarkus repository -and pull requests should be submitted there: -https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc -//// -= Dev UI -include::_attributes.adoc[] -:categories: writing-extensions -:summary: Learn how to get your extension to contribute features to the Dev UI (v2). - -[NOTE] -.Dev UI v2 -==== -This guide covers the Dev UI v2, which is the default from Quarkus 3 onwards. Read xref:dev-ui.adoc[Dev UI v1] for Quarkus 2.x. -==== - -This guide covers the Quarkus Dev UI for xref:building-my-first-extension.adoc[extension authors]. - -Quarkus ships with a Developer UI, which is available in dev mode (when you start -quarkus with `mvn quarkus:dev`) at http://localhost:8080/q/dev-ui[/q/dev-ui] by default. It will show you something like -this: - -image::dev-ui-overview-v2.png[alt=Dev UI overview,role="center"] - -It allows you to: - -- quickly visualize all the extensions currently loaded -- view extension statuses and go directly to extension documentation -- view and change `Configuration` -- manage and visualize `Continuous Testing` -- view `Dev Services` information -- view the Build information -- view and stream various logs - -Each extension used in the application will be listed and you can navigate to the guide for each extension, see some more information on the extension, and view configuration applicable for that extension: - -image::dev-ui-extension-card-v2.png[alt=Dev UI extension card,role="center"] - -== Make my extension extend the Dev UI - -In order to make your extension listed in the Dev UI you don't need to do anything! - -So you can always start with that :) - -Extensions can: - -- xref:add-links-to-an-extension-card[Add links to an extension card] -- xref:add-full-pages[Add full custom pages] -- xref:add-a-log-file[Add a log stream] -- xref:add-a-section-menu[Add a section menu] -- xref:custom-cards[Create a custom card] - -== Add links to an extension card - -=== External Links - -These are links that reference other (external from Dev UI) data. This data can be HTML pages, text or other data. - -A good example of this is the SmallRye OpenAPI extension that contains links to the generated openapi schema in both json and yaml format, and a link to Swagger UI: - -image::dev-ui-extension-openapi-v2.png[alt=Dev UI extension card,role="center"] - -The links to these external references is known at build time, so to get links like this on your card, all you need to do is add the following Build Step in your extension: - -[source,java] ----- -@BuildStep(onlyIf = IsDevelopment.class)// <1> -public CardPageBuildItem pages(NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem) { - - CardPageBuildItem cardPageBuildItem = new CardPageBuildItem(); // <2> - - cardPageBuildItem.addPage(Page.externalPageBuilder("Schema yaml") // <3> - .url(nonApplicationRootPathBuildItem.resolvePath("openapi")) // <4> - .isYamlContent() // <5> - .icon("font-awesome-solid:file-lines")); // <6> - - cardPageBuildItem.addPage(Page.externalPageBuilder("Schema json") - .url(nonApplicationRootPathBuildItem.resolvePath("openapi") + "?format=json") - .isJsonContent() - .icon("font-awesome-solid:file-code")); - - cardPageBuildItem.addPage(Page.externalPageBuilder("Swagger UI") - .url(nonApplicationRootPathBuildItem.resolvePath("swagger-ui")) - .isHtmlContent() - .icon("font-awesome-solid:signs-post")); - - return cardPageBuildItem; -} ----- -<1> Always make sure that this build step is only run when in dev mode -<2> To add anything on the card, you need to return/produce a `CardPageBuildItem`. -<3> To add a link, you can use the `addPage` method, as all links go to a "page". `Page` has some builders to assist with building a page. For `external` links, use the `externalPageBuilder` -<4> Adding the url of the external link (in this case we use `NonApplicationRootPathBuildItem` to create this link, as this link is under the configurable non application path, default `/q`). Always use `NonApplicationRootPathBuildItem` if your link is available under `/q`. -<5> You can (optionally) hint the content type of the content you are navigating to. If there is no hint, a header call will be made to determine the `MediaType`; -<6> You can add an icon. All free font-awesome icons are available. - -[NOTE] -.Note about icons - -If you find your icon at https://fontawesome.com/search?o=r&m=free[Font awesome], you can map as follow: Example `` will map to `font-awesome-solid:house`, so `fa` becomes `font-awesome` and for the icon name, remove the `fa-`; - -==== Embedding external content - -By default, even external links will render inside (embedded) in Dev UI. In the case of HTML, the page will be rendered and any other content will be shown using https://codemirror.net/[code-mirror] to markup the media type. For example the open api schema document in `yaml` format: - -image::dev-ui-extension-openapi-embed-v2.png[alt=Dev UI embedded page,role="center"] - -If you do not want to embed the content, you can use the `.doNotEmbed()` on the Page Builder, this will then open the link in a new tab. - -==== Runtime external links - -The example above assumes you know the link to use at build time. There might be cases where you only know this at runtime. In that case you can use a xref:JsonRPC[JsonRPC] Method that returns the link to add, and use that when creating the link. Rather than using the `.url` method on the page builder, use the `.dynamicUrlJsonRPCMethodName("yourJsonRPCMethodName")`. - -==== Adding labels - -You can add an option label to the link in the card using one of the builder methods on the page builder. These labels can be - -- static (known at build time) `.staticLabel("staticLabelValue")` -- dynamic (loaded at runtime) `.dynamicLabelJsonRPCMethodName("yourJsonRPCMethodName")` -- streaming (continuously streaming updated values at runtime) `.streamingLabelJsonRPCMethodName("yourJsonRPCMethodName")` - -For dynamic and streaming labels, see the xref:JsonRPC[JsonRPC] Section. - -image::dev-ui-extension-card-label-v2.png[alt=Dev UI card labels,role="center"] - -== Add full pages - -You can also link to an "internal" page (as opposed to the above "external" page). This means that you can build the page and add data and actions for rendering in Dev UI. - -=== Build time data - -To make build time data available in your full page, you can add any data to your `CardPageBuildItem` with a key and a value: - -[source,java] ----- -CardPageBuildItem pageBuildItem = new CardPageBuildItem(); -pageBuildItem.addBuildTimeData("someKey", getSomeValueObject()); ----- - -You can add multiple of these key-value pairs for all the data you know at build time that you need on the page. - -There are a few options to add full page content in Dev UI. Starting from the most basic (good start) to a full blown web-component (preferred). - -=== Display some build time data on a screen (without having to do frontend coding): - -If you have some data that is known at build time that you want to display you can use one of the following builders in `Page`: - -- xref:raw-data[Raw data] -- xref:table-data[Table data] -- xref:qute-data[Qute data] -- xref:web-component-page[Web Component page] - -==== Raw data -This will display your data in it's raw (serialised) json value: - -[source,java] ----- -cardPageBuildItem.addPage(Page.rawDataPageBuilder("Raw data") // <1> - .icon("font-awesome-brands:js") - .buildTimeDataKey("someKey")); // <2> ----- -<1> Use the `rawDataPageBuilder`. -<2> Link back to the key used when you added the build time data in `addBuildTimeData` on the Page BuildItem. - -That will create a link to a page that renders the raw data in json: - -image::dev-ui-raw-page-v2.png[alt=Dev UI raw page,role="center"] - -==== Table data - -You can also display your Build time data in a table if the structure allows it: - -[source,java] ----- -cardPageBuildItem.addPage(Page.tableDataPageBuilder("Table data") // <1> - .icon("font-awesome-solid:table") - .showColumn("timestamp") // <2> - .showColumn("user") // <2> - .showColumn("fullJoke") // <2> - .buildTimeDataKey("someKey")); // <3> ----- -<1> Use the `tableDataPageBuilder`. -<2> Optionally only show certain fields. -<3> Link back to the key used when you added the build time data in `addBuildTimeData` on the Page BuildItem. - -That will create a link to a page that renders the data in a table: - -image::dev-ui-table-page-v2.png[alt=Dev UI table page,role="center"] - -==== Qute data - -You can also display your build time data using a qute template. All build time data keys are available to use in the template: - -[source,java] ----- -cardPageBuildItem.addPage(Page.quteDataPageBuilder("Qute data") // <1> - .icon("font-awesome-solid:q") - .templateLink("qute-jokes-template.html")); // <2> ----- -<1> Use the `quteDataPageBuilder`. -<2> Link to the Qute template in `/deployment/src/main/resources/dev-ui/`. - -Using any Qute template to display the data, for example `qute-jokes-template.html`: - -[source,html] ----- - - - - - - - - - - {#for joke in jokes} // <1> - - - - - - {/for} - -
TimestampUserJoke
{joke.timestamp} {joke.user}{joke.fullJoke}
----- -<1> `jokes` added as a build time data key on the Page Build Item. - -==== Web Component page - -To build an interactive page with actions and runtime (or build time) data, you need to use the web component page: - -[source,java] ----- -cardPageBuildItem.addPage(Page.webComponentPageBuilder() // <1> - .icon("font-awesome-solid:egg") - .componentLink("qwc-arc-beans.js") // <2> - .staticLabel(String.valueOf(beans.size()))); ----- -<1> Use the `webComponentPageBuilder`. -<2> Link to the Web Component in `/deployment/src/main/resources/dev-ui/`. The title can also be defined (using `.title("My title")` in the builder), but if not the title will be assumed from the componentLink, which should always have the format `qwc` (stands for Quarkus Web Component) dash `extensionName` (example, `arc` in this case ) dash `page title` ("Beans" in this case) - -Dev UI uses https://lit.dev/[Lit] to make building these web components easier. You can read more about Web Components and Lit: - -- https://www.webcomponents.org/introduction[Web components Getting started] -- https://lit.dev/docs/[Lit documentation] - -===== Basic structure of a Web component page - -A Web component page is just a JavaScript Class that creates a new HTML Element: - -[source,javascript] ----- -import { LitElement, html, css} from 'lit'; // <1> -import { beans } from 'build-time-data'; // <2> - -/** - * This component shows the Arc Beans - */ -export class QwcArcBeans extends LitElement { // <3> - - static styles = css` // <4> - .annotation { - color: var(--lumo-contrast-50pct); // <5> - } - - .producer { - color: var(--lumo-primary-text-color); - } - `; - - static properties = { - _beans: {state: true}, // <6> - }; - - constructor() { // <7> - super(); - this._beans = beans; - } - - render() { // <8> - if (this._beans) { - return html`
    - ${this._beans.map((bean) => // <9> - html`
  • ${bean.providerType.name}
  • ` - )}
`; - } else { - return html`No beans found`; - } - } -} -customElements.define('qwc-arc-beans', QwcArcBeans); // <10> ----- - -<1> You can import Classes and/or functions from other libraries. -In this case we use the `LitElement` class and `html` & `css` functions from `Lit` -<2> Build time data as defined in the Build step and can be imported using the key and always from `build-time-data`. All keys added in your Build step will be available. -<3> The component should be named in the following format: Qwc (stands for Quarkus Web Component) then Extension Name then Page Title, all concatenated with Camel Case. This will also match the file name format as described earlier. The component should also extend `LitComponent`. -<4> CSS styles can be added using the `css` function, and these styles only apply to your component. -<5> Styles can reference globally defined CSS variables to make sure your page renders correctly, especially when switching between light and dark mode. You can find all CSS variables in the Vaadin documentation (https://vaadin.com/docs/latest/styling/lumo/lumo-style-properties/color[Color], https://vaadin.com/docs/latest/styling/lumo/lumo-style-properties/size-space[Sizing and Spacing], etc) -<6> Properties can be added. Use `_` in front of a property if that property is private. Properties are usually injected in the HTML template, and can be defined as having state, meaning that if that property changes, the component should re-render. In this case, the beans are Build time data and only change on hot-reload, which will be covered later. -<7> Constructors (optional) should always call `super` first, and then set the default values for the properties. -<8> The render method (from `LitElement`) will be called to render the page. In this method you return the markup of the page you want. You can use the `html` function from `Lit`, that gives you a template language to output the HTML you want. Once the template is created, you only need to set/change the properties to re-render the page content. Read more about https://lit.dev/docs/components/rendering/[Lit html] -<9> You can use the built-in template functions to do conditional, list, etc. Read more about https://lit.dev/docs/templates/overview/[Lit Templates] -<10> You always need to register your Web component as a custom element, with a unique tag. Here the tag will follow the same format as the filename (`qwc` dash `extension name` dash `page title` ); - -===== Using Vaadin UI components for rendering - -Dev UI makes extensive usage of https://vaadin.com/docs/latest/components[Vaadin web components] as UI Building blocks. - -As an example, the Arc Beans are rendered using a https://vaadin.com/docs/latest/components/grid[Vaadin Grid]: - -[source,javascript] ----- -import { LitElement, html, css} from 'lit'; -import { beans } from 'build-time-data'; -import '@vaadin/grid'; // <1> -import { columnBodyRenderer } from '@vaadin/grid/lit.js'; // <2> -import '@vaadin/vertical-layout'; -import 'qui-badge'; // <3> - -/** - * This component shows the Arc Beans - */ -export class QwcArcBeans extends LitElement { - - static styles = css` - .arctable { - height: 100%; - padding-bottom: 10px; - } - - code { - font-size: 85%; - } - - .annotation { - color: var(--lumo-contrast-50pct); - } - - .producer { - color: var(--lumo-primary-text-color); - } - `; - - static properties = { - _beans: {state: true}, - }; - - constructor() { - super(); - this._beans = beans; - } - - render() { - if (this._beans) { - - return html` - - - - - - - - - - `; - - } else { - return html`No beans found`; - } - } - - _beanRenderer(bean) { - return html` - @${bean.scope.simpleName} - ${bean.nonDefaultQualifiers.map(qualifier => - html`${this._qualifierRenderer(qualifier)}` - )} - ${bean.providerType.name} - `; - } - - _kindRenderer(bean) { - return html` - - ${this._kindBadgeRenderer(bean)} - ${this._kindClassRenderer(bean)} - - `; - } - - _kindBadgeRenderer(bean){ - let kind = this._camelize(bean.kind); - let level = null; - - if(bean.kind.toLowerCase() === "field"){ - kind = "Producer field"; - level = "success"; - }else if(bean.kind.toLowerCase() === "method"){ - kind = "Producer method"; - level = "success"; - }else if(bean.kind.toLowerCase() === "synthetic"){ - level = "contrast"; - } - - return html` - ${level - ? html`${kind}` - : html`${kind}` - }`; - } - - _kindClassRenderer(bean){ - return html` - ${bean.declaringClass - ? html`${bean.declaringClass.simpleName}.${bean.memberName}()` - : html`${bean.memberName}` - } - `; - } - - _interceptorsRenderer(bean) { - if (bean.interceptors && bean.interceptors.length > 0) { - return html` - ${bean.interceptorInfos.map(interceptor => - html`
- ${interceptor.interceptorClass.name} - ${interceptor.priority} -
` - )} -
`; - } - } - - _qualifierRenderer(qualifier) { - return html`${qualifier.simpleName}`; - } - - _camelize(str) { - return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function (match, index) { - if (+match === 0) - return ""; - return index === 0 ? match.toUpperCase() : match.toLowerCase(); - }); - } -} -customElements.define('qwc-arc-beans', QwcArcBeans); ----- -<1> Import the Vaadin component you want to use -<2> You can also import other functions if needed -<3> There are some internal UI components that you can use, described below - -===== Using internal UI components - -Some https://github.com/quarkusio/quarkus/tree/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qui[internal UI components] (under the `qui` namespace) are available to make certain things easier: - -- Card -- Badge -- Alert -- Code block -- IDE Link - -====== Card - -Card component to display contents in a card - -[source,javascript] ----- -import 'qui-card'; ----- - -[source,html] ----- - -
- My contents -
-
----- - -https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/resources/dev-ui/qwc-jokes-vaadin.js#L110[Example code] - -====== Badge - -Badge UI Component based on the https://vaadin.com/docs/latest/components/badge[vaadin themed] badge - -image::dev-ui-qui-badge-v2.png[alt=Dev UI Badge,role="center"] - -[source,javascript] ----- -import 'qui-badge'; ----- - -You can use any combination of small, primary, pill, with icon and clickable with any level of `default`, `success`, `warning`, `error`, `contrast` or set your own colors. - -[source,html] ----- -
-

Badges

-

Badges wrap the Vaadin theme in a component. - See https://vaadin.com/docs/latest/components/badge for more info. -

-
- -
-
- Default - Success - Warning - Error - Contrast - Custom colours -
-
-
- -
-
- Default primary - Success primary - Warning primary - Error primary - Contrast primary - Custom colours -
-
-
- -
-
- Default pill - Success pill - Warning pill - Error pill - Contrast pill - Custom colours -
-
-
- -
-
- - Default icon - - - Success icon - - - Warning icon - - - Error icon - - - Contrast icon - - - Custom colours - -
-
-
- -
-
- - - - - - -
-
-
- -
-
- this._info()}>Default - this._success()}>Success - this._warning()}>Warning - this._error()}>Error - this._contrast()}>Contrast - this._info()}>Custom colours -
-
-
-
-
----- - -https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/resources/dev-ui/qwc-jokes-vaadin.js#L214[Example code] - -====== Alert - -Alerts are modeled around the Bootstrap alerts. Click https://getbootstrap.com/docs/4.0/components/alerts[here] for more info. - -Also see Notification controller below as an alternative. - -image::dev-ui-qui-alert-v2.png[alt=Dev UI Alert,role="center"] - -[source,javascript] ----- -import 'qui-alert'; ----- - -[source,html] ----- -
-
- Info alert - Success alert - Warning alert - Error alert -
- Permanent Info alert - Permanent Success alert - Permanent Warning alert - Permanent Error alert -
- Center Info alert - Center Success alert - Center Warning alert - Center Error alert -
- Info alert with icon - Success alert with icon - Warning alert with icon - Error alert with icon -
- Info alert with custom icon - Success alert with custom icon - Warning alert with custom icon - Error alert with custom icon -
- Small Info alert with icon - Small Success alert with icon - Small Warning alert with icon - Small Error alert with icon -
- Info alert with markup
quarkus.io
- Success alert with markup
quarkus.io
- Warning alert with markup
quarkus.io
- Error alert with markup
quarkus.io
-
- Primary Info alert with icon - Primary Success alert with icon - Primary Warning alert with icon - Primary Error alert with icon -
- Info alert with title - Success alert with title - Warning alert with title - Error alert with title -
- Info alert with title and icon - Success alert with title and icon - Warning alert with title and icon - Error alert with title and icon -
-
----- - -https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/resources/dev-ui/qwc-jokes-vaadin.js#L316[Example code] - - -====== Code block - -Display a code block. This component is aware of the theme and will use the correct codemirror theme to match the light/dark mode. - - -image::dev-ui-qui-code-block-v2.png[alt=Dev UI Code Block,role="center"] - -[source,javascript] ----- -import 'qui-code-block'; ----- - -[source,html] ----- -
- - -
; ----- - -https://github.com/quarkusio/quarkus/blob/e03a97845738436c69443a591ec4ce88ed04ac91/extensions/kubernetes/vanilla/deployment/src/main/resources/dev-ui/qwc-kubernetes-manifest.js#L99[Example code] - -or fetching the contents from a URL: - -[source,html] ----- -
- - -
----- - -https://github.com/quarkusio/quarkus/blob/95c54fa46a6b6f31d69477234486d9359a2a3a4a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-external-page.js#L116[Example code] - -====== IDE link - -Creates a link to a resource (like a Java source file) that can be opened in the user's IDE (if we could detect the IDE). - -[source,javascript] ----- -import 'qui-ide-link'; ----- - -[source,html] ----- -[${sourceClassNameFull}]; ----- - -https://github.com/quarkusio/quarkus/blob/582f1f78806d2268885faea7aa8f5a4d2b3f5b98/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-server-log.js#L315[Example code] - -===== Using internal controllers - -Some https://github.com/quarkusio/quarkus/tree/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller[internal controllers] are available to make certain things easier: - -- Notifier -- Storage -- Log -- Router -- JsonRPC - -====== Notifier - -This is an easy way to show a toast message. The toast can be placed on the screen (default left bottom) and can have a level (Info, Success, Warning, Error). Any of the levels can also be primary, that will create a more prominent toast message. - -See the source of this controller https://github.com/quarkusio/quarkus/blob/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/notifier.js[here]. - -Example usage: - -image::dev-ui-controller-notifier.gif[alt=Dev UI Notifier,role="center"] - -[source,javascript] ----- -import { notifier } from 'notifier'; ----- - -[source,html] ----- - this._info()}>Info; ----- - -[source,javascript] ----- -_info(position = null){ - notifier.showInfoMessage("This is an information message", position); -} ----- - -You can find all the valid positions https://vaadin.com/docs/latest/components/notification/#position[here]. - -https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/resources/dev-ui/qwc-jokes-vaadin.js#L374[Example code] - -====== Storage - -An easy way to access the local storage in a safe way. This will store values in the local storage, scoped to your extension. This way you do not have to worry that you might clash with another extension. - -Local storage is useful to remember user preferences or state. For example, the footer remembers the state (open/close) and the size when open of the bottom drawer. - -[source,javascript] ----- -import { StorageController } from 'storage-controller'; - -// ... - -storageControl = new StorageController(this); // Passing in this will scope the storage to your extension - -// ... - -const storedHeight = this.storageControl.get("height"); // Get some value - -// ... - -this.storageControl.set('height', 123); // Set some val ----- - -https://github.com/quarkusio/quarkus/blob/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-footer.js[Example code] - - -====== Log - -The log controller is used to add control buttons to a (footer) log. -See <>. - -image::dev-ui-log-control-v2.png[alt=Dev UI Log control,role="center"] - -[source,javascript] ----- -import { LogController } from 'log-controller'; - -// ... - -logControl = new LogController(this); // Passing in this will scope the control to your extension - -// ... -this.logControl - .addToggle("On/off switch", true, (e) => { - this._toggleOnOffClicked(e); - }).addItem("Log levels", "font-awesome-solid:layer-group", "var(--lumo-tertiary-text-color)", (e) => { - this._logLevels(); - }).addItem("Columns", "font-awesome-solid:table-columns", "var(--lumo-tertiary-text-color)", (e) => { - this._columns(); - }).addItem("Zoom out", "font-awesome-solid:magnifying-glass-minus", "var(--lumo-tertiary-text-color)", (e) => { - this._zoomOut(); - }).addItem("Zoom in", "font-awesome-solid:magnifying-glass-plus", "var(--lumo-tertiary-text-color)", (e) => { - this._zoomIn(); - }).addItem("Clear", "font-awesome-solid:trash-can", "var(--lumo-error-color)", (e) => { - this._clearLog(); - }).addFollow("Follow log", true , (e) => { - this._toggleFollowLog(e); - }).done(); ----- - -https://github.com/quarkusio/quarkus/blob/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-server-log.js[Example code] - -====== Router - -The router is mostly used internally. This uses https://github.com/vaadin/router[Vaadin Router] under the covers to route URLs to the correct page/section within the SPA. It will update the navigation and allow history (back button). This also creates the sub-menu available on extensions that have multiple pages. - -See the https://github.com/quarkusio/quarkus/blob/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/router-controller.js[controller] for some methods that might be useful. - -[#JsonRPC] -====== JsonRPC - -This controller allows you to fetch or stream runtime data. (vs. <> discussed earlier). There are two parts to getting data during runtime. The Java side in the runtime module, and then the usage in the web component. - -*Java part* - -This code is responsible for making data available to display on the UI. - -You need to register the JsonPRCService in your processor in the deployment module: - -[source,java] ----- -@BuildStep(onlyIf = IsDevelopment.class)// <1> -JsonRPCProvidersBuildItem createJsonRPCServiceForCache() {// <2> - return new JsonRPCProvidersBuildItem(CacheJsonRPCService.class);// <3> -} ----- -<1> Always only do this in Dev Mode -<2> Produce / return a `JsonRPCProvidersBuildItem` -<3> Define the class in your runtime module that will contain methods that make data available in the UI - -https://github.com/quarkusio/quarkus/blob/main/extensions/cache/deployment/src/main/java/io/quarkus/cache/deployment/devui/CacheDevUiProcessor.java[Example code] - -Now, in your Runtime module create the JsonRPC Service. This class will default to an application scoped bean, except if you explicitly scope the bean. All public methods that return something will be made available to call from the Web component Javascript. - -The return object in these methods can be: - -- primitives or `String`, -- `io.vertx.core.json.JsonArray` -- `io.vertx.core.json.JsonObject` -- any other POJO that can be serializable to Json - -All of the above can be blocking (POJO) or non-blocking (`@NonBlocking` or `Uni`). Or alternatively data can be streamed using `Multi`. - -[source,java] ----- -@NonBlocking // <1> -public JsonArray getAll() { // <2> - Collection names = manager.getCacheNames(); - List allCaches = new ArrayList<>(names.size()); - for (String name : names) { - Optional cache = manager.getCache(name); - if (cache.isPresent() && cache.get() instanceof CaffeineCache) { - allCaches.add((CaffeineCache) cache.get()); - } - } - allCaches.sort(Comparator.comparing(CaffeineCache::getName)); - - var array = new JsonArray(); - for (CaffeineCache cc : allCaches) { - array.add(getJsonRepresentationForCache(cc)); - } - return array; -} ----- -<1> This example runs non blocking. We could also return `Uni` -<2> The method name `getAll` will be available in the Javascript - -https://github.com/quarkusio/quarkus/blob/main/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/devconsole/CacheJsonRPCService.java[Example code] - -*Webcomponent (Javascript) part* - -Now you can use the JsonRPC controller to access the `getAll` method (and any other methods in you JsonRPC Service) - -[source,javascript] ----- -import { JsonRpc } from 'jsonrpc'; - -// ... - -jsonRpc = new JsonRpc(this); // Passing in this will scope the rpc calls to your extension - -// ... - -/** - * Called when displayed - */ -connectedCallback() { - super.connectedCallback(); - this.jsonRpc.getAll().then(jsonRpcResponse => { // <1> - this._caches = new Map(); - jsonRpcResponse.result.forEach(c => { //<2> - this._caches.set(c.name, c); - }); - }); -} ----- - -<1> Note the method `getAll` corresponds to the method in your Java Service. This method returns a https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise[Promise] with the JsonRPC result. -<2> In this case the result is an array, so we can loop over it. - -JsonArray (or any Java collection) in either blocking or non-blocking will return an array, else a JsonObject will be returned. - -https://github.com/quarkusio/quarkus/blob/main/extensions/cache/deployment/src/main/resources/dev-ui/qwc-cache-caches.js[Example code] - -You can also pass in parameters in the method being called, for example: -(In the Runtime Java code) - -[source,java] ----- -public Uni clear(String name) { //<1> - Optional cache = manager.getCache(name); - if (cache.isPresent()) { - return cache.get().invalidateAll().map((t) -> getJsonRepresentationForCache(cache.get())); - } else { - return Uni.createFrom().item(new JsonObject().put("name", name).put("size", -1)); - } -} ----- -<1> the clear method takes one parameter called `name` - -In the Webcomponent (Javascript): - -[source,javascript] ----- -_clear(name) { - this.jsonRpc.clear({name: name}).then(jsonRpcResponse => { //<1> - this._updateCache(jsonRpcResponse.result) - }); -} ----- -<1> the `name` parameter is passed in. - -====== Streaming data - -You can keep a UI screen updated with the latest data by continuously streaming data to the screen. This can be done with `Multi` (Java side) and `Observer` (Javascript side) - -Java side of streaming data: - -[source,java] ----- -public class JokesJsonRPCService { - - private final BroadcastProcessor jokeStream = BroadcastProcessor.create(); - - @PostConstruct - void init() { - Multi.createFrom().ticks().every(Duration.ofHours(4)).subscribe().with((item) -> { - jokeStream.onNext(getJoke()); - }); - } - - public Multi streamJokes() { // <1> - return jokeStream; - } - - // ... -} ----- -<1> Return the Multi that will stream jokes - -https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/runtime/src/main/java/io/quarkus/jokes/runtime/JokesJsonRPCService.java#L37[Example code] - -Javascript side of streaming data: - -[source,javascript] ----- -this._observer = this.jsonRpc.streamJokes().onNext(jsonRpcResponse => { //<1> - this._addToJokes(jsonRpcResponse.result); - this._numberOfJokes = this._numberOfJokes++; -}); - -// ... - -this._observer.cancel(); //<2> ----- -<1> You can call the method (optionally passing in parameters) and then provide the code that will be called on the next event. -<2> Make sure to keep an instance of the observer to cancel later if needed. - -https://github.com/phillip-kruger/quarkus-jokes/blob/main/deployment/src/main/resources/dev-ui/qwc-jokes-web-components.js[Example code] - -====== Dev UI Log - -When running a local application using the `999-SNAPSHOT` version, the Dev UI will show a `Dev UI` Log in the footer. This is useful to debug all JSON RPC messages flowing between the browser and the Quarkus app. - -image::dev-ui-jsonrpc-log-v2.png[alt=Dev UI Json RPC Log,role="center"] - -== Hot reload - -You can update a screen automatically when a Hot reload has happened. To do this replace the `LitElement` that your Webcomponent extends with `QwcHotReloadElement`. - -`QwcHotReloadElement` extends `LitElement` so your component is still a Lit Element. - -When extending a `QwcHotReloadElement` you have to provide the `hotReload` method. (You also still need to provide the `render` method from Lit) - -[source,javascript] ----- -import { QwcHotReloadElement, html, css} from 'qwc-hot-reload-element'; - -// ... - -export class QwcMyExtensionPage extends QwcHotReloadElement { - - render(){ - // ... - } - - hotReload(){ - // .. - } - -} ----- - -== Custom cards - -You can customize the card that is being displayed on the extension page if you do not want to use the default built-in card. - -To do this, you need to provide a Webcomponent that will be loaded in the place of the provided card and register this in the Java Processor: - -[source,java] ----- -cardPageBuildItem.setCustomCard("qwc-mycustom-card.js"); ----- - -On the Javascript side, you have access to all the pages (in case you want to create links) - -[source,javascript] ----- -import { pages } from 'build-time-data'; ----- - -And the following properties will be passed in: - -- extensionName -- description -- guide -- namespace - -[source,javascript] ----- -static properties = { - extensionName: {type: String}, - description: {type: String}, - guide: {type: String}, - namespace: {type: String} -} ----- - -== State (Advance) - -State allows properties to contain state and can be reused globally. An example of state properties are the theme, the connection state (if we are connected to the backend), etc. - -See the https://github.com/quarkusio/quarkus/tree/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/state[current built-in] state objects. - -The state in Dev UI uses https://github.com/gitaarik/lit-state[LitState] and you can read more about it in their https://gitaarik.github.io/lit-state/build/[documentation]. - - -== Add a log file - -Apart from adding a card and a page, extensions can add a log to the footer. This is useful to log things happening continuously. A page will lose connection to the backend when navigating away from that page, a log in the footer is permanently connected. - -Adding something to the footer works exactly like adding a Card, except you use a `FooterPageBuildItem` rather than a `CardPageBuildItem`. - -[source,java] ----- -FooterPageBuildItem footerPageBuildItem = new FooterPageBuildItem(); - -footerPageBuildItem.addPage(Page.webComponentPageBuilder() - .icon("font-awesome-regular:face-grin-tongue-wink") - .title("Joke Log") - .componentLink("qwc-jokes-log.js")); - -footerProducer.produce(footerPageBuildItem); ----- - -https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/java/io/quarkus/jokes/deployment/devui/JokesDevUIProcessor.java#L87[Example code] - -In your Webcomponent you can then stream the log to the UI: - -[source,javascript] ----- -export class QwcJokesLog extends LitElement { - jsonRpc = new JsonRpc(this); - logControl = new LogController(this); - - // .... -} ----- - -https://github.com/phillip-kruger/quarkus-jokes/blob/main/deployment/src/main/resources/dev-ui/qwc-jokes-log.js[Example code] - -== Add a section menu - -This allows an extension to link a page directly in the section Menu. - -Adding something to the section menu works exactly like adding a Card, except you use a `MenuPageBuildItem` rather than a `CardPageBuildItem`. - -[source,java] ----- -MenuPageBuildItem menuPageBuildItem = new MenuPageBuildItem(); - -menuPageBuildItem.addPage(Page.webComponentPageBuilder() - .icon("font-awesome-regular:face-grin-tongue-wink") - .title("One Joke") - .componentLink("qwc-jokes-menu.js")); - -menuProducer.produce(menuPageBuildItem); ----- - -https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/java/io/quarkus/jokes/deployment/devui/JokesDevUIProcessor.java#LL71C16-L71C16[Example code] - -Your page can be any Page similar to Cards. - -== Testing - -You can add tests to your extension that test: - -- Build time data -- Runtime data via JsonRPC - -You need to add this to your pom: - -[source,xml] ----- - - io.quarkus - quarkus-vertx-http-dev-ui-tests - test - ----- - -This will give you access to two base classes for creating these tests. - -=== Testing Build time data - -If you added Build time data, for example: - -[source,java] ----- -cardPageBuildItem.addBuildTimeData("somekey", somevalue); ----- - -To test that your build time data is generated correctly you can add a test that extends `DevUIBuildTimeDataTest`. - -[source,java] ----- -public class SomeTest extends DevUIBuildTimeDataTest { - - @RegisterExtension - static final QuarkusDevModeTest config = new QuarkusDevModeTest().withEmptyApplication(); - - public SomeTest() { - super("io.quarkus.my-extension"); - } - - @Test - public void testSomekey() throws Exception { - JsonNode somekeyResponse = super.getBuildTimeData("somekey"); - Assertions.assertNotNull(somekeyResponse); - - // Check more values on somekeyResponse - } - -} ----- - -=== Testing Runtime data - -If you added a JsonRPC Service with runtime data responses, for example: - -[source,java] ----- -public boolean updateProperties(String content, String type) { - // ... -} ----- - -To test that `updateProperties` execute correctly via JsonRPC you can add a test that extends `DevUIJsonRPCTest`. - -[source,java] ----- -public class SomeTest extends DevUIJsonRPCTest { - - @RegisterExtension - static final QuarkusDevModeTest config = new QuarkusDevModeTest().withEmptyApplication(); - - public SomeTest() { - super("io.quarkus.my-extension"); - } - - @Test - public void testUpdateProperties() throws Exception { - - JsonNode updatePropertyResponse = super.executeJsonRPCMethod("updateProperty", - Map.of( - "name", "quarkus.application.name", - "value", "changedByTest")); - Assertions.assertTrue(updatePropertyResponse.asBoolean()); - - // Get the properties to make sure it is changed - JsonNode allPropertiesResponse = super.executeJsonRPCMethod("getAllValues"); - String applicationName = allPropertiesResponse.get("quarkus.application.name").asText(); - Assertions.assertEquals("changedByTest", applicationName); - } -} ----- diff --git a/_versions/main/guides/dev-ui.adoc b/_versions/main/guides/dev-ui.adoc index bdc51abba6..bd1f4088be 100644 --- a/_versions/main/guides/dev-ui.adoc +++ b/_versions/main/guides/dev-ui.adoc @@ -6,405 +6,1237 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Dev UI include::_attributes.adoc[] :categories: writing-extensions -:summary: Learn how to get your extension contribute features to the Dev UI (v1). +:summary: Learn how to get your extension to contribute features to the Dev UI (v2). +:topics: dev-ui,tooling,testing +:extensions: io.quarkus:quarkus-core [NOTE] -.Dev UI v1 +.Dev UI v2 ==== -This guide covers the Dev UI v1, which has been replaced in Quarkus 3 with xref:dev-ui-v2.adoc[a new Dev UI]. -You can still access the Dev UI v1 using http://localhost:8080/q/dev-v1[/q/dev-v1] +This guide covers the Dev UI v2, which is the default from Quarkus 3 onwards. ==== This guide covers the Quarkus Dev UI for xref:building-my-first-extension.adoc[extension authors]. -Quarkus ships with a new experimental Dev UI, which is available in dev mode (when you start -quarkus with `mvn quarkus:dev`) at http://localhost:8080/q/dev-v1[/q/dev-v1] by default. It will show you something like +Quarkus ships with a Developer UI, which is available in dev mode (when you start +quarkus with `mvn quarkus:dev`) at http://localhost:8080/q/dev-ui[/q/dev-ui] by default. It will show you something like this: -image::dev-ui-overview.png[alt=Dev UI overview,role="center",width=90%] +image::dev-ui-overview-v2.png[alt=Dev UI overview,role="center"] -It allows you to quickly visualize all the extensions currently loaded, see their status and go directly -to their documentation. +It allows you to: -On top of that, each extension can add: +- quickly visualize all the extensions currently loaded +- view extension statuses and go directly to extension documentation +- view and change `Configuration` +- manage and visualize `Continuous Testing` +- view `Dev Services` information +- view the Build information +- view and stream various logs -- xref:how-can-i-make-my-extension-support-the-dev-ui[Custom useful bits of runtime information in the overview] -- xref:adding-full-pages[Full custom pages] -- xref:advanced-usage-adding-actions[Interactive pages with actions] +Each extension used in the application will be listed and you can navigate to the guide for each extension, see some more information on the extension, and view configuration applicable for that extension: -== How can I make my extension support the Dev UI? +image::dev-ui-extension-card-v2.png[alt=Dev UI extension card,role="center"] + +== Make my extension extend the Dev UI In order to make your extension listed in the Dev UI you don't need to do anything! So you can always start with that :) -If you want to contribute badges or links in your extension card on the Dev UI overview -page, like this: +Extensions can: -image:dev-ui-embedded.png[alt=Dev UI embedded,role="center"] +- xref:add-links-to-an-extension-card[Add links to an extension card] +- xref:add-full-pages[Add full custom pages] +- xref:add-a-log-file[Add a log stream] +- xref:add-a-section-menu[Add a section menu] +- xref:custom-cards[Create a custom card] -You have to add a file named `dev-templates/embedded.html` in your -xref:building-my-first-extension.adoc#description-of-a-quarkus-extension[`deployment`] -extension module's resources: +== Add links to an extension card -image::dev-ui-embedded-file.png[alt=Dev UI embedded.html,align=center] +=== External Links -The contents of this file will be included in your extension card, so for example we can place -two links with some styling and icons: +These are links that reference other (external from Dev UI) data. This data can be HTML pages, text or other data. -[source,html] +A good example of this is the SmallRye OpenAPI extension that contains links to the generated openapi schema in both json and yaml format, and a link to Swagger UI: + +image::dev-ui-extension-openapi-v2.png[alt=Dev UI extension card,role="center"] + +The links to these external references is known at build time, so to get links like this on your card, all you need to do is add the following Build Step in your extension: + +[source,java] ---- - - - OpenAPI -
- - - Swagger UI +@BuildStep(onlyIf = IsDevelopment.class)// <1> +public CardPageBuildItem pages(NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem) { + + CardPageBuildItem cardPageBuildItem = new CardPageBuildItem(); // <2> + + cardPageBuildItem.addPage(Page.externalPageBuilder("Schema yaml") // <3> + .url(nonApplicationRootPathBuildItem.resolvePath("openapi")) // <4> + .isYamlContent() // <5> + .icon("font-awesome-solid:file-lines")); // <6> + + cardPageBuildItem.addPage(Page.externalPageBuilder("Schema json") + .url(nonApplicationRootPathBuildItem.resolvePath("openapi") + "?format=json") + .isJsonContent() + .icon("font-awesome-solid:file-code")); + + cardPageBuildItem.addPage(Page.externalPageBuilder("Swagger UI") + .url(nonApplicationRootPathBuildItem.resolvePath("swagger-ui")) + .isHtmlContent() + .icon("font-awesome-solid:signs-post")); + + return cardPageBuildItem; +} ---- +<1> Always make sure that this build step is only run when in dev mode +<2> To add anything on the card, you need to return/produce a `CardPageBuildItem`. +<3> To add a link, you can use the `addPage` method, as all links go to a "page". `Page` has some builders to assist with building a page. For `external` links, use the `externalPageBuilder` +<4> Adding the url of the external link (in this case we use `NonApplicationRootPathBuildItem` to create this link, as this link is under the configurable non application path, default `/q`). Always use `NonApplicationRootPathBuildItem` if your link is available under `/q`. +<5> You can (optionally) hint the content type of the content you are navigating to. If there is no hint, a header call will be made to determine the `MediaType`; +<6> You can add an icon. All free font-awesome icons are available. + +[NOTE] +.Note about icons + +If you find your icon at https://fontawesome.com/search?o=r&m=free[Font awesome], you can map as follow: Example `` will map to `font-awesome-solid:house`, so `fa` becomes `font-awesome` and for the icon name, remove the `fa-`; + +==== Embedding external content + +By default, even external links will render inside (embedded) in Dev UI. In the case of HTML, the page will be rendered and any other content will be shown using https://codemirror.net/[code-mirror] to markup the media type. For example the open api schema document in `yaml` format: + +image::dev-ui-extension-openapi-embed-v2.png[alt=Dev UI embedded page,role="center"] + +If you do not want to embed the content, you can use the `.doNotEmbed()` on the Page Builder, this will then open the link in a new tab. + +==== Runtime external links + +The example above assumes you know the link to use at build time. There might be cases where you only know this at runtime. In that case you can use a xref:JsonRPC[JsonRPC] Method that returns the link to add, and use that when creating the link. Rather than using the `.url` method on the page builder, use the `.dynamicUrlJsonRPCMethodName("yourJsonRPCMethodName")`. -TIP: We use the Font Awesome Free icon set. +==== Adding labels -Note how the paths are specified: `{config:http-path('quarkus.smallrye-openapi.path')}`. This is a special -directive that the quarkus dev console understands: it will replace that value with the resolved route -named 'quarkus.smallrye-openapi.path'. +You can add an option label to the link in the card using one of the builder methods on the page builder. These labels can be -The corresponding non-application endpoint is declared using `.routeConfigKey` to associate the route with a name: +- static (known at build time) `.staticLabel("staticLabelValue")` +- dynamic (loaded at runtime) `.dynamicLabelJsonRPCMethodName("yourJsonRPCMethodName")` +- streaming (continuously streaming updated values at runtime) `.streamingLabelJsonRPCMethodName("yourJsonRPCMethodName")` + +For dynamic and streaming labels, see the xref:JsonRPC[JsonRPC] Section. + +image::dev-ui-extension-card-label-v2.png[alt=Dev UI card labels,role="center"] + +== Add full pages + +You can also link to an "internal" page (as opposed to the above "external" page). This means that you can build the page and add data and actions for rendering in Dev UI. + +=== Build time data + +To make build time data available in your full page, you can add any data to your `CardPageBuildItem` with a key and a value: [source,java] ---- - nonApplicationRootPathBuildItem.routeBuilder() - .route(openApiConfig.path) // <1> - .routeConfigKey("quarkus.smallrye-openapi.path") // <2> - ... - .build(); +CardPageBuildItem pageBuildItem = new CardPageBuildItem(); +pageBuildItem.addBuildTimeData("someKey", getSomeValueObject()); ---- -<1> The configured path is resolved into a valid route. -<2> The resolved route path is then associated with the key `quarkus.smallrye-openapi.path`. -== Path considerations +You can add multiple of these key-value pairs for all the data you know at build time that you need on the page. -Paths are tricky business. Keep the following in mind: +There are a few options to add full page content in Dev UI. Starting from the most basic (good start) to a full blown web-component (preferred). -* Assume your UI will be nested under the dev endpoint. Do not provide a way to customize this without a strong reason. -* Never construct your own absolute paths. Adding a suffix to a known, normalized and resolved path is fine. +=== Display some build time data on a screen (without having to do frontend coding): -Configured paths, like the `dev` endpoint used by the console or the SmallRye OpenAPI path shown in the example above, -need to be properly resolved against both `quarkus.http.root-path` and `quarkus.http.non-application-root-path`. -Use `NonApplicationRootPathBuildItem` or `HttpRootPathBuildItem` to construct endpoint routes and identify resolved -path values that can then be used in templates. +If you have some data that is known at build time that you want to display you can use one of the following builders in `Page`: -The `{devRootAppend}` variable can also be used in templates to construct URLs for static dev console resources, for example: +- xref:raw-data[Raw data] +- xref:table-data[Table data] +- xref:qute-data[Qute data] +- xref:web-component-page[Web Component page] -[source,html] +==== Raw data +This will display your data in it's raw (serialised) json value: + +[source,java] ---- -Quarkus +cardPageBuildItem.addPage(Page.rawDataPageBuilder("Raw data") // <1> + .icon("font-awesome-brands:js") + .buildTimeDataKey("someKey")); // <2> ---- +<1> Use the `rawDataPageBuilder`. +<2> Link back to the key used when you added the build time data in `addBuildTimeData` on the Page BuildItem. -Refer to the xref:all-config.adoc#quarkus-vertx-http_quarkus.http.non-application-root-path[Quarkus Vertx HTTP configuration reference] -for details on how the non-application root path is configured. +That will create a link to a page that renders the raw data in json: -== Template and styling support +image::dev-ui-raw-page-v2.png[alt=Dev UI raw page,role="center"] -Both the `embedded.html` files and any full page you add in `/dev-templates` will be interpreted by -xref:qute.adoc[the Qute template engine]. +==== Table data -This also means that you can xref:qute-reference.adoc#user_tags[add custom Qute tags] in -`/dev-templates/tags` for your templates to use. +You can also display your Build time data in a table if the structure allows it: -The style system currently in use is https://getbootstrap.com/docs/4.6/getting-started/introduction/[Bootstrap V4 (4.6.0)] -but note that this might change in the future. +[source,java] +---- +cardPageBuildItem.addPage(Page.tableDataPageBuilder("Table data") // <1> + .icon("font-awesome-solid:table") + .showColumn("timestamp") // <2> + .showColumn("user") // <2> + .showColumn("fullJoke") // <2> + .buildTimeDataKey("someKey")); // <3> +---- +<1> Use the `tableDataPageBuilder`. +<2> Optionally only show certain fields. +<3> Link back to the key used when you added the build time data in `addBuildTimeData` on the Page BuildItem. + +That will create a link to a page that renders the data in a table: -The main template also includes https://jquery.com/[jQuery 3.5.1], but here again this might change. +image::dev-ui-table-page-v2.png[alt=Dev UI table page,role="center"] -=== Accessing Config Properties +==== Qute data -A `config:property(name)` expression can be used to output the config value for the given property name. -The property name can be either a string literal or obtained dynamically by another expression. -For example `{config:property('quarkus.lambda.handler')}` and `{config:property(foo.propertyName)}`. +You can also display your build time data using a qute template. All build time data keys are available to use in the template: -Reminder: do not use this to retrieve raw configured path values. As shown above, use `{config:http-path(...)}` with -a known route configuration key when working with resource paths. +[source,java] +---- +cardPageBuildItem.addPage(Page.quteDataPageBuilder("Qute data") // <1> + .icon("font-awesome-solid:q") + .templateLink("qute-jokes-template.html")); // <2> +---- +<1> Use the `quteDataPageBuilder`. +<2> Link to the Qute template in `/deployment/src/main/resources/dev-ui/`. -== Adding full pages +Using any Qute template to display the data, for example `qute-jokes-template.html`: -To add full pages for your Dev UI extension such as this one: +[source,html] +---- + + + + + + + + + + {#for joke in jokes} // <1> + + + + + + {/for} + +
TimestampUserJoke
{joke.timestamp} {joke.user}{joke.fullJoke}
+---- +<1> `jokes` added as a build time data key on the Page Build Item. -image::dev-ui-page.png[alt=Dev UI custom page,align=center,width=90%] +==== Web Component page -You need to place them in your extension's -xref:building-my-first-extension.adoc#description-of-a-quarkus-extension[`deployment`] module's -`/dev-templates` resource folder, like this page for the xref:cache.adoc[`quarkus-cache` extension]: +To build an interactive page with actions and runtime (or build time) data, you need to use the web component page: -[[action-example]] [source,java] ---- -{#include main}// <1> - {#style}// <2> - .custom { - color: gray; +cardPageBuildItem.addPage(Page.webComponentPageBuilder() // <1> + .icon("font-awesome-solid:egg") + .componentLink("qwc-arc-beans.js") // <2> + .staticLabel(String.valueOf(beans.size()))); +---- +<1> Use the `webComponentPageBuilder`. +<2> Link to the Web Component in `/deployment/src/main/resources/dev-ui/`. The title can also be defined (using `.title("My title")` in the builder), but if not the title will be assumed from the componentLink, which should always have the format `qwc` (stands for Quarkus Web Component) dash `extensionName` (example, `arc` in this case ) dash `page title` ("Beans" in this case) + +Dev UI uses https://lit.dev/[Lit] to make building these web components easier. You can read more about Web Components and Lit: + +- https://www.webcomponents.org/introduction[Web components Getting started] +- https://lit.dev/docs/[Lit documentation] + +===== Basic structure of a Web component page + +A Web component page is just a JavaScript Class that creates a new HTML Element: + +[source,javascript] +---- +import { LitElement, html, css} from 'lit'; // <1> +import { beans } from 'build-time-data'; // <2> + +/** + * This component shows the Arc Beans + */ +export class QwcArcBeans extends LitElement { // <3> + + static styles = css` // <4> + .annotation { + color: var(--lumo-contrast-50pct); // <5> + } + + .producer { + color: var(--lumo-primary-text-color); + } + `; + + static properties = { + _beans: {state: true}, // <6> + }; + + constructor() { // <7> + super(); + this._beans = beans; + } + + render() { // <8> + if (this._beans) { + return html`
    + ${this._beans.map((bean) => // <9> + html`
  • ${bean.providerType.name}
  • ` + )}
`; + } else { + return html`No beans found`; + } + } +} +customElements.define('qwc-arc-beans', QwcArcBeans); // <10> +---- + +<1> You can import Classes and/or functions from other libraries. +In this case we use the `LitElement` class and `html` & `css` functions from `Lit` +<2> Build time data as defined in the Build step and can be imported using the key and always from `build-time-data`. All keys added in your Build step will be available. +<3> The component should be named in the following format: Qwc (stands for Quarkus Web Component) then Extension Name then Page Title, all concatenated with Camel Case. This will also match the file name format as described earlier. The component should also extend `LitComponent`. +<4> CSS styles can be added using the `css` function, and these styles only apply to your component. +<5> Styles can reference globally defined CSS variables to make sure your page renders correctly, especially when switching between light and dark mode. You can find all CSS variables in the Vaadin documentation (https://vaadin.com/docs/latest/styling/lumo/lumo-style-properties/color[Color], https://vaadin.com/docs/latest/styling/lumo/lumo-style-properties/size-space[Sizing and Spacing], etc) +<6> Properties can be added. Use `_` in front of a property if that property is private. Properties are usually injected in the HTML template, and can be defined as having state, meaning that if that property changes, the component should re-render. In this case, the beans are Build time data and only change on hot-reload, which will be covered later. +<7> Constructors (optional) should always call `super` first, and then set the default values for the properties. +<8> The render method (from `LitElement`) will be called to render the page. In this method you return the markup of the page you want. You can use the `html` function from `Lit`, that gives you a template language to output the HTML you want. Once the template is created, you only need to set/change the properties to re-render the page content. Read more about https://lit.dev/docs/components/rendering/[Lit html] +<9> You can use the built-in template functions to do conditional, list, etc. Read more about https://lit.dev/docs/templates/overview/[Lit Templates] +<10> You always need to register your Web component as a custom element, with a unique tag. Here the tag will follow the same format as the filename (`qwc` dash `extension name` dash `page title` ); + +===== Using Vaadin UI components for rendering + +Dev UI makes extensive usage of https://vaadin.com/docs/latest/components[Vaadin web components] as UI Building blocks. + +As an example, the Arc Beans are rendered using a https://vaadin.com/docs/latest/components/grid[Vaadin Grid]: + +[source,javascript] +---- +import { LitElement, html, css} from 'lit'; +import { beans } from 'build-time-data'; +import '@vaadin/grid'; // <1> +import { columnBodyRenderer } from '@vaadin/grid/lit.js'; // <2> +import '@vaadin/vertical-layout'; +import 'qui-badge'; // <3> + +/** + * This component shows the Arc Beans + */ +export class QwcArcBeans extends LitElement { + + static styles = css` + .arctable { + height: 100%; + padding-bottom: 10px; + } + + code { + font-size: 85%; + } + + .annotation { + color: var(--lumo-contrast-50pct); + } + + .producer { + color: var(--lumo-primary-text-color); + } + `; + + static properties = { + _beans: {state: true}, + }; + + constructor() { + super(); + this._beans = beans; + } + + render() { + if (this._beans) { + + return html` + + + + + + + + + + `; + + } else { + return html`No beans found`; + } + } + + _beanRenderer(bean) { + return html` + @${bean.scope.simpleName} + ${bean.nonDefaultQualifiers.map(qualifier => + html`${this._qualifierRenderer(qualifier)}` + )} + ${bean.providerType.name} + `; + } + + _kindRenderer(bean) { + return html` + + ${this._kindBadgeRenderer(bean)} + ${this._kindClassRenderer(bean)} + + `; + } + + _kindBadgeRenderer(bean){ + let kind = this._camelize(bean.kind); + let level = null; + + if(bean.kind.toLowerCase() === "field"){ + kind = "Producer field"; + level = "success"; + }else if(bean.kind.toLowerCase() === "method"){ + kind = "Producer method"; + level = "success"; + }else if(bean.kind.toLowerCase() === "synthetic"){ + level = "contrast"; + } + + return html` + ${level + ? html`${kind}` + : html`${kind}` + }`; + } + + _kindClassRenderer(bean){ + return html` + ${bean.declaringClass + ? html`${bean.declaringClass.simpleName}.${bean.memberName}()` + : html`${bean.memberName}` + } + `; + } + + _interceptorsRenderer(bean) { + if (bean.interceptors && bean.interceptors.length > 0) { + return html` + ${bean.interceptorInfos.map(interceptor => + html`
+ ${interceptor.interceptorClass.name} + ${interceptor.priority} +
` + )} +
`; } - {/style} - {#script} // <3> - $(document).ready(function(){ - $(function () { - $('[data-toggle="tooltip"]').tooltip() + } + + _qualifierRenderer(qualifier) { + return html`${qualifier.simpleName}`; + } + + _camelize(str) { + return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function (match, index) { + if (+match === 0) + return ""; + return index === 0 ? match.toUpperCase() : match.toLowerCase(); }); - }); - {/script} - {#title}Cache{/title}// <4> - {#body}// <5> - - - - - - - - - {#for cacheInfo in info:cacheInfos}// <6> - - - - - {/for} - -
NameSize
- {cacheInfo.name} - -
- enctype="application/x-www-form-urlencoded"> - - - -
-
- {/body} -{/include} ----- -<1> In order to benefit from the same style as other Dev UI pages, extend the `main` template -<2> You can pass extra CSS for your page in the `style` template parameter -<3> You can pass extra JavaScript for your page in the `script` template parameter. This will be added inline after the JQuery script, so you can safely use JQuery in your script. -<4> Don't forget to set your page title in the `title` template parameter -<5> The `body` template parameter will contain your content -<6> In order for your template to read custom information from your Quarkus extension, you can use - the `info` xref:qute-reference.adoc#namespace_extension_methods[namespace]. -<7> This shows an xref:advanced-usage-adding-actions[interactive page] - -== Linking to your full-page templates - -Full-page templates for extensions live under a pre-defined `{devRootAppend}/{groupId}.{artifactId}/` directory -that is referenced using the `urlbase` template parameter. Using configuration defaults, that would resolve to -`/q/dev-v1/io.quarkus.quarkus-cache/`, as an example. - -Use the `{urlbase}` template parameter to reference this folder in `embedded.html`: + } +} +customElements.define('qwc-arc-beans', QwcArcBeans); +---- +<1> Import the Vaadin component you want to use +<2> You can also import other functions if needed +<3> There are some internal UI components that you can use, described below + +===== Using internal UI components + +Some https://github.com/quarkusio/quarkus/tree/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qui[internal UI components] (under the `qui` namespace) are available to make certain things easier: + +- Card +- Badge +- Alert +- Code block +- IDE Link + +====== Card + +Card component to display contents in a card + +[source,javascript] +---- +import 'qui-card'; +---- + +[source,html] +---- + +
+ My contents +
+
+---- + +https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/resources/dev-ui/qwc-jokes-vaadin.js#L110[Example code] + +====== Badge + +Badge UI Component based on the https://vaadin.com/docs/latest/components/badge[vaadin themed] badge + +image::dev-ui-qui-badge-v2.png[alt=Dev UI Badge,role="center"] + +[source,javascript] +---- +import 'qui-badge'; +---- + +You can use any combination of small, primary, pill, with icon and clickable with any level of `default`, `success`, `warning`, `error`, `contrast` or set your own colors. + +[source,html] +---- +
+

Badges

+

Badges wrap the Vaadin theme in a component. + See https://vaadin.com/docs/latest/components/badge for more info. +

+
+ +
+
+ Default + Success + Warning + Error + Contrast + Custom colours +
+
+
+ +
+
+ Default primary + Success primary + Warning primary + Error primary + Contrast primary + Custom colours +
+
+
+ +
+
+ Default pill + Success pill + Warning pill + Error pill + Contrast pill + Custom colours +
+
+
+ +
+
+ + Default icon + + + Success icon + + + Warning icon + + + Error icon + + + Contrast icon + + + Custom colours + +
+
+
+ +
+
+ + + + + + +
+
+
+ +
+
+ this._info()}>Default + this._success()}>Success + this._warning()}>Warning + this._error()}>Error + this._contrast()}>Contrast + this._info()}>Custom colours +
+
+
+
+
+---- + +https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/resources/dev-ui/qwc-jokes-vaadin.js#L214[Example code] + +====== Alert + +Alerts are modeled around the Bootstrap alerts. Click https://getbootstrap.com/docs/4.0/components/alerts[here] for more info. + +Also see Notification controller below as an alternative. + +image::dev-ui-qui-alert-v2.png[alt=Dev UI Alert,role="center"] + +[source,javascript] +---- +import 'qui-alert'; +---- + +[source,html] +---- +
+
+ Info alert + Success alert + Warning alert + Error alert +
+ Permanent Info alert + Permanent Success alert + Permanent Warning alert + Permanent Error alert +
+ Center Info alert + Center Success alert + Center Warning alert + Center Error alert +
+ Info alert with icon + Success alert with icon + Warning alert with icon + Error alert with icon +
+ Info alert with custom icon + Success alert with custom icon + Warning alert with custom icon + Error alert with custom icon +
+ Small Info alert with icon + Small Success alert with icon + Small Warning alert with icon + Small Error alert with icon +
+ Info alert with markup
quarkus.io
+ Success alert with markup
quarkus.io
+ Warning alert with markup
quarkus.io
+ Error alert with markup
quarkus.io
+
+ Primary Info alert with icon + Primary Success alert with icon + Primary Warning alert with icon + Primary Error alert with icon +
+ Info alert with title + Success alert with title + Warning alert with title + Error alert with title +
+ Info alert with title and icon + Success alert with title and icon + Warning alert with title and icon + Error alert with title and icon +
+
+---- + +https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/resources/dev-ui/qwc-jokes-vaadin.js#L316[Example code] + + +====== Code block + +Display a code block. This component is aware of the theme and will use the correct codemirror theme to match the light/dark mode. + + +image::dev-ui-qui-code-block-v2.png[alt=Dev UI Code Block,role="center"] + +[source,javascript] +---- +import 'qui-code-block'; +---- + +[source,html] +---- +
+ + +
; +---- + +https://github.com/quarkusio/quarkus/blob/e03a97845738436c69443a591ec4ce88ed04ac91/extensions/kubernetes/vanilla/deployment/src/main/resources/dev-ui/qwc-kubernetes-manifest.js#L99[Example code] + +or fetching the contents from a URL: + +[source,html] +---- +
+ + +
+---- + +https://github.com/quarkusio/quarkus/blob/95c54fa46a6b6f31d69477234486d9359a2a3a4a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-external-page.js#L116[Example code] + +====== IDE link + +Creates a link to a resource (like a Java source file) that can be opened in the user's IDE (if we could detect the IDE). + +[source,javascript] +---- +import 'qui-ide-link'; +---- + +[source,html] +---- +[${sourceClassNameFull}]; +---- + +https://github.com/quarkusio/quarkus/blob/582f1f78806d2268885faea7aa8f5a4d2b3f5b98/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-server-log.js#L315[Example code] + +===== Using internal controllers + +Some https://github.com/quarkusio/quarkus/tree/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller[internal controllers] are available to make certain things easier: + +- Notifier +- Storage +- Log +- Router +- JsonRPC + +====== Notifier + +This is an easy way to show a toast message. The toast can be placed on the screen (default left bottom) and can have a level (Info, Success, Warning, Error). Any of the levels can also be primary, that will create a more prominent toast message. + +See the source of this controller https://github.com/quarkusio/quarkus/blob/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/notifier.js[here]. + +Example usage: + +image::dev-ui-controller-notifier.gif[alt=Dev UI Notifier,role="center"] + +[source,javascript] +---- +import { notifier } from 'notifier'; +---- [source,html] ---- -// <1> - - Caches {info:cacheInfos.size()} + this._info()}>Info; +---- + +[source,javascript] +---- +_info(position = null){ + notifier.showInfoMessage("This is an information message", position); +} +---- + +You can find all the valid positions https://vaadin.com/docs/latest/components/notification/#position[here]. + +https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/resources/dev-ui/qwc-jokes-vaadin.js#L374[Example code] + +====== Storage + +An easy way to access the local storage in a safe way. This will store values in the local storage, scoped to your extension. This way you do not have to worry that you might clash with another extension. + +Local storage is useful to remember user preferences or state. For example, the footer remembers the state (open/close) and the size when open of the bottom drawer. + +[source,javascript] +---- +import { StorageController } from 'storage-controller'; + +// ... + +storageControl = new StorageController(this); // Passing in this will scope the storage to your extension + +// ... + +const storedHeight = this.storageControl.get("height"); // Get some value + +// ... + +this.storageControl.set('height', 123); // Set some val +---- + +https://github.com/quarkusio/quarkus/blob/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-footer.js[Example code] + + +====== Log + +The log controller is used to add control buttons to a (footer) log. +See <>. + +image::dev-ui-log-control-v2.png[alt=Dev UI Log control,role="center"] + +[source,javascript] ---- -<1> Use the `urlbase` template parameter to reference full-page templates for your extension +import { LogController } from 'log-controller'; + +// ... + +logControl = new LogController(this); // Passing in this will scope the control to your extension + +// ... +this.logControl + .addToggle("On/off switch", true, (e) => { + this._toggleOnOffClicked(e); + }).addItem("Log levels", "font-awesome-solid:layer-group", "var(--lumo-tertiary-text-color)", (e) => { + this._logLevels(); + }).addItem("Columns", "font-awesome-solid:table-columns", "var(--lumo-tertiary-text-color)", (e) => { + this._columns(); + }).addItem("Zoom out", "font-awesome-solid:magnifying-glass-minus", "var(--lumo-tertiary-text-color)", (e) => { + this._zoomOut(); + }).addItem("Zoom in", "font-awesome-solid:magnifying-glass-plus", "var(--lumo-tertiary-text-color)", (e) => { + this._zoomIn(); + }).addItem("Clear", "font-awesome-solid:trash-can", "var(--lumo-error-color)", (e) => { + this._clearLog(); + }).addFollow("Follow log", true , (e) => { + this._toggleFollowLog(e); + }).done(); +---- + +https://github.com/quarkusio/quarkus/blob/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-server-log.js[Example code] + +====== Router + +The router is mostly used internally. This uses https://github.com/vaadin/router[Vaadin Router] under the covers to route URLs to the correct page/section within the SPA. It will update the navigation and allow history (back button). This also creates the sub-menu available on extensions that have multiple pages. + +See the https://github.com/quarkusio/quarkus/blob/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/router-controller.js[controller] for some methods that might be useful. -== Passing information to your templates +[#JsonRPC] +====== JsonRPC -In `embedded.html` or in full-page templates, you will likely want to display information that is -available from your extension. +This controller allows you to fetch or stream runtime data. (vs. <> discussed earlier). There are two parts to getting data during runtime. The Java side in the runtime module, and then the usage in the web component. -There are two ways to make that information available, depending on whether it is available at -build time or at run time. +*Java part* -In both cases we advise that you add support for the Dev UI in your `{pkg}.deployment.devconsole` -package in a `DevConsoleProcessor` class (in your extension's -xref:building-my-first-extension.adoc#description-of-a-quarkus-extension[`deployment`] module). +This code is responsible for making data available to display on the UI. -=== Passing run-time information +You need to register the JsonPRCService in your processor in the deployment module: [source,java] ---- -package io.quarkus.cache.deployment.devconsole; +@BuildStep(onlyIf = IsDevelopment.class)// <1> +JsonRPCProvidersBuildItem createJsonRPCServiceForCache() {// <2> + return new JsonRPCProvidersBuildItem(CacheJsonRPCService.class);// <3> +} +---- +<1> Always only do this in Dev Mode +<2> Produce / return a `JsonRPCProvidersBuildItem` +<3> Define the class in your runtime module that will contain methods that make data available in the UI + +https://github.com/quarkusio/quarkus/blob/main/extensions/cache/deployment/src/main/java/io/quarkus/cache/deployment/devui/CacheDevUiProcessor.java[Example code] + +Now, in your Runtime module create the JsonRPC Service. This class will default to an application scoped bean, except if you explicitly scope the bean. All public methods that return something will be made available to call from the Web component Javascript. + +The return object in these methods can be: -import io.quarkus.cache.runtime.CaffeineCacheSupplier; -import io.quarkus.deployment.IsDevelopment; -import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem; +- primitives or `String`, +- `io.vertx.core.json.JsonArray` +- `io.vertx.core.json.JsonObject` +- any other POJO that can be serializable to Json -public class DevConsoleProcessor { +All of the above can be blocking (POJO) or non-blocking (`@NonBlocking` or `Uni`). Or alternatively data can be streamed using `Multi`. - @BuildStep(onlyIf = IsDevelopment.class)// <1> - public DevConsoleRuntimeTemplateInfoBuildItem collectBeanInfo() { - return new DevConsoleRuntimeTemplateInfoBuildItem("cacheInfos", - new CaffeineCacheSupplier());// <2> +[source,java] +---- +@NonBlocking // <1> +public JsonArray getAll() { // <2> + Collection names = manager.getCacheNames(); + List allCaches = new ArrayList<>(names.size()); + for (String name : names) { + Optional cache = manager.getCache(name); + if (cache.isPresent() && cache.get() instanceof CaffeineCache) { + allCaches.add((CaffeineCache) cache.get()); + } } + allCaches.sort(Comparator.comparing(CaffeineCache::getName)); + + var array = new JsonArray(); + for (CaffeineCache cc : allCaches) { + array.add(getJsonRepresentationForCache(cc)); + } + return array; } ---- -<1> Don't forget to make this xref:building-my-first-extension.adoc#deploying-the-greeting-feature[build step] - conditional on being in dev mode -<2> Declare a run-time dev `info:cacheInfos` template value +<1> This example runs non blocking. We could also return `Uni` +<2> The method name `getAll` will be available in the Javascript + +https://github.com/quarkusio/quarkus/blob/main/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/devconsole/CacheJsonRPCService.java[Example code] + +*Webcomponent (Javascript) part* + +Now you can use the JsonRPC controller to access the `getAll` method (and any other methods in you JsonRPC Service) + +[source,javascript] +---- +import { JsonRpc } from 'jsonrpc'; + +// ... + +jsonRpc = new JsonRpc(this); // Passing in this will scope the rpc calls to your extension + +// ... + +/** + * Called when displayed + */ +connectedCallback() { + super.connectedCallback(); + this.jsonRpc.getAll().then(jsonRpcResponse => { // <1> + this._caches = new Map(); + jsonRpcResponse.result.forEach(c => { //<2> + this._caches.set(c.name, c); + }); + }); +} +---- + +<1> Note the method `getAll` corresponds to the method in your Java Service. This method returns a https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise[Promise] with the JsonRPC result. +<2> In this case the result is an array, so we can loop over it. + +JsonArray (or any Java collection) in either blocking or non-blocking will return an array, else a JsonObject will be returned. + +https://github.com/quarkusio/quarkus/blob/main/extensions/cache/deployment/src/main/resources/dev-ui/qwc-cache-caches.js[Example code] -This will map the `info:cacheInfos` value to this supplier in your extension's -xref:building-my-first-extension.adoc#description-of-a-quarkus-extension[`runtime module`]: +You can also pass in parameters in the method being called, for example: +(In the Runtime Java code) [source,java] ---- -package io.quarkus.cache.runtime; +public Uni clear(String name) { //<1> + Optional cache = manager.getCache(name); + if (cache.isPresent()) { + return cache.get().invalidateAll().map((t) -> getJsonRepresentationForCache(cache.get())); + } else { + return Uni.createFrom().item(new JsonObject().put("name", name).put("size", -1)); + } +} +---- +<1> the clear method takes one parameter called `name` + +In the Webcomponent (Javascript): + +[source,javascript] +---- +_clear(name) { + this.jsonRpc.clear({name: name}).then(jsonRpcResponse => { //<1> + this._updateCache(jsonRpcResponse.result) + }); +} +---- +<1> the `name` parameter is passed in. -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.function.Supplier; +====== Streaming data -import io.quarkus.arc.Arc; -import io.quarkus.cache.CaffeineCache; +You can keep a UI screen updated with the latest data by continuously streaming data to the screen. This can be done with `Multi` (Java side) and `Observer` (Javascript side) -public class CaffeineCacheSupplier implements Supplier> { +Java side of streaming data: - @Override - public List get() { - List allCaches = new ArrayList<>(allCaches()); - allCaches.sort(Comparator.comparing(CaffeineCache::getName)); - return allCaches; +[source,java] +---- +public class JokesJsonRPCService { + + private final BroadcastProcessor jokeStream = BroadcastProcessor.create(); + + @PostConstruct + void init() { + Multi.createFrom().ticks().every(Duration.ofHours(4)).subscribe().with((item) -> { + jokeStream.onNext(getJoke()); + }); } - public static Collection allCaches() { - // Get it from ArC at run-time - return (Collection) (Collection) - Arc.container().instance(CacheManagerImpl.class).get().getAllCaches(); + public Multi streamJokes() { // <1> + return jokeStream; } + + // ... } ---- +<1> Return the Multi that will stream jokes -=== Passing build-time information +https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/runtime/src/main/java/io/quarkus/jokes/runtime/JokesJsonRPCService.java#L37[Example code] -Sometimes you only need build-time information to be passed to your template, so you can do it like this: +Javascript side of streaming data: -[source,java] +[source,javascript] ---- -package io.quarkus.qute.deployment.devconsole; - -import java.util.List; - -import io.quarkus.deployment.IsDevelopment; -import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.devconsole.spi.DevConsoleTemplateInfoBuildItem; -import io.quarkus.qute.deployment.CheckedTemplateBuildItem; -import io.quarkus.qute.deployment.TemplateVariantsBuildItem; - -public class DevConsoleProcessor { - - @BuildStep(onlyIf = IsDevelopment.class) - public DevConsoleTemplateInfoBuildItem collectBeanInfo( - List checkedTemplates,// <1> - TemplateVariantsBuildItem variants) { - DevQuteInfos quteInfos = new DevQuteInfos(); - for (CheckedTemplateBuildItem checkedTemplate : checkedTemplates) { - DevQuteTemplateInfo templateInfo = - new DevQuteTemplateInfo(checkedTemplate.templateId, - variants.getVariants().get(checkedTemplate.templateId), - checkedTemplate.bindings); - quteInfos.addQuteTemplateInfo(templateInfo); - } - return new DevConsoleTemplateInfoBuildItem("devQuteInfos", quteInfos);// <2> +this._observer = this.jsonRpc.streamJokes().onNext(jsonRpcResponse => { //<1> + this._addToJokes(jsonRpcResponse.result); + this._numberOfJokes = this._numberOfJokes++; +}); + +// ... + +this._observer.cancel(); //<2> +---- +<1> You can call the method (optionally passing in parameters) and then provide the code that will be called on the next event. +<2> Make sure to keep an instance of the observer to cancel later if needed. + +https://github.com/phillip-kruger/quarkus-jokes/blob/main/deployment/src/main/resources/dev-ui/qwc-jokes-web-components.js[Example code] + +====== Dev UI Log + +When running a local application using the `999-SNAPSHOT` version, the Dev UI will show a `Dev UI` Log in the footer. This is useful to debug all JSON RPC messages flowing between the browser and the Quarkus app. + +image::dev-ui-jsonrpc-log-v2.png[alt=Dev UI Json RPC Log,role="center"] + +== Hot reload + +You can update a screen automatically when a Hot reload has happened. To do this replace the `LitElement` that your Webcomponent extends with `QwcHotReloadElement`. + +`QwcHotReloadElement` extends `LitElement` so your component is still a Lit Element. + +When extending a `QwcHotReloadElement` you have to provide the `hotReload` method. (You also still need to provide the `render` method from Lit) + +[source,javascript] +---- +import { QwcHotReloadElement, html, css} from 'qwc-hot-reload-element'; + +// ... + +export class QwcMyExtensionPage extends QwcHotReloadElement { + + render(){ + // ... } + hotReload(){ + // .. + } + +} +---- + +== Custom cards + +You can customize the card that is being displayed on the extension page if you do not want to use the default built-in card. + +To do this, you need to provide a Webcomponent that will be loaded in the place of the provided card and register this in the Java Processor: + +[source,java] +---- +cardPageBuildItem.setCustomCard("qwc-mycustom-card.js"); +---- + +On the Javascript side, you have access to all the pages (in case you want to create links) + +[source,javascript] +---- +import { pages } from 'build-time-data'; +---- + +And the following properties will be passed in: + +- extensionName +- description +- guide +- namespace + +[source,javascript] +---- +static properties = { + extensionName: {type: String}, + description: {type: String}, + guide: {type: String}, + namespace: {type: String} } ---- -<1> Use whatever dependencies you need as input -<2> Declare a build-time `info:devQuteInfos` DEV template value -== Advanced usage: adding actions +== State (Advance) + +State allows properties to contain state and can be reused globally. An example of state properties are the theme, the connection state (if we are connected to the backend), etc. + +See the https://github.com/quarkusio/quarkus/tree/main/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/state[current built-in] state objects. -You can also add actions to your Dev UI templates: +The state in Dev UI uses https://github.com/gitaarik/lit-state[LitState] and you can read more about it in their https://gitaarik.github.io/lit-state/build/[documentation]. -image::dev-ui-interactive.png[alt=Dev UI interactive page,align=center,width=90%] -This can be done by adding another xref:building-my-first-extension.adoc#deploying-the-greeting-feature[build step] to -declare the action in your extension's -xref:building-my-first-extension.adoc#description-of-a-quarkus-extension[`deployment`] module: +== Add a log file +Apart from adding a card and a page, extensions can add a log to the footer. This is useful to log things happening continuously. A page will lose connection to the backend when navigating away from that page, a log in the footer is permanently connected. + +Adding something to the footer works exactly like adding a Card, except you use a `FooterPageBuildItem` rather than a `CardPageBuildItem`. [source,java] ---- -package io.quarkus.cache.deployment.devconsole; +FooterPageBuildItem footerPageBuildItem = new FooterPageBuildItem(); -import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT; +footerPageBuildItem.addPage(Page.webComponentPageBuilder() + .icon("font-awesome-regular:face-grin-tongue-wink") + .title("Joke Log") + .componentLink("qwc-jokes-log.js")); -import io.quarkus.cache.runtime.devconsole.CacheDevConsoleRecorder; -import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.deployment.annotations.Record; -import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem; +footerProducer.produce(footerPageBuildItem); +---- -public class DevConsoleProcessor { +https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/java/io/quarkus/jokes/deployment/devui/JokesDevUIProcessor.java#L87[Example code] - @BuildStep - @Record(value = STATIC_INIT, optional = true)// <1> - DevConsoleRouteBuildItem invokeEndpoint(CacheDevConsoleRecorder recorder) { - return new DevConsoleRouteBuildItem("caches", "POST", - recorder.clearCacheHandler());// <2> - } +In your Webcomponent you can then stream the log to the UI: + +[source,javascript] +---- +export class QwcJokesLog extends LitElement { + jsonRpc = new JsonRpc(this); + logControl = new LogController(this); + + // .... } ---- -<1> Mark the recorder as optional, so it will only be invoked when in dev mode -<2> Declare a `POST {urlbase}/caches` route handled by the given handler +https://github.com/phillip-kruger/quarkus-jokes/blob/main/deployment/src/main/resources/dev-ui/qwc-jokes-log.js[Example code] -Note: you can see xref:action-example[how to invoke this action from your full page]. +== Add a section menu -Now all you have to do is implement the recorder in your extension's -xref:building-my-first-extension.adoc#description-of-a-quarkus-extension[`runtime module`]: +This allows an extension to link a page directly in the section Menu. +Adding something to the section menu works exactly like adding a Card, except you use a `MenuPageBuildItem` rather than a `CardPageBuildItem`. [source,java] ---- -package io.quarkus.cache.runtime.devconsole; - -import io.quarkus.cache.CaffeineCache; -import io.quarkus.cache.runtime.CaffeineCacheSupplier; -import io.quarkus.runtime.annotations.Recorder; -import io.quarkus.devconsole.runtime.spi.DevConsolePostHandler; -import io.quarkus.vertx.http.runtime.devmode.devconsole.FlashScopeUtil.FlashMessageStatus; -import io.vertx.core.Handler; -import io.vertx.core.MultiMap; -import io.vertx.ext.web.RoutingContext; - -@Recorder -public class CacheDevConsoleRecorder { - - public Handler clearCacheHandler() { - return new DevConsolePostHandler() {// <1> - @Override - protected void handlePost(RoutingContext event, MultiMap form) // <2> - throws Exception { - String cacheName = form.get("name"); - for (CaffeineCache cache : CaffeineCacheSupplier.allCaches()) { - if (cache.getName().equals(cacheName)) { - cache.invalidateAll(); - flashMessage(event, "Cache for " + cacheName + " cleared");// <3> - return; - } - } - flashMessage(event, "Cache for " + cacheName + " not found", - FlashMessageStatus.ERROR);// <4> - } - }; +MenuPageBuildItem menuPageBuildItem = new MenuPageBuildItem(); + +menuPageBuildItem.addPage(Page.webComponentPageBuilder() + .icon("font-awesome-regular:face-grin-tongue-wink") + .title("One Joke") + .componentLink("qwc-jokes-menu.js")); + +menuProducer.produce(menuPageBuildItem); +---- + +https://github.com/phillip-kruger/quarkus-jokes/blob/f572ed6f949de0c0b8cbfa99d7389ab5168fea65/deployment/src/main/java/io/quarkus/jokes/deployment/devui/JokesDevUIProcessor.java#LL71C16-L71C16[Example code] + +Your page can be any Page similar to Cards. + +== Testing + +You can add tests to your extension that test: + +- Build time data +- Runtime data via JsonRPC + +You need to add this to your pom: + +[source,xml] +---- + + io.quarkus + quarkus-vertx-http-dev-ui-tests + test + +---- + +This will give you access to two base classes for creating these tests. + +=== Testing Build time data + +If you added Build time data, for example: + +[source,java] +---- +cardPageBuildItem.addBuildTimeData("somekey", somevalue); +---- + +To test that your build time data is generated correctly you can add a test that extends `DevUIBuildTimeDataTest`. + +[source,java] +---- +public class SomeTest extends DevUIBuildTimeDataTest { + + @RegisterExtension + static final QuarkusDevModeTest config = new QuarkusDevModeTest().withEmptyApplication(); + + public SomeTest() { + super("io.quarkus.my-extension"); } + + @Test + public void testSomekey() throws Exception { + JsonNode somekeyResponse = super.getBuildTimeData("somekey"); + Assertions.assertNotNull(somekeyResponse); + + // Check more values on somekeyResponse + } + +} +---- + +=== Testing Runtime data + +If you added a JsonRPC Service with runtime data responses, for example: + +[source,java] +---- +public boolean updateProperties(String content, String type) { + // ... } ---- -<1> While you can use https://vertx.io/docs/vertx-web/java/#_routing_by_http_method[any Vert.x handler], - the `DevConsolePostHandler` superclass will handle your POST actions - nicely, and auto-redirect to the `GET` URI right after your `POST` for optimal behavior. -<2> You can get the Vert.x `RoutingContext` as well as the `form` contents -<3> Don't forget to add a message for the user to let them know everything went fine -<4> You can also add error messages +To test that `updateProperties` execute correctly via JsonRPC you can add a test that extends `DevUIJsonRPCTest`. + +[source,java] +---- +public class SomeTest extends DevUIJsonRPCTest { + + @RegisterExtension + static final QuarkusDevModeTest config = new QuarkusDevModeTest().withEmptyApplication(); -NOTE: Flash messages are handled by the `main` DEV template and will result in nice notifications for your -users: + public SomeTest() { + super("io.quarkus.my-extension"); + } + + @Test + public void testUpdateProperties() throws Exception { -image::dev-ui-message.png[alt=Dev UI message,align=center,width=90%] + JsonNode updatePropertyResponse = super.executeJsonRPCMethod("updateProperty", + Map.of( + "name", "quarkus.application.name", + "value", "changedByTest")); + Assertions.assertTrue(updatePropertyResponse.asBoolean()); + // Get the properties to make sure it is changed + JsonNode allPropertiesResponse = super.executeJsonRPCMethod("getAllValues"); + String applicationName = allPropertiesResponse.get("quarkus.application.name").asText(); + Assertions.assertEquals("changedByTest", applicationName); + } +} +---- diff --git a/_versions/main/guides/doc-concept.adoc b/_versions/main/guides/doc-concept.adoc index 2387175811..7cc84e5fc4 100644 --- a/_versions/main/guides/doc-concept.adoc +++ b/_versions/main/guides/doc-concept.adoc @@ -9,6 +9,7 @@ include::_attributes.adoc[] :diataxis-type: concept :categories: contributing :fn-diataxis: footnote:diataxis[Procida, D. Diátaxis documentation framework. https://diataxis.fr/] +:topics: internals,documentation Quarkus documentation is structured into four distinct content types: concepts, how-tos, tutorials, and references. The composition and structure of Quarkus docs follow the Diátaxis systematic documentation framework for technical documentation authoring. @@ -16,7 +17,7 @@ Each content type resolves a different user need, fulfills a different purpose, == Diátaxis documentation framework -We chose to align Quarkus docs with the Diátaxis documentation framework{fn-diataxis}, which defines a core content structure that addresses the different needs users have when consulting docs. +We chose to align Quarkus docs with the Diátaxis documentation framework{fn-diataxis}, which defines a core content structure that addresses the different needs users have when consulting docs. image::diataxis-framework.png[The content types in the Diátaxis documentation framework{fn-diataxis},width=40%, align=left] @@ -46,11 +47,11 @@ You can cite design decisions, historical reasons, and technical constraints to > How-to guides are _directions_ that take the reader through the steps required to solve a real-world problem. How-to guides are _goal-oriented_. -Good how-to guides: +Good how-to guides: - guide (walk-through) or demonstrate how to complete a task. -- assume you have enough context to begin the task. -- describes the concrete steps necessary to complete a task, but these steps +- assume you have enough context to begin the task. +- describes the concrete steps necessary to complete a task, but these steps could be in the middle of a larger task. - do not explain concepts, they rely on other documents (like concepts) to do that. - are adaptable to real-world use cases. @@ -61,15 +62,15 @@ Good how-to guides: > Reference guides are _technical descriptions_ of the machinery and how to operate it. Reference material is _information-oriented_. -Good reference guides: +Good reference guides: - are concise and to the point. They state, describe, and inform. -- are consistent (to the extent possible) with other reference guides. +- are consistent (to the extent possible) with other reference guides. Following the template helps here. -- remain focused on describing their topic. +- remain focused on describing their topic. They don't explain or provide additional context from other sources. - provide examples or illustrations that help readers understand what is being described. -- are kept up to date. While configuration reference material is generated, +- are kept up to date. While configuration reference material is generated, extension references that describe how configuration should be applied must be accurate to be useful. @@ -78,13 +79,13 @@ Good reference guides: > Tutorials are _lessons_ that take the reader by the hand through a series of steps to complete a project of some kind. Tutorials are _learning-oriented_. -Good tutorials: +Good tutorials: - provide a learning experience, giving the reader something they can do. - get the reader started (they do not create an expert). - provide the reader with concrete steps to follow that each have a comprehensible result. - are reliable and consistent (they work for all users, every time). -- include only enough information to complete the task. +- include only enough information to complete the task. They delegate to other documentation types (concepts or reference) to provide additional context. - focus on one way of doing the task. Alternative approaches are explored in other document types (a how-to guide, for example). diff --git a/_versions/main/guides/doc-contribute-docs-howto.adoc b/_versions/main/guides/doc-contribute-docs-howto.adoc index fbb6376d7d..8c522b2cb9 100644 --- a/_versions/main/guides/doc-contribute-docs-howto.adoc +++ b/_versions/main/guides/doc-contribute-docs-howto.adoc @@ -8,6 +8,7 @@ include::_attributes.adoc[] :diataxis-type: howto :categories: contributing :fn-diataxis: footnote:diataxis[Procida, D. Diátaxis documentation framework. https://diataxis.fr/] +:topics: internals,documentation Contribute to the documentation by using the recommended diataxis content types, steps, workflow, and style guidance to ensure the content successfully renders on the Quarkus website portal. @@ -56,7 +57,7 @@ include::_attributes.adoc[] <3> :categories: security,web <5> <6> ---- -<1> Set the `id` value to be the same as the file name but without the extension. +<1> Set the `id` value to be the same as the file name but without the extension. <2> For information about how to create a good title for each content type, see xref:{doc-guides}/doc-reference.adoc#titles-and-headings[Titles and headings] on the "Quarkus style and content guidelines" page. <3> The `_attributes.adoc` include is required to ensure that attributes get resolved and the table of contents is generated. <4> Specify the diataxis type: `concept`, `howto`, `reference`, or `tutorial`. diff --git a/_versions/main/guides/doc-create-tutorial.adoc b/_versions/main/guides/doc-create-tutorial.adoc index a1bccc9ced..ed8a37fb2f 100644 --- a/_versions/main/guides/doc-create-tutorial.adoc +++ b/_versions/main/guides/doc-create-tutorial.adoc @@ -8,6 +8,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: tutorial :categories: contributing +:topics: internals,documentation Create a new tutorial that guides users through creating, running, and testing a Quarkus application that uses annotations from an imaginary extension. diff --git a/_versions/main/guides/doc-reference.adoc b/_versions/main/guides/doc-reference.adoc index 805fafb379..1cac929cd7 100644 --- a/_versions/main/guides/doc-reference.adoc +++ b/_versions/main/guides/doc-reference.adoc @@ -8,6 +8,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: reference :categories: contributing +:topics: internals,documentation Guidelines are provided to help you to contribute clear and consistent content that is also sourced in the required diataxis structure and composition of Quarkus documentation. @@ -137,7 +138,7 @@ Suffix:: Use a suffix that reflects the document type (optional): - `-concept.adoc` for concept documents - `-howto.adoc` for how-to guides -- `-reference.adoc` for references +- `-reference.adoc` for references - `-tutorial.adoc` for tutorials [[doc-structure]] diff --git a/_versions/main/guides/duplicated-context.adoc b/_versions/main/guides/duplicated-context.adoc index 25a97d1413..7dea4f7969 100644 --- a/_versions/main/guides/duplicated-context.adoc +++ b/_versions/main/guides/duplicated-context.adoc @@ -8,6 +8,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: concept :categories: core, architecture +:topics: internals,extensions When using a traditional, blocking, and synchronous framework, processing of each request is performed in a dedicated thread. So, the same thread is used for the entire processing. diff --git a/_versions/main/guides/elasticsearch-dev-services.adoc b/_versions/main/guides/elasticsearch-dev-services.adoc index b02a6c2704..2ede49bdb9 100644 --- a/_versions/main/guides/elasticsearch-dev-services.adoc +++ b/_versions/main/guides/elasticsearch-dev-services.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: Start Elasticsearch automatically in dev and test modes +:topics: data,search,elasticsearch,nosql,devservices,tooling,testing,devmode +:extensions: io.quarkus:quarkus-elasticsearch-java-client,io.quarkus:quarkus-elasticsearch-rest-client,io.quarkus:quarkus-hibernate-search-orm-elasticsearch If any Elasticsearch-related extension is present (e.g. `quarkus-elasticsearch-rest-client` or `quarkus-hibernate-search-orm-elasticsearch`), Dev Services for Elasticsearch automatically starts an Elasticsearch server in dev mode and when running tests. diff --git a/_versions/main/guides/elasticsearch.adoc b/_versions/main/guides/elasticsearch.adoc index b1a915f32e..e35795e45c 100644 --- a/_versions/main/guides/elasticsearch.adoc +++ b/_versions/main/guides/elasticsearch.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: This guide covers how to interact with an Elasticsearch cluster using the low level REST client or the Elasticsearch Java client. +:topics: data,search,elasticsearch,nosql +:extensions: io.quarkus:quarkus-elasticsearch-java-client,io.quarkus:quarkus-elasticsearch-rest-client Elasticsearch is a well known full text search engine and NoSQL datastore. diff --git a/_versions/main/guides/extension-codestart.adoc b/_versions/main/guides/extension-codestart.adoc index 284b47a27f..398ffdd8b4 100644 --- a/_versions/main/guides/extension-codestart.adoc +++ b/_versions/main/guides/extension-codestart.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: writing-extensions :summary: Provide users with initial code for extensions when generating Quarkus applications on code.quarkus.io and all the Quarkus tooling. This guide explains how to create and configure a Codestart for an extension. +:topics: extensions,codestarts +:extensions: io.quarkus:quarkus-core This guide explains how to create and configure a Quarkus Codestart for an extension. diff --git a/_versions/main/guides/extension-metadata.adoc b/_versions/main/guides/extension-metadata.adoc index d48bad282b..738c463a5b 100644 --- a/_versions/main/guides/extension-metadata.adoc +++ b/_versions/main/guides/extension-metadata.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Quarkus Extension Metadata include::_attributes.adoc[] +:categories: writing-extensions +:topics: extensions,codestarts +:extensions: io.quarkus:quarkus-core Quarkus extensions are distributed as Maven JAR artifacts that application and other libraries may depend on. When a Quarkus application project is built, tested or edited using the Quarkus dev tools, Quarkus extension JAR artifacts will be identified on the application classpath by the presence of the Quarkus extension metadata files in them. This document describes the purpose of each Quarkus extension metadata file and its content. diff --git a/_versions/main/guides/extension-registry-user.adoc b/_versions/main/guides/extension-registry-user.adoc index 697b677e30..552baf7103 100644 --- a/_versions/main/guides/extension-registry-user.adoc +++ b/_versions/main/guides/extension-registry-user.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: architecture :summary: Learn more about the notion of extension registry and how you can use your own. +:topics: internals,extensions The Quarkus dev tools, such as the xref:cli-tooling.adoc[Quarkus CLI], the xref:maven-tooling.adoc[Maven] and the xref:gradle-tooling.adoc[Gradle] plugins, or https://code.quarkus.io[code.quarkus.io] can be used to list and search the Quarkus ecosystem for extensions that match a certain criteria. That includes the xref:platform.adoc[Quarkus platform] extensions and various other extensions contributed by the community, many of which are hosted on the https://github.com/quarkiverse[Quarkiverse Hub]. diff --git a/_versions/main/guides/flyway.adoc b/_versions/main/guides/flyway.adoc index f2a07ece5a..a60401bcc4 100644 --- a/_versions/main/guides/flyway.adoc +++ b/_versions/main/guides/flyway.adoc @@ -9,6 +9,8 @@ include::_attributes.adoc[] :summary: This guide covers how to use the Flyway extension to manage your schema migrations. :migrations-path: src/main/resources/db/migration :config-file: application.properties +:topics: flyway,data,schema-migration,database +:extensions: io.quarkus:quarkus-flyway https://flywaydb.org/[Flyway] is a popular database migration tool that is commonly used in JVM environments. diff --git a/_versions/main/guides/funqy-aws-lambda-http.adoc b/_versions/main/guides/funqy-aws-lambda-http.adoc index ff843ff5fb..406777e416 100644 --- a/_versions/main/guides/funqy-aws-lambda-http.adoc +++ b/_versions/main/guides/funqy-aws-lambda-http.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: This guide explains Funqy's AWS Lambda HTTP binding. +:topics: aws,lambda,serverless,function,cloud,funqy +:extensions: io.quarkus:quarkus-funqy-http,io.quarkus:quarkus-amazon-lambda-http If you want to allow HTTP clients to invoke on your Funqy functions on AWS Lambda, Quarkus allows you to expose multiple Funqy functions through HTTP deployed as one AWS Lambda. This approach does add overhead over the diff --git a/_versions/main/guides/funqy-aws-lambda.adoc b/_versions/main/guides/funqy-aws-lambda.adoc index e0a2d9f568..f440ba5764 100644 --- a/_versions/main/guides/funqy-aws-lambda.adoc +++ b/_versions/main/guides/funqy-aws-lambda.adoc @@ -9,6 +9,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: This guide explains Funqy's AWS Lambda binding. +:topics: aws,lambda,serverless,function,cloud,funqy +:extensions: io.quarkus:quarkus-funqy-amazon-lambda The guide walks through quickstart code to show you how you can deploy Funqy functions to AWS Lambda. diff --git a/_versions/main/guides/funqy-azure-functions-http.adoc b/_versions/main/guides/funqy-azure-functions-http.adoc index 47d3a31984..cc0a6ad34b 100644 --- a/_versions/main/guides/funqy-azure-functions-http.adoc +++ b/_versions/main/guides/funqy-azure-functions-http.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: Use Funqy HTTP binding with Microsoft Azure Functions to deploy your serverless Quarkus applications. +:topics: azure,serverless,function,cloud,funqy +:extensions: io.quarkus:quarkus-azure-functions-http You can use xref:funqy-http.adoc[Funqy HTTP] on Azure Functions. This allows you to invoke on multiple Funqy functions using HTTP deployed as one Azure Function. diff --git a/_versions/main/guides/funqy-gcp-functions-http.adoc b/_versions/main/guides/funqy-gcp-functions-http.adoc index f72418f707..99d5a62b5d 100644 --- a/_versions/main/guides/funqy-gcp-functions-http.adoc +++ b/_versions/main/guides/funqy-gcp-functions-http.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: This guide explains Funqy's Google Cloud Platform Functions HTTP binding. +:topics: google,gcp,serverless,function,cloud,funqy +:extensions: io.quarkus:quarkus-funqy-http,io.quarkus:quarkus-google-cloud-functions-http If you want to allow HTTP clients to invoke your Funqy functions on Google Cloud Functions, Quarkus allows you to expose multiple Funqy functions through HTTP deployed as one Google Cloud Function. This approach does add overhead over the diff --git a/_versions/main/guides/funqy-gcp-functions.adoc b/_versions/main/guides/funqy-gcp-functions.adoc index 9a8070c374..5a6b9fa932 100644 --- a/_versions/main/guides/funqy-gcp-functions.adoc +++ b/_versions/main/guides/funqy-gcp-functions.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: This guide explains Funqy's Google Cloud Platform Functions binding. +:topics: google,gcp,serverless,function,cloud,funqy +:extensions: io.quarkus:quarkus-funqy-http,io.quarkus:quarkus-funqy-google-cloud-functions The guide walks through quickstart code to show you how you can deploy Funqy functions to Google Cloud Functions. diff --git a/_versions/main/guides/funqy-http.adoc b/_versions/main/guides/funqy-http.adoc index 894d84623c..e6aa35f736 100644 --- a/_versions/main/guides/funqy-http.adoc +++ b/_versions/main/guides/funqy-http.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: cloud :summary: This guide explains Funqy's HTTP binding. :extension-status: preview +:topics: serverless,function,cloud,funqy +:extensions: io.quarkus:quarkus-funqy-http The guide walks through quickstart code to show you how you can deploy Funqy as a standalone service and invoke on Funqy functions using HTTP. diff --git a/_versions/main/guides/funqy-knative-events.adoc b/_versions/main/guides/funqy-knative-events.adoc index 031506756e..f9e458e9d6 100644 --- a/_versions/main/guides/funqy-knative-events.adoc +++ b/_versions/main/guides/funqy-knative-events.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: cloud :summary: This guide explains Funqy's Knative Events binding. :devtools-no-gradle: +:topics: serverless,function,cloud,funqy +:extensions: io.quarkus:quarkus-funqy-knative-events Quarkus Funqy link:https://knative.dev/docs/eventing[Knative Events] builds off of the xref:funqy-http.adoc[Funqy HTTP] extension to allow you to route and process Knative Events within a Funqy function. diff --git a/_versions/main/guides/funqy.adoc b/_versions/main/guides/funqy.adoc index 1723981be0..b82fa9421c 100644 --- a/_versions/main/guides/funqy.adoc +++ b/_versions/main/guides/funqy.adoc @@ -8,6 +8,7 @@ include::_attributes.adoc[] :categories: cloud :summary: This guide explains basics of the Funqy framework, a simple portable cross-provider cloud function API. :extension-status: preview +:topics: serverless,function,cloud,funqy Quarkus Funqy is part of Quarkus's serverless strategy and aims to provide a portable Java API to write functions deployable to various FaaS environments like AWS Lambda, Azure Functions, Google Cloud Functions, Knative, and Knative Events (Cloud Events). @@ -72,7 +73,7 @@ public class GreetingFunction { == Async Reactive Types -Funqy supports the https://smallrye.io/smallrye-mutiny[Smallrye Mutiny] `Uni` reactive type as a return type. The only requirement is that +Funqy supports the https://smallrye.io/smallrye-mutiny[SmallRye Mutiny] `Uni` reactive type as a return type. The only requirement is that the `Uni` must fill out the generic type. [source, java] diff --git a/_versions/main/guides/gcp-functions-http.adoc b/_versions/main/guides/gcp-functions-http.adoc index de92afa715..5a94708336 100644 --- a/_versions/main/guides/gcp-functions-http.adoc +++ b/_versions/main/guides/gcp-functions-http.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: This guide explains how you can deploy Vert.x Web, Servlet, or RESTEasy microservices as a Google Cloud Function. +:topics: google,gcp,serverless,function,cloud +:extensions: io.quarkus:quarkus-google-cloud-functions-http The `quarkus-google-cloud-functions-http` extension allows you to write microservices with RESTEasy Reactive (Jakarta REST), Undertow (Servlet), Reactive Routes, or xref:funqy-http.adoc[Funqy HTTP], and make these microservices deployable to the Google Cloud Functions runtime. diff --git a/_versions/main/guides/gcp-functions.adoc b/_versions/main/guides/gcp-functions.adoc index 136852b1d0..d0ce3a5a1f 100644 --- a/_versions/main/guides/gcp-functions.adoc +++ b/_versions/main/guides/gcp-functions.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: This guide explains how you can deploy Quarkus-based Google Cloud Functions. +:topics: google,gcp,serverless,function,cloud +:extensions: io.quarkus:quarkus-google-cloud-functions The `quarkus-google-cloud-functions` extension allows you to use Quarkus to build your Google Cloud Functions. Your functions can use injection annotations from CDI or Spring and other Quarkus facilities as you need them. diff --git a/_versions/main/guides/getting-started-dev-services.adoc b/_versions/main/guides/getting-started-dev-services.adoc index ace01fc77c..ef39883cf2 100644 --- a/_versions/main/guides/getting-started-dev-services.adoc +++ b/_versions/main/guides/getting-started-dev-services.adoc @@ -9,6 +9,7 @@ include::_attributes.adoc[] :diataxis-type: tutorial :categories: getting-started, data, core :summary: Discover some of the features that make developing with Quarkus a joyful experience. +:topics: getting-started,devservices This tutorial shows you how to create an application which writes to and reads from a database. You will use Dev Services, so you will not actually download, configure, or even start the database yourself. diff --git a/_versions/main/guides/getting-started-reactive.adoc b/_versions/main/guides/getting-started-reactive.adoc index 5ae2dc045a..2d4ce722df 100644 --- a/_versions/main/guides/getting-started-reactive.adoc +++ b/_versions/main/guides/getting-started-reactive.adoc @@ -5,8 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Getting Started With Reactive include::_attributes.adoc[] -:categories: getting-started +:categories: getting-started,reactive :summary: Learn more about developing reactive applications with Quarkus. +:topics: getting-started,reactive _Reactive_ is a set of principles to build robust, efficient, and concurrent applications and systems. These principles let you handle more load than traditional approaches while using the resources (CPU and memory) more efficiently while also reacting to failures gracefully. diff --git a/_versions/main/guides/getting-started-testing.adoc b/_versions/main/guides/getting-started-testing.adoc index 663483c70f..849538d3e1 100644 --- a/_versions/main/guides/getting-started-testing.adoc +++ b/_versions/main/guides/getting-started-testing.adoc @@ -11,6 +11,7 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: getting-started,testing,tooling Learn how to test your Quarkus Application. @@ -426,7 +427,7 @@ Alternatively or additionally to an interceptor, you can enrich *all* your `@Qua * `io.quarkus.test.junit.callback.QuarkusTestAfterTestExecutionCallback` * `io.quarkus.test.junit.callback.QuarkusTestAfterEachCallback` -Optionally, you can enable these callbacks also for the `@QuarkusIntegrationTest` tests if the property `quarkus.test.enable-callbacks-for-integration-tests` is `true`. +Optionally, you can enable these callbacks also for the `@QuarkusIntegrationTest` tests if the property `quarkus.test.enable-callbacks-for-integration-tests` is `true`. Such a callback implementation has to be registered as a "service provider" as defined by `java.util.ServiceLoader`. @@ -1536,8 +1537,8 @@ public class Foo { @Inject Charlie charlie; <2> - - @ConfigProperty(name = "bar") + + @ConfigProperty(name = "bar") boolean bar; <3> public String ping() { @@ -1622,16 +1623,16 @@ public class FooTest { So what exactly does the `QuarkusComponentTest` do? It starts the CDI container and registers a dedicated xref:config-reference.adoc[configuration object]. -If the test instance lifecycle is `Lifecycle#PER_METHOD` (default) then the container is started during the `before each` test phase and stopped during the `after each` test phase. -However, if the test instance lifecycle is `Lifecycle#PER_CLASS` then the container is started during the `before all` test phase and stopped during the `after all` test phase. +If the test instance lifecycle is `Lifecycle#PER_METHOD` (default) then the container is started during the `before each` test phase and stopped during the `after each` test phase. +However, if the test instance lifecycle is `Lifecycle#PER_CLASS` then the container is started during the `before all` test phase and stopped during the `after all` test phase. The fields annotated with `@Inject` and `@InjectMock` are injected after a test instance is created. Finally, the CDI request context is activated and terminated per each test method. === Auto Mocking Unsatisfied Dependencies -Unlike in regular CDI environments the test does not fail if a component injects an unsatisfied dependency. +Unlike in regular CDI environments the test does not fail if a component injects an unsatisfied dependency. Instead, a synthetic bean is registered automatically for each combination of required type and qualifiers of an injection point that resolves to an unsatisfied dependency. -The bean has the `@Singleton` scope so it's shared across all injection points with the same required type and qualifiers. +The bean has the `@Singleton` scope so it's shared across all injection points with the same required type and qualifiers. The injected reference is an _unconfigured_ Mockito mock. You can inject the mock in your test and leverage the Mockito API to configure the behavior. @@ -1648,6 +1649,8 @@ If you only need to use the default values for missing config properties, then t It is also possible to set configuration properties for a test method with the `@io.quarkus.test.component.TestConfigProperty` annotation. However, if the test instance lifecycle is `Lifecycle#_PER_CLASS` this annotation can only be used on the test class and is ignored on test methods. +CDI beans are also automatically registered for all injected https://smallrye.io/smallrye-config/Main/config/mappings/[Config Mappings]. The mappings are populated with the test configuration properties. + === Mocking CDI Interceptors If a tested component class declares an interceptor binding then you might need to mock the interception too. @@ -1672,17 +1675,17 @@ public class FooTest { public void testPing() { assertEquals("OK", foo.ping()); } - + @ApplicationScoped static class Foo { - + @SimpleBinding <1> String ping() { return "ok"; } - + } - + @SimpleBinding @Interceptor static class SimpleInterceptor { <2> @@ -1730,14 +1733,14 @@ public class FooTest { @ApplicationScoped static class Foo { - + @SimpleBinding <1> String ping() { return "ok"; } - + } } ---- -<1> The interceptor bindings of the resulting interceptor are specified by annotating the method with the interceptor binding types. +<1> The interceptor bindings of the resulting interceptor are specified by annotating the method with the interceptor binding types. <2> Defines the interception type. diff --git a/_versions/main/guides/getting-started.adoc b/_versions/main/guides/getting-started.adoc index e3ec995872..525fff0d5e 100644 --- a/_versions/main/guides/getting-started.adoc +++ b/_versions/main/guides/getting-started.adoc @@ -10,6 +10,7 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: getting-started Learn how to create a Hello World Quarkus app. This guide covers: diff --git a/_versions/main/guides/gradle-tooling.adoc b/_versions/main/guides/gradle-tooling.adoc index 496c89aa7a..1cd29b37d3 100644 --- a/_versions/main/guides/gradle-tooling.adoc +++ b/_versions/main/guides/gradle-tooling.adoc @@ -9,6 +9,7 @@ include::_attributes.adoc[] :categories: tooling, native :summary: Develop and build your Quarkus application with Gradle :devtools-no-maven: +:topics: gradle,tooling Use Gradle to create a new project, add or remove extensions, launch development mode, debug your application, and build your application into a jar, native executable, or container-friendly executable. Import your project into your favorite IDE using Gradle project metadata. diff --git a/_versions/main/guides/grpc-getting-started.adoc b/_versions/main/guides/grpc-getting-started.adoc index a3a4d78838..de5f5cda75 100644 --- a/_versions/main/guides/grpc-getting-started.adoc +++ b/_versions/main/guides/grpc-getting-started.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: serialization :summary: This guide explains how to start using gRPC in your Quarkus application. +:topics: grpc +:extensions: io.quarkus:quarkus-grpc This page explains how to start using gRPC in your Quarkus application. While this page describes how to configure it with Maven, it is also possible to use Gradle. @@ -229,7 +231,7 @@ Further docs explain how to enable and use each of them. Now that we have the generated classes let's implement our _hello_ service. -With Quarkus, implementing a service requires to implement the generated service interface based on Mutiny, a Reactive Programming API integrated in Quarkus, and expose it as a CDI bean. +With Quarkus, implementing a service requires to implement the generated service interface based on Mutiny, a Reactive Programming API integrated in Quarkus, and expose it as a CDI bean. Learn more about Mutiny on the xref:mutiny-primer.adoc[Mutiny guide]. The service class must be annotated with the `@io.quarkus.grpc.GrpcService` annotation. diff --git a/_versions/main/guides/grpc-kubernetes.adoc b/_versions/main/guides/grpc-kubernetes.adoc index 638c063352..104c57d8b5 100644 --- a/_versions/main/guides/grpc-kubernetes.adoc +++ b/_versions/main/guides/grpc-kubernetes.adoc @@ -7,9 +7,11 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: serialization :summary: This guide explains how to deploy your gRPC services in Quarkus to Kubernetes. +:topics: grpc,kubernetes +:extensions: io.quarkus:quarkus-grpc,io.quarkus:quarkus-kubernetes -This page explains how to deploy your gRPC service in Quarkus in Kubernetes. -We'll continue with the example from xref:grpc-getting-started.adoc[the Getting Started gRPC guide]. +This page explains how to deploy your gRPC service in Quarkus in Kubernetes. +We'll continue with the example from xref:grpc-getting-started.adoc[the Getting Started gRPC guide]. == Configuring your project to use the Quarkus Kubernetes extension @@ -82,7 +84,7 @@ implementation("io.quarkus:quarkus-smallrye-health") TIP: More information about the health extension can be found in xref:microprofile-health.adoc[the Microprofile Health guide]. -By the default, this extension will configure the probes to use the HTTP server (which is provided by some extensions like the Quarkus RESTEasy reactive extension). Internally, this probe will also use xref:grpc-service-implementation.adoc#health[the generated gRPC Health services]. +By the default, this extension will configure the probes to use the HTTP server (which is provided by some extensions like the Quarkus RESTEasy reactive extension). Internally, this probe will also use xref:grpc-service-implementation.adoc#health[the generated gRPC Health services]. If your application does not use any Quarkus extension that exposes an HTTP server, you can still configure the probes to directly use the gRPC Health service by adding the property `quarkus.kubernetes.readiness-probe.grpc-action-enabled=true` into your configuration: diff --git a/_versions/main/guides/grpc-service-consumption.adoc b/_versions/main/guides/grpc-service-consumption.adoc index a05c32c1bd..4483f07f2d 100644 --- a/_versions/main/guides/grpc-service-consumption.adoc +++ b/_versions/main/guides/grpc-service-consumption.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: serialization :summary: This guide explains how to consume gRPC services in your Quarkus application. +:topics: grpc +:extensions: io.quarkus:quarkus-grpc gRPC clients can be injected in your application code. @@ -247,7 +249,7 @@ quarkus.grpc.clients.hello.ssl.trust-store=tls/ca.pem === Client Stub Deadlines If you need to configure a deadline for a gRPC stub, i.e. to specify a duration of time after which the stub will always return the status error `DEADLINE_EXCEEDED`. -You can specify the deadline via the `quarkus.grpc.clients."service-name".deadline` configuration property, e.g.: +You can specify the deadline via the `quarkus.grpc.clients."service-name".deadline` configuration property, e.g.: [source,properties] ---- diff --git a/_versions/main/guides/grpc-service-implementation.adoc b/_versions/main/guides/grpc-service-implementation.adoc index f49e1161ae..2d870aed2c 100644 --- a/_versions/main/guides/grpc-service-implementation.adoc +++ b/_versions/main/guides/grpc-service-implementation.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: serialization :summary: This guide explains how to implement gRPC services in your Quarkus application. +:topics: grpc +:extensions: io.quarkus:quarkus-grpc gRPC service implementations exposed as CDI beans are automatically registered and served by quarkus-grpc. diff --git a/_versions/main/guides/grpc-virtual-threads.adoc b/_versions/main/guides/grpc-virtual-threads.adoc index cfd6c9f618..0b3d657ddb 100644 --- a/_versions/main/guides/grpc-virtual-threads.adoc +++ b/_versions/main/guides/grpc-virtual-threads.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :runonvthread: https://javadoc.io/doc/io.smallrye.common/smallrye-common-annotation/latest/io/smallrye/common/annotation/RunOnVirtualThread.html :blocking_annotation: https://javadoc.io/doc/io.smallrye.reactive/smallrye-reactive-messaging-api/latest/io/smallrye/reactive/messaging/annotations/Blocking.html +:topics: grpc,virtual-threads +:extensions: io.quarkus:quarkus-grpc This guide explains how to benefit from Java virtual threads when implementing a gRPC service. diff --git a/_versions/main/guides/grpc-xds.adoc b/_versions/main/guides/grpc-xds.adoc index e073fe917f..da28d6f1d4 100644 --- a/_versions/main/guides/grpc-xds.adoc +++ b/_versions/main/guides/grpc-xds.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: serialization :summary: This page explains how to enable xDS gRPC usage in your Quarkus application. +:topics: grpc,xds +:extensions: io.quarkus:quarkus-grpc-xds This page explains how to enable xDS gRPC usage in your Quarkus application. diff --git a/_versions/main/guides/grpc.adoc b/_versions/main/guides/grpc.adoc index 7e6af77c5b..12c908ac2c 100644 --- a/_versions/main/guides/grpc.adoc +++ b/_versions/main/guides/grpc.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: serialization :summary: Entry point for everything gRPC. +:topics: grpc +:extensions: io.quarkus:quarkus-grpc,io.quarkus:quarkus-grpc-xds https://grpc.io/[gRPC] is a high-performance RPC framework. It can efficiently connect services implemented using various languages and frameworks. diff --git a/_versions/main/guides/hibernate-orm-panache-kotlin.adoc b/_versions/main/guides/hibernate-orm-panache-kotlin.adoc index 7625154010..8a45bc598b 100644 --- a/_versions/main/guides/hibernate-orm-panache-kotlin.adoc +++ b/_versions/main/guides/hibernate-orm-panache-kotlin.adoc @@ -8,13 +8,15 @@ include::_attributes.adoc[] :categories: data, alt-languages :summary: This explains the specifics of using Hibernate ORM with Panache in a Kotlin project. :config-file: application.properties +:topics: data,hibernate-orm,panache,kotlin,sql,jdbc +:extensions: io.quarkus:quarkus-hibernate-orm-panache-kotlin,io.quarkus:quarkus-hibernate-orm-panache,io.quarkus:quarkus-hibernate-orm Hibernate ORM is the de facto standard Jakarta Persistence (formerly known as JPA) implementation and is well-known in the Java ecosystem. Hibernate ORM with Panache offers a new layer atop this familiar framework. This guide will not dive in to the specifics of either as those are already covered in the xref:hibernate-orm-panache.adoc[Hibernate ORM with Panache guide]. In this guide, we'll cover the Kotlin specific changes needed to use Hibernate ORM with Panache in your Kotlin-based Quarkus applications. -NOTE: When using the kotlin version of Hibernate ORM with Panache, note that the `PanacheEntity`, `PanacheQuery` and `PanacheRepository` are in a different package: `io.quarkus.hibernate.orm.panache.kotlin`. +NOTE: When using the Kotlin version of Hibernate ORM with Panache, note that the `PanacheEntity`, `PanacheQuery` and `PanacheRepository` are in a different package: `io.quarkus.hibernate.orm.panache.kotlin`. == First: an example diff --git a/_versions/main/guides/hibernate-orm-panache.adoc b/_versions/main/guides/hibernate-orm-panache.adoc index a26c101fd1..6377bc904f 100644 --- a/_versions/main/guides/hibernate-orm-panache.adoc +++ b/_versions/main/guides/hibernate-orm-panache.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: data :summary: Hibernate ORM is the de facto Jakarta Persistence implementation and offers you the full breadth of an Object Relational Mapper. It makes complex mappings possible, but it does not make simple and common mappings trivial. Panache focuses on making your entities trivial and fun to write. :config-file: application.properties +:topics: data,hibernate-orm,panache,sql,jdbc +:extensions: io.quarkus:quarkus-hibernate-orm-panache,io.quarkus:quarkus-hibernate-orm Hibernate ORM is the de facto Jakarta Persistence (formerly known as JPA) implementation and offers you the full breadth of an Object Relational Mapper. It makes complex mappings possible, but it does not make simple and common mappings trivial. @@ -944,7 +946,7 @@ matching the values returned by the select clause: ---- import io.quarkus.runtime.annotations.RegisterForReflection; -@RegisterForReflection +@RegisterForReflection public class RaceWeight { public final String race; public final Double weight; @@ -1198,7 +1200,7 @@ public class PanacheFunctionalityTest { // We can even mock your custom methods Mockito.when(Person.findOrdered()).thenReturn(Collections.emptyList()); Assertions.assertTrue(Person.findOrdered().isEmpty()); - + // Mocking a void method Person.voidMethod(); diff --git a/_versions/main/guides/hibernate-orm.adoc b/_versions/main/guides/hibernate-orm.adoc index 48933c0770..3390dd8c02 100644 --- a/_versions/main/guides/hibernate-orm.adoc +++ b/_versions/main/guides/hibernate-orm.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: data :summary: Hibernate ORM is the de facto Jakarta Persistence implementation and offers you the full breath of an Object Relational Mapper. It works beautifully in Quarkus. :config-file: application.properties +:topics: data,hibernate-orm,sql,jdbc +:extensions: io.quarkus:quarkus-hibernate-orm Hibernate ORM is the de facto standard Jakarta Persistence (formerly known as JPA) implementation and offers you the full breadth of an Object Relational Mapper. It works beautifully in Quarkus. @@ -944,7 +946,7 @@ public class FruitResource { return entityManager.createNamedQuery("Fruits.findAll", Fruit.class) .getResultList().toArray(new Fruit[0]); } - + } ---- @@ -968,7 +970,7 @@ public class CustomTenantResolver implements TenantResolver { public String getDefaultTenantId() { return "base"; } - + @Override public String resolveTenantId() { String path = context.request().path(); @@ -981,7 +983,7 @@ public class CustomTenantResolver implements TenantResolver { return parts[1]; } - + } ---- <1> Annotate the TenantResolver implementation with the `@PersistenceUnitExtension` qualifier @@ -1026,7 +1028,7 @@ The following setup will use the xref:flyway.adoc[Flyway] extension to achieve t ==== SCHEMA approach The same data source will be used for all tenants and a schema has to be created for every tenant inside that data source. -CAUTION: Some databases like MariaDB/MySQL do not support database schemas. In these cases you have to use the DATABASE approach below. +CAUTION: Some databases like MariaDB/MySQL do not support database schemas. In these cases you have to use the DATABASE approach below. [source,properties] ---- @@ -1035,7 +1037,7 @@ quarkus.hibernate-orm.database.generation=none # Enable SCHEMA approach and use default datasource quarkus.hibernate-orm.multitenant=SCHEMA -# You could use a non-default datasource by using the following setting +# You could use a non-default datasource by using the following setting # quarkus.hibernate-orm.multitenant-schema-datasource=other # The default data source used for all tenant schemas @@ -1081,7 +1083,7 @@ INSERT INTO mycompany.known_fruits(id, name) VALUES (3, 'Blackberries'); ==== DATABASE approach -For every tenant you need to create a named data source with the same identifier that is returned by the `TenantResolver`. +For every tenant you need to create a named data source with the same identifier that is returned by the `TenantResolver`. [source,properties] ---- diff --git a/_versions/main/guides/hibernate-reactive-panache.adoc b/_versions/main/guides/hibernate-reactive-panache.adoc index 7ba55fe448..37ce51721a 100644 --- a/_versions/main/guides/hibernate-reactive-panache.adoc +++ b/_versions/main/guides/hibernate-reactive-panache.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: data :summary: Simplified reactive ORM layer based on Hibernate Reactive. :config-file: application.properties +:topics: data,hibernate-reactive,panache,sql +:extensions: io.quarkus:quarkus-hibernate-reactive-panache,io.quarkus:quarkus-hibernate-reactive link:https://hibernate.org/reactive/[Hibernate Reactive] is the only reactive Jakarta Persistence (formerly known as JPA) implementation and offers you the full breadth of an Object Relational Mapper allowing you to access your database over reactive drivers. diff --git a/_versions/main/guides/hibernate-reactive.adoc b/_versions/main/guides/hibernate-reactive.adoc index 6127b7a779..e5ae2678fd 100644 --- a/_versions/main/guides/hibernate-reactive.adoc +++ b/_versions/main/guides/hibernate-reactive.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :config-file: application.properties :reactive-doc-url-prefix: https://hibernate.org/reactive/documentation/1.1/reference/html_single/#getting-started :extension-status: preview +:topics: data,hibernate-reactive,sql +:extensions: io.quarkus:quarkus-hibernate-reactive-panache,io.quarkus:quarkus-hibernate-reactive link:https://hibernate.org/reactive/[Hibernate Reactive] is a reactive API for Hibernate ORM, supporting non-blocking database drivers and a reactive style of interaction with the database. diff --git a/_versions/main/guides/hibernate-search-orm-elasticsearch.adoc b/_versions/main/guides/hibernate-search-orm-elasticsearch.adoc index 7e5a2757f2..a24b1221ac 100644 --- a/_versions/main/guides/hibernate-search-orm-elasticsearch.adoc +++ b/_versions/main/guides/hibernate-search-orm-elasticsearch.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: Hibernate Search allows you to index your entities in an Elasticsearch cluster and easily offer full text search in all your Hibernate ORM-based applications. +:topics: data,hibernate-search,elasticsearch,search,nosql +:extensions: io.quarkus:quarkus-hibernate-search-orm-elasticsearch You have a Hibernate ORM-based application? You want to provide a full-featured full-text search to your users? You're at the right place. diff --git a/_versions/main/guides/http-reference.adoc b/_versions/main/guides/http-reference.adoc index 642c75c921..763ea0fae4 100644 --- a/_versions/main/guides/http-reference.adoc +++ b/_versions/main/guides/http-reference.adoc @@ -10,7 +10,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 - +:topics: http,web,webjars,vertx,servlet,undertow +:extensions: io.quarkus:quarkus-vertx-http This document explains various HTTP features that you can use in Quarkus. diff --git a/_versions/main/guides/ide-tooling.adoc b/_versions/main/guides/ide-tooling.adoc index 6ab775495c..d9531c3980 100644 --- a/_versions/main/guides/ide-tooling.adoc +++ b/_versions/main/guides/ide-tooling.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: getting-started :summary: Learn more about Quarkus integrations in IDEs. +:topics: ide,tooling The following IDEs have support for the community developed Quarkus Tools: diff --git a/_versions/main/guides/infinispan-client-reference.adoc b/_versions/main/guides/infinispan-client-reference.adoc index a6fcee3da0..6a49859d9c 100644 --- a/_versions/main/guides/infinispan-client-reference.adoc +++ b/_versions/main/guides/infinispan-client-reference.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: Infinispan is an in memory distributed data store and cache server that offers flexible deployment options and robust capabilities for storing, managing, and processing data. +:topics: data,infinispan +:extensions: io.quarkus:quarkus-infinispan-client Infinispan is a distributed, in-memory key/value store that provides Quarkus applications with a highly configurable and independently scalable data layer. diff --git a/_versions/main/guides/infinispan-client.adoc b/_versions/main/guides/infinispan-client.adoc index f787de4bd2..06e08e5624 100644 --- a/_versions/main/guides/infinispan-client.adoc +++ b/_versions/main/guides/infinispan-client.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: This guide covers how to use Infinispan with Quarkus. +:topics: data,infinispan +:extensions: io.quarkus:quarkus-infinispan-client This guide demonstrates how your Quarkus application can connect to an Infinispan server using the Infinispan Client extension. diff --git a/_versions/main/guides/infinispan-dev-services.adoc b/_versions/main/guides/infinispan-dev-services.adoc index 138ed82b84..5ea1b1dbb5 100644 --- a/_versions/main/guides/infinispan-dev-services.adoc +++ b/_versions/main/guides/infinispan-dev-services.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: Start Infinispan automatically in dev and test modes. +:topics: devservices,data,infinispan,tooling,testing,devmode +:extensions: io.quarkus:quarkus-infinispan-client Quarkus supports a feature called Dev Services that allows you to create various datasources without any config. If you have docker running and have not configured `quarkus.infinispan-client.hosts`, diff --git a/_versions/main/guides/init-tasks.adoc b/_versions/main/guides/init-tasks.adoc index 082214330c..b29a45a398 100644 --- a/_versions/main/guides/init-tasks.adoc +++ b/_versions/main/guides/init-tasks.adoc @@ -6,6 +6,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Initialization tasks :categories: initialization :summary: This reference guide explains how to configure initialization tasks +:topics: init,kubernetes,openshift,liquibase,flyway +:extensions: io.quarkus:quarkus-kubernetes,io.quarkus:quarkus-openshift,io.quarkus:quarkus-flyway,io.quarkus:quarkus-liquibase There are often initialization tasks performed by Quarkus extensions that are meant to be run once. For example, Flyway or Liquibase initialization falls into that category. But what happens when the scaling @@ -13,8 +15,8 @@ needs of an application requires more instances of the application to run? Or wh restarts ? A common environment where both of these cases are pretty common is Kubernetes. To address these challenges, -Quarkus allows externalization of such tasks as Kubernetes https://kubernetes.io/docs/concepts/workloads/controllers/job/[Jobs] and uses https://kubernetes.io/docs/concepts/workloads/pods/init-containers/[init containers] to ensure that an -application instance only starts once the initialization jobs have finished. With this approach even if an +Quarkus allows externalization of such tasks as Kubernetes https://kubernetes.io/docs/concepts/workloads/controllers/job/[Jobs] and uses https://kubernetes.io/docs/concepts/workloads/pods/init-containers/[init containers] to ensure that an +application instance only starts once the initialization jobs have finished. With this approach even if an application has multiple replicas, the initialization logic will only run once. This approach is reflected in the manifests generated by xref:kubernetes.adoc[Kubernetes extension]. @@ -36,7 +38,7 @@ or on Openshift: quarkus.openshift.init-task-defaults.enabled=false ---- -**Note**: All the configuration options in this guide are available on both OpenShift and Kubernetes. The rest of the guide will use Kubernetes(`quarkus.kubernetes` prefix) +**Note**: All the configuration options in this guide are available on both OpenShift and Kubernetes. The rest of the guide will use Kubernetes(`quarkus.kubernetes` prefix) configuration prefix, but all the configuration options are also available for OpenShift(`quarkus.openshift` prefix) too. In the case where we need to disable a particular task, we can use the following property: @@ -131,11 +133,11 @@ quarkus.kubernetes.init-containers.wait-for-flyway=my/wait-for-image:1.0 === Configuring permissions For an init container to be able to perform the `wait for job` it needs to be able to perform `get` operations on the job resource. -This is done automatically and the generated manifests include the required `Role` and `RoleBinding` resources. +This is done automatically and the generated manifests include the required `Role` and `RoleBinding` resources. If for any reason additional permissions are required either by the init container or the job, they can be configured with through the xref:deploying-to-kuberentes.adoc#generating-rbac-resources[Kubernetes RBAC configuration]. -**Note**: The application, the init container and the job use the same `ServiceAccount` and therefore, share the same permissions. +**Note**: The application, the init container and the job use the same `ServiceAccount` and therefore, share the same permissions. == Extension providing Initialization Tasks diff --git a/_versions/main/guides/jms.adoc b/_versions/main/guides/jms.adoc index 384ba24334..a101e261d6 100644 --- a/_versions/main/guides/jms.adoc +++ b/_versions/main/guides/jms.adoc @@ -8,7 +8,8 @@ include::_attributes.adoc[] :categories: messaging :summary: This guide demonstrates how your Quarkus application can use JMS messaging with AMQP 1.0 using Apache Qpid JMS, or using Apache ActiveMQ Artemis JMS. :extension-status: preview - +:topics: messaging,jms,artemis,qpid,activemq +:extensions: org.amqphub.quarkus:quarkus-qpid-jms,io.quarkiverse.artemis:quarkus-artemis-jms This guide demonstrates how your Quarkus application can use JMS messaging via the Apache Qpid JMS AMQP client, or alternatively the Apache ActiveMQ Artemis JMS client. diff --git a/_versions/main/guides/jreleaser.adoc b/_versions/main/guides/jreleaser.adoc index 6a1ae287f2..afe40f060f 100644 --- a/_versions/main/guides/jreleaser.adoc +++ b/_versions/main/guides/jreleaser.adoc @@ -10,6 +10,7 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: tooling This guide covers packaging and releasing CLI applications using the link:https://jreleaser.org[JReleaser] tool. diff --git a/_versions/main/guides/kafka-dev-services.adoc b/_versions/main/guides/kafka-dev-services.adoc index e48283d851..b6d32ba55e 100644 --- a/_versions/main/guides/kafka-dev-services.adoc +++ b/_versions/main/guides/kafka-dev-services.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: messaging :summary: Start Apache Kafka automatically in dev and test modes. +:topics: messaging,kafka,devservices,tooling,testing,devmode +:extensions: io.quarkus:quarkus-kafka-client,io.quarkus:quarkus-smallrye-reactive-messaging-kafka If any Kafka-related extension is present (e.g. `quarkus-smallrye-reactive-messaging-kafka`), Dev Services for Kafka automatically starts a Kafka broker in dev mode and when running tests. So, you don't have to start a broker manually. diff --git a/_versions/main/guides/kafka-dev-ui.adoc b/_versions/main/guides/kafka-dev-ui.adoc index 049c884fd9..2625df6a7e 100644 --- a/_versions/main/guides/kafka-dev-ui.adoc +++ b/_versions/main/guides/kafka-dev-ui.adoc @@ -7,8 +7,10 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: messaging :summary: Dev UI extension for Apache Kafka for development purposes. +:topics: messaging,kafka,dev-ui,devmode +:extensions: io.quarkus:quarkus-kafka-client,io.quarkus:quarkus-smallrye-reactive-messaging-kafka -If any Kafka-related extension is present (e.g. `quarkus-smallrye-reactive-messaging-kafka`), +If any Kafka-related extension is present (e.g. `quarkus-smallrye-reactive-messaging-kafka`), the Quarkus Dev UI is extended with a Kafka broker management UI. It is connected automatically to the Kafka broker configured for the application. diff --git a/_versions/main/guides/kafka-reactive-getting-started.adoc b/_versions/main/guides/kafka-reactive-getting-started.adoc index 90f3234693..cb4c541a3c 100644 --- a/_versions/main/guides/kafka-reactive-getting-started.adoc +++ b/_versions/main/guides/kafka-reactive-getting-started.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: messaging :summary: This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with Apache Kafka. +:topics: messaging,kafka,reactive-messaging +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-kafka This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with Apache Kafka. diff --git a/_versions/main/guides/kafka-schema-registry-avro.adoc b/_versions/main/guides/kafka-schema-registry-avro.adoc index daba110ca8..36713441af 100644 --- a/_versions/main/guides/kafka-schema-registry-avro.adoc +++ b/_versions/main/guides/kafka-schema-registry-avro.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: messaging :summary: Use Apache Kafka, Avro serialized records, and connect to a schema registry. +:topics: messaging,kafka,apicurio,registry +:extensions: io.quarkus:quarkus-apicurio-registry-avro,io.quarkus:quarkus-smallrye-reactive-messaging-kafka This guide shows how your Quarkus application can use Apache Kafka, https://avro.apache.org/docs/current/[Avro] serialized records, and connect to a schema registry (such as the https://docs.confluent.io/platform/current/schema-registry/index.html[Confluent Schema Registry] or https://www.apicur.io/registry/[Apicurio Registry]). diff --git a/_versions/main/guides/kafka-streams.adoc b/_versions/main/guides/kafka-streams.adoc index 9c832ac6ca..e5cc5fa70d 100644 --- a/_versions/main/guides/kafka-streams.adoc +++ b/_versions/main/guides/kafka-streams.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: messaging :summary: This guide demonstrates how your Quarkus application can utilize the Apache Kafka Streams API to implement stream processing applications based on Apache Kafka. +:topics: messaging,kafka,kafka-streams +:extensions: io.quarkus:quarkus-kafka-streams This guide demonstrates how your Quarkus application can utilize the Apache Kafka Streams API to implement stream processing applications based on Apache Kafka. @@ -466,7 +468,7 @@ TIP: Alternatively, you can use `kafka.bootstrap.servers` instead of `quarkus.ka [NOTE] ==== -Once you are ready to promote your application into production, consider changing the above configuration values. While `cache.max.bytes.buffering=10240` will move your records faster through the topology, the default value of `10485760` is more throughput-friendly. Also condider increasing `metadata.max.age.ms` from `500`, which will update cluster metadata quickly, but will generate a lot of redundant requests, to a value closer to the default of `300000`. A `commit.interval.ms` of `1000` is good for exactly-once processing, but might generate excessive load for the default at-least-once processing with the default value of `30000`. +Once you are ready to promote your application into production, consider changing the above configuration values. While `cache.max.bytes.buffering=10240` will move your records faster through the topology, the default value of `10485760` is more throughput-friendly. Also condider increasing `metadata.max.age.ms` from `500`, which will update cluster metadata quickly, but will generate a lot of redundant requests, to a value closer to the default of `300000`. A `commit.interval.ms` of `1000` is good for exactly-once processing, but might generate excessive load for the default at-least-once processing with the default value of `30000`. ==== All the properties within the `kafka-streams` namespace are passed through as-is to the Kafka Streams engine. diff --git a/_versions/main/guides/kafka.adoc b/_versions/main/guides/kafka.adoc index 01c6215374..41160e03eb 100644 --- a/_versions/main/guides/kafka.adoc +++ b/_versions/main/guides/kafka.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: messaging,kafka,reactive-messaging +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-kafka This reference guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with Apache Kafka. @@ -350,12 +352,12 @@ If `throttled.unprocessed-record-max-age.ms` is set to less than or equal to `0` Such a setting might lead to running out of memory if there are "poison pill" messages (that are never acked). This strategy is the default if `enable.auto.commit` is not explicitly set to true. -- `checkpoint` allows persisting consumer offsets on a **state store**, instead of committing them back to the Kafka broker. -Using the `CheckpointMetadata` API, consumer code can persist a _processing state_ with the record offset to mark the progress of a consumer. -When the processing continues from a previously persisted offset, it seeks the Kafka consumer to that offset and also restores the persisted state, continuing the stateful processing from where it left off. -The checkpoint strategy holds locally the processing state associated with the latest offset, and persists it periodically to the state store (period specified by `auto.commit.interval.ms` (default: 5000)). -The connector will be marked as unhealthy if no processing state is persisted to the state store in `checkpoint.unsynced-state-max-age.ms` (default: 10000). -If `checkpoint.unsynced-state-max-age.ms` is set to less than or equal to 0, it does not perform any health check verification. +- `checkpoint` allows persisting consumer offsets on a **state store**, instead of committing them back to the Kafka broker. +Using the `CheckpointMetadata` API, consumer code can persist a _processing state_ with the record offset to mark the progress of a consumer. +When the processing continues from a previously persisted offset, it seeks the Kafka consumer to that offset and also restores the persisted state, continuing the stateful processing from where it left off. +The checkpoint strategy holds locally the processing state associated with the latest offset, and persists it periodically to the state store (period specified by `auto.commit.interval.ms` (default: 5000)). +The connector will be marked as unhealthy if no processing state is persisted to the state store in `checkpoint.unsynced-state-max-age.ms` (default: 10000). +If `checkpoint.unsynced-state-max-age.ms` is set to less than or equal to 0, it does not perform any health check verification. For more information, see xref:stateful-processing-checkpointing[Stateful processing with Checkpointing] - `latest` commits the record offset received by the Kafka consumer as soon as the associated message is acknowledged (if the offset is higher than the previously committed offset). @@ -713,17 +715,17 @@ The `checkpoint` commit strategy is an experimental feature and can change in th ==== Smallrye Reactive Messaging `checkpoint` commit strategy allows consumer applications to process messages in a stateful manner, while also respecting Kafka consumer scalability. -An incoming channel with `checkpoint` commit strategy persists consumer offsets on an external +An incoming channel with `checkpoint` commit strategy persists consumer offsets on an external xref:state-stores[state store], such as a relational database or a key-value store. -As a result of processing consumed records, the consumer application can accumulate an internal state for each topic-partition assigned to the Kafka consumer. +As a result of processing consumed records, the consumer application can accumulate an internal state for each topic-partition assigned to the Kafka consumer. This local state will be periodically persisted to the state store and will be associated with the offset of the record that produced it. -This strategy does not commit any offsets to the Kafka broker, so when new partitions get assigned to the consumer, -i.e. consumer restarts or consumer group instances scale, +This strategy does not commit any offsets to the Kafka broker, so when new partitions get assigned to the consumer, +i.e. consumer restarts or consumer group instances scale, the consumer resumes the processing from the latest _checkpointed_ offset with its saved state. The `@Incoming` channel consumer code can manipulate the processing state through the `CheckpointMetadata` API. -For example, a consumer calculating the moving average of prices received on a Kafka topic would look the following: +For example, a consumer calculating the moving average of prices received on a Kafka topic would look the following: [source,java] ---- @@ -746,20 +748,20 @@ public class MeanCheckpointConsumer { public CompletionStage consume(Message record) { // Get the `CheckpointMetadata` from the incoming message CheckpointMetadata checkpoint = CheckpointMetadata.fromMessage(record); - + // `CheckpointMetadata` allows transforming the processing state // Applies the given function, starting from the value `0.0` when no previous state exists checkpoint.transform(new AveragePrice(), average -> average.update(record.getPayload()), /* persistOnAck */ true); - + // `persistOnAck` flag set to true, ack will persist the processing state // associated with the latest offset (per partition). return record.ack(); } - + static class AveragePrice { long count; double mean; - + AveragePrice update(double newPrice) { mean += ((newPrice - mean) / ++count); return this; @@ -768,25 +770,25 @@ public class MeanCheckpointConsumer { } ---- -The `transform` method applies the transformation function to the current state, producing a changed state and registering it locally for checkpointing. -By default, the local state is persisted to the state store periodically, period specified by `auto.commit.interval.ms`, (default: 5000). -If `persistOnAck` flag is given, the latest state is persisted to the state store eagerly on message acknowledgment. +The `transform` method applies the transformation function to the current state, producing a changed state and registering it locally for checkpointing. +By default, the local state is persisted to the state store periodically, period specified by `auto.commit.interval.ms`, (default: 5000). +If `persistOnAck` flag is given, the latest state is persisted to the state store eagerly on message acknowledgment. The `setNext` method works similarly directly setting the latest state. -The checkpoint commit strategy tracks when a processing state is last persisted for each topic-partition. +The checkpoint commit strategy tracks when a processing state is last persisted for each topic-partition. If an outstanding state change can not be persisted for `checkpoint.unsynced-state-max-age.ms` (default: 10000), the channel is marked unhealthy. [[state-stores]] ==== State stores -State store implementations determine where and how the processing states are persisted. +State store implementations determine where and how the processing states are persisted. This is configured by the `mp.messaging.incoming.[channel-name].checkpoint.state-store` property. -The serialization of state objects depends on the state store implementation. +The serialization of state objects depends on the state store implementation. In order to instruct state stores for serialization can require configuring the class name of state objects using `mp.messaging.incoming.[channel-name].checkpoint.state-type` property. Quarkus provides following state store implementations: -- `quarkus-redis`: Uses the xref:redis-reference.adoc[`quarkus-redis-client`] extension to persist processing states. +- `quarkus-redis`: Uses the xref:redis-reference.adoc[`quarkus-redis-client`] extension to persist processing states. Jackson is used to serialize processing state in Json. For complex objects it is required to configure the `checkpoint.state-type` property with the class name of the object. By default, the state store uses the default redis client, but if a xref:redis-reference.adoc#default-and-named-clients[named client] is to be used, the client name can be specified using the `mp.messaging.incoming.[channel-name].checkpoint.quarkus-redis.client-name` property. Processing states will be stored in Redis using the key naming scheme `[consumer-group-id]:[topic]:[partition]`. @@ -807,8 +809,8 @@ quarkus.redis.my-redis.hosts=redis://localhost:7000 quarkus.redis.my-redis.password= ---- -- `quarkus-hibernate-reactive`: Uses the xref:hibernate-reactive.adoc[`quarkus-hibernate-reactive`] extension to persist processing states. -Processing state objects are required to be a Jakarta Persistence entity and extend the `CheckpointEntity` class, +- `quarkus-hibernate-reactive`: Uses the xref:hibernate-reactive.adoc[`quarkus-hibernate-reactive`] extension to persist processing states. +Processing state objects are required to be a Jakarta Persistence entity and extend the `CheckpointEntity` class, which handles object identifiers composed of the consumer group id, topic and partition. Therefore, the class name of the entity needs to be configured using the `checkpoint.state-type` property. @@ -846,7 +848,7 @@ public class AveragePriceEntity extends CheckpointEntity { ---- - `quarkus-hibernate-orm`: Uses the xref:hibernate-orm.adoc[`quarkus-hibernate-orm`] extension to persist processing states. -It is similar to the previous state store, but it uses Hibernate ORM instead of Hibernate Reactive. +It is similar to the previous state store, but it uses Hibernate ORM instead of Hibernate Reactive. When configured, it can use a named `persistence-unit` for the checkpointing state store: @@ -865,7 +867,7 @@ quarkus.hibernate-orm."prices".datasource=prices quarkus.hibernate-orm."prices".packages=org.acme ---- -For instructions on how to implement custom state stores, +For instructions on how to implement custom state stores, see https://smallrye.io/smallrye-reactive-messaging/3.22.0/kafka/receiving-kafka-records/#implementing-state-stores[Implementing State Stores]. == Sending messages to Kafka @@ -2690,9 +2692,9 @@ public class FruitStore { } ---- <1> Inject the Hibernate Reactive `Session` -<2> Hibernate Reactive `Session` and `Panache` APIs require an active CDI Request context. +<2> Hibernate Reactive `Session` and `Panache` APIs require an active CDI Request context. `@ActivateRequestContext` annotation creates a new request context and destroys it when the `Uni` returned from the method completes. -If `Panache` is not used, `Mutiny.SessionFactory` can be injected and used similarly without the need of activating the request context or closing the session manually. +If `Panache` is not used, `Mutiny.SessionFactory` can be injected and used similarly without the need of activating the request context or closing the session manually. <3> Requests a new transaction. The transaction completes when the passed action completes. <4> Persist the entity. It returns a `Uni`. <5> Switch back to a `Uni`. diff --git a/_versions/main/guides/kotlin.adoc b/_versions/main/guides/kotlin.adoc index 17ef00743b..644dbb9717 100644 --- a/_versions/main/guides/kotlin.adoc +++ b/_versions/main/guides/kotlin.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: alt-languages :summary: This guide explains how to use Kotlin. +:topics: kotlin +:extensions: io.quarkus:quarkus-kotlin https://kotlinlang.org/[Kotlin] is a very popular programming language that targets the JVM (amongst other environments). Kotlin has experienced a surge in popularity the last few years making it the most popular JVM language, except for Java of course. diff --git a/_versions/main/guides/kubernetes-client.adoc b/_versions/main/guides/kubernetes-client.adoc index ca75c11fc8..6dcaeb4182 100644 --- a/_versions/main/guides/kubernetes-client.adoc +++ b/_versions/main/guides/kubernetes-client.adoc @@ -7,7 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: This guide demonstrates how to use the Fabric8 Kubernetes client to interact with your Kubernetes cluster. - +:topics: kubernetes,openshift,kubernetes-client +:extensions: io.quarkus:quarkus-kubernetes-client Quarkus includes the `kubernetes-client` extension which enables the use of the https://github.com/fabric8io/kubernetes-client[Fabric8 Kubernetes Client] in native mode while also making it easier to work with. diff --git a/_versions/main/guides/kubernetes-config.adoc b/_versions/main/guides/kubernetes-config.adoc index b824b17d4e..0654b09431 100644 --- a/_versions/main/guides/kubernetes-config.adoc +++ b/_versions/main/guides/kubernetes-config.adoc @@ -7,7 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: Use ConfigMaps as a configuration source for your Quarkus applications. - +:topics: kubernetes,openshift,configuration,configmap +:extensions: io.quarkus:quarkus-kubernetes-config Quarkus includes the `kubernetes-config` extension which allows developers to use Kubernetes https://cloud.google.com/kubernetes-engine/docs/concepts/configmap[ConfigMaps] and https://cloud.google.com/kubernetes-engine/docs/concepts/secret[Secrets] as a configuration source, without having to mount them into the https://kubernetes.io/docs/concepts/workloads/pods/pod/[Pod] running the Quarkus application or make any other modifications to their Kubernetes `Deployment` (or OpenShift `DeploymentConfig`). diff --git a/_versions/main/guides/kubernetes-dev-services.adoc b/_versions/main/guides/kubernetes-dev-services.adoc index 15e23210c6..bd2e9bfa0e 100644 --- a/_versions/main/guides/kubernetes-dev-services.adoc +++ b/_versions/main/guides/kubernetes-dev-services.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: cloud :summary: Start a Kubernetes API server automatically in dev and test modes. +:topics: devservices,kubernetes,tooling,testing,devmode +:extensions: io.quarkus:quarkus-kubernetes-client Dev Services for Kubernetes automatically starts a Kubernetes API server in dev mode and when running tests. So you don't have to start a Kubernetes cluster manually. @@ -19,7 +21,7 @@ Dev Services for Kubernetes is automatically enabled unless: - `quarkus.kubernetes-client.devservices.enabled` is set to `false` - the `api-server-url` is configured - a valid Kube config file is found and `quarkus.kubernetes-client.devservices.override-kubeconfig` is not set to `true` -- you include the `quarkus-test-kubernetes-client` dependency +- you include the `quarkus-test-kubernetes-client` dependency Dev Services for Kubernetes relies on Docker to start the API server. If your environment does not support Docker, you will need to start the Kubernetes cluster manually, or connect to an already running Kubernetes cluster. diff --git a/_versions/main/guides/lifecycle.adoc b/_versions/main/guides/lifecycle.adoc index 400cdc552b..539b59006b 100644 --- a/_versions/main/guides/lifecycle.adoc +++ b/_versions/main/guides/lifecycle.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: core :keywords: lifecycle event :summary: You often need to execute custom actions when the application starts and clean up everything when the application stops. This guide explains how to be notified when an application stops or starts. +:topics: lifecycle,observers +:extensions: io.quarkus:quarkus-core,io.quarkus:quarkus-arc You often need to execute custom actions when the application starts and clean up everything when the application stops. This guide explains how to: diff --git a/_versions/main/guides/liquibase-mongodb.adoc b/_versions/main/guides/liquibase-mongodb.adoc index a9e37fcab7..81c112257a 100644 --- a/_versions/main/guides/liquibase-mongodb.adoc +++ b/_versions/main/guides/liquibase-mongodb.adoc @@ -5,8 +5,11 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Using Liquibase MongoDB include::_attributes.adoc[] +:categories: data :change-log: src/main/resources/db/changeLog.xml :config-file: application.properties +:topics: data,schema-migration,liquibase,mongodb +:extensions: io.quarkus:quarkus-liquibase-mongodb https://www.liquibase.org/[Liquibase] is an open source tool for database schema change management, it allows managing MongoDB databases via it's https://github.com/liquibase/liquibase-mongodb[MongoDB Extension]. diff --git a/_versions/main/guides/liquibase.adoc b/_versions/main/guides/liquibase.adoc index a90348cbd4..2b5ae1ea45 100644 --- a/_versions/main/guides/liquibase.adoc +++ b/_versions/main/guides/liquibase.adoc @@ -9,6 +9,8 @@ include::_attributes.adoc[] :summary: This guide covers how to use the Liquibase extension to manage your schema migrations. :change-log: src/main/resources/db/changeLog.xml :config-file: application.properties +:topics: data,schema-migration,liquibase +:extensions: io.quarkus:quarkus-liquibase https://www.liquibase.org/[Liquibase] is an open source tool for database schema change management. diff --git a/_versions/main/guides/logging.adoc b/_versions/main/guides/logging.adoc index 12db2820bb..147a5b48b9 100644 --- a/_versions/main/guides/logging.adoc +++ b/_versions/main/guides/logging.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: core,getting-started,observability :diataxis-type: reference +:topics: logging,observability +:extensions: io.quarkus:quarkus-core Read about the use of logging API in Quarkus, configuring logging output, and using logging adapters to unify the output from other logging APIs. @@ -441,7 +443,7 @@ For details about its configuration, see the xref:#quarkus-log-logging-log-confi To log events to a file on the application's host, use the Quarkus file log handler. The file log handler is disabled by default, so you must first enable it. -The Quarkus file log handler supports log file rotation. +The Quarkus file log handler supports log file rotation. Log file rotation ensures effective log file management over time by maintaining a specified number of backup log files, while also keeping the primary log file up-to-date and manageable. Log file rotation ensures effective log file management over time by maintaining a specified number of backup log files, while keeping the primary log file up-to-date and manageable. diff --git a/_versions/main/guides/lra.adoc b/_versions/main/guides/lra.adoc index 89a804aa51..4a4445e678 100644 --- a/_versions/main/guides/lra.adoc +++ b/_versions/main/guides/lra.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: This guides covers the usage of LRA to coordinate activities across services. +:topics: data,lra,narayana +:extensions: io.quarkus:quarkus-narayana-lra == Introduction diff --git a/_versions/main/guides/mailer-reference.adoc b/_versions/main/guides/mailer-reference.adoc index f7eef7d048..2ddb943b42 100644 --- a/_versions/main/guides/mailer-reference.adoc +++ b/_versions/main/guides/mailer-reference.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: miscellaneous :summary: This reference guide explains in more details the configuration and usage of the Quarkus Mailer. +:topics: mail,mailer +:extensions: io.quarkus:quarkus-mailer This guide is the companion from the xref:mailer.adoc[Mailer Getting Started Guide]. It explains in more details the configuration and usage of the Quarkus Mailer. diff --git a/_versions/main/guides/mailer.adoc b/_versions/main/guides/mailer.adoc index 4c1fbd60a7..44cb28b56c 100644 --- a/_versions/main/guides/mailer.adoc +++ b/_versions/main/guides/mailer.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: miscellaneous :summary: Learn more about how you can send email from a Quarkus application with our reactive email client. +:topics: mail,mailer +:extensions: io.quarkus:quarkus-mailer This guide demonstrates how your Quarkus application can send emails using an SMTP server. This is a getting started guide. diff --git a/_versions/main/guides/management-interface-reference.adoc b/_versions/main/guides/management-interface-reference.adoc index fd7e0ca4bd..345592ca61 100644 --- a/_versions/main/guides/management-interface-reference.adoc +++ b/_versions/main/guides/management-interface-reference.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: management,observability +:extensions: io.quarkus:quarkus-vertx-http By default, Quarkus exposes the _management_ endpoints under `/q` on the main HTTP server. The same HTTP server provides the application endpoints and the management endpoints. diff --git a/_versions/main/guides/maven-tooling.adoc b/_versions/main/guides/maven-tooling.adoc index 6180858189..4e87a4566e 100644 --- a/_versions/main/guides/maven-tooling.adoc +++ b/_versions/main/guides/maven-tooling.adoc @@ -9,6 +9,7 @@ include::_attributes.adoc[] :categories: tooling, native :summary: Develop and build your Quarkus application with Maven :devtools-no-gradle: +:topics: maven,tooling Use Maven to create a new project, add or remove extensions, launch development mode, debug your application, and build your application into a jar, native executable, or container-friendly executable. Import your project into your favorite IDE using Maven project metadata. @@ -1063,23 +1064,23 @@ Here is an example `info` output for a simple project: ---- [aloubyansky@localhost code-with-quarkus]$ mvn quarkus:info [INFO] Scanning for projects... -[INFO] +[INFO] [INFO] ---------------------< org.acme:code-with-quarkus >--------------------- [INFO] Building code-with-quarkus 1.0.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- -[INFO] +[INFO] [INFO] --- quarkus-maven-plugin:{quarkus-version}:info (default-cli) @ code-with-quarkus --- [WARNING] quarkus:info goal is experimental, its options and output may change in future versions [INFO] Quarkus platform BOMs: <1> [INFO] {quarkus-platform-groupid}:quarkus-bom:pom:{quarkus-version} [INFO] {quarkus-platform-groupid}:quarkus-camel-bom:pom:{quarkus-version} -[INFO] +[INFO] [INFO] Extensions from {quarkus-platform-groupid}:quarkus-bom: <2> [INFO] io.quarkus:quarkus-resteasy-reactive -[INFO] +[INFO] [INFO] Extensions from {quarkus-platform-groupid}:quarkus-camel-bom: <3> [INFO] org.apache.camel.quarkus:camel-quarkus-rabbitmq -[INFO] +[INFO] [INFO] Extensions from registry.quarkus.io: <4> [INFO] io.quarkiverse.prettytime:quarkus-prettytime:0.2.1 ---- @@ -1103,13 +1104,13 @@ NOTE: `quarkus:info` will also report Quarkus extensions that aren't found in th [INFO] Quarkus platform BOMs: [INFO] {quarkus-platform-groupid}:quarkus-bom:pom:{quarkus-version} [INFO] {quarkus-platform-groupid}:quarkus-camel-bom:pom:{quarkus-version} | unnecessary <1> -[INFO] +[INFO] [INFO] Extensions from {quarkus-platform-groupid}:quarkus-bom: [INFO] io.quarkus:quarkus-resteasy-reactive:2.6.3.Final | misaligned <2> -[INFO] +[INFO] [INFO] Extensions from {quarkus-platform-groupid}:quarkus-camel-bom: [INFO] org.apache.camel.quarkus:camel-quarkus-rabbitmq -[INFO] +[INFO] [INFO] Extensions from registry.quarkus.io: [INFO] io.quarkiverse.prettytime:quarkus-prettytime:0.2.1 [INFO] @@ -1136,14 +1137,14 @@ Assuming we have a project including Kogito, Camel and core Quarkus extensions a ---- [aloubyansky@localhost code-with-quarkus]$ mvn quarkus:update [INFO] Scanning for projects... -[INFO] +[INFO] [INFO] ---------------------< org.acme:code-with-quarkus >--------------------- [INFO] Building code-with-quarkus 1.0.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- -[INFO] +[INFO] [INFO] --- quarkus-maven-plugin:{quarkus-version}:update (default-cli) @ code-with-quarkus --- [WARNING] quarkus:update goal is experimental, its options and output might change in future versions -[INFO] +[INFO] [INFO] Recommended Quarkus platform BOM updates: <1> [INFO] Update: {quarkus-platform-groupid}:quarkus-bom:pom:2.7.1.Final -> {quarkus-version} [INFO] Update: {quarkus-platform-groupid}:quarkus-camel-bom:pom:2.7.1.Final -> {quarkus-version} @@ -1160,10 +1161,10 @@ If we modify the project to remove all the Camel Quarkus extensions from the pro [INFO] Recommended Quarkus platform BOM updates: <1> [INFO] Update: {quarkus-platform-groupid}:quarkus-bom:pom:2.7.1.Final -> {quarkus-version} [INFO] Remove: {quarkus-platform-groupid}:quarkus-camel-bom:pom:2.7.1.Final <2> -[INFO] +[INFO] [INFO] Extensions from {quarkus-platform-groupid}:quarkus-bom: [INFO] Update: io.quarkus:quarkus-resteasy-reactive:2.6.3.Final -> remove version (managed) <3> -[INFO] +[INFO] [INFO] Extensions from registry.quarkus.io: [INFO] Update: io.quarkiverse.prettytime:quarkus-prettytime:0.2.0 -> 0.2.1 <4> ---- diff --git a/_versions/main/guides/messaging-virtual-threads.adoc b/_versions/main/guides/messaging-virtual-threads.adoc index ccf8a9f0b6..2612dcb742 100644 --- a/_versions/main/guides/messaging-virtual-threads.adoc +++ b/_versions/main/guides/messaging-virtual-threads.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Quarkus Virtual Thread support with Reactive Messaging include::_attributes.adoc[] +:categories: messaging +:topics: messaging,kafka,reactive-messaging,virtual-threads +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-kafka :runonvthread: https://javadoc.io/doc/io.smallrye.common/smallrye-common-annotation/latest/io/smallrye/common/annotation/RunOnVirtualThread.html :rm_blocking_annotation: https://javadoc.io/doc/io.smallrye.reactive/smallrye-reactive-messaging-api/latest/io/smallrye/reactive/messaging/annotations/Blocking.html :rm_blocking_docs: http://smallrye.io/smallrye-reactive-messaging/4.8.0/concepts/blocking/ diff --git a/_versions/main/guides/mongodb-panache-kotlin.adoc b/_versions/main/guides/mongodb-panache-kotlin.adoc index 7a28074d37..95bf7aa870 100644 --- a/_versions/main/guides/mongodb-panache-kotlin.adoc +++ b/_versions/main/guides/mongodb-panache-kotlin.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: data, alt-languages :summary: This guide covers the usage of MongoDB using active records and repositories in a Kotlin project. :config-file: application.properties +:topics: data,mongodb,nosql,panache,kotlin +:extensions: io.quarkus:quarkus-mongodb-panache-kotlin,io.quarkus:quarkus-mongodb-panache,io.quarkus:quarkus-mongodb-client MongoDB is a well known NoSQL Database that is widely used. MongoDB with Panache offers a new layer atop this familiar framework. This guide will not dive in to the specifics of either as those are already diff --git a/_versions/main/guides/mongodb-panache.adoc b/_versions/main/guides/mongodb-panache.adoc index e40a082643..e033479477 100644 --- a/_versions/main/guides/mongodb-panache.adoc +++ b/_versions/main/guides/mongodb-panache.adoc @@ -9,6 +9,8 @@ include::_attributes.adoc[] :summary: This guide covers the usage of MongoDB using active records and repositories. :config-file: application.properties :mongodb-doc-root-url: https://www.mongodb.com/docs/drivers/java/sync/current +:topics: data,mongodb,nosql,panache,kotlin +:extensions: io.quarkus:quarkus-mongodb-panache,io.quarkus:quarkus-mongodb-client MongoDB is a well known NoSQL Database that is widely used, but using its raw API can be cumbersome as you need to express your entities and your queries as a MongoDB link:{mongodb-doc-root-url}/fundamentals/data-formats/documents/#document[`Document`]. @@ -1260,14 +1262,14 @@ this file manually in some cases. == Multitenancy -"Multitenancy is a software architecture where a single software instance can serve multiple, distinct user groups. Software-as-a-service (SaaS) +"Multitenancy is a software architecture where a single software instance can serve multiple, distinct user groups. Software-as-a-service (SaaS) offerings are an example of multitenant architecture." (link:https://www.redhat.com/en/topics/cloud-computing/what-is-multitenancy#:~:text=Multitenancy%20is%20a%20software%20architecture,an%20example%20of%20multitenant%20architecture.[Red Hat]). MongoDB with Panache currently supports the database per tenant approach, it's similar to schema per tenant approach when compared to SQL databases. === Writing the application -In order to resolve the tenant from incoming requests and map it to a specific database, you must create an implementation +In order to resolve the tenant from incoming requests and map it to a specific database, you must create an implementation of the `io.quarkus.mongodb.panache.common.MongoDatabaseResolver` interface. [source,java] @@ -1280,26 +1282,26 @@ public class CustomMongoDatabaseResolver implements MongoDatabaseResolver { @Inject RoutingContext context; - + @Override public String resolve() { return context.request().getHeader("X-Tenant"); } - + } ---- <1> The bean is made `@RequestScoped` as the tenant resolution depends on the incoming request. [IMPORTANT] ==== -The database selection priority order is as follow: `@MongoEntity(database="mizain")`, `MongoDatabaseResolver`, +The database selection priority order is as follow: `@MongoEntity(database="mizain")`, `MongoDatabaseResolver`, and then `quarkus.mongodb.database` property. ==== [NOTE] ==== -If you also use xref:security-openid-connect-multitenancy.adoc[OIDC multitenancy], then if the OIDC tenantID and MongoDB -database are the same and must be extracted from the Vert.x `RoutingContext` you can pass the tenant id from the OIDC `TenantResolver` +If you also use xref:security-openid-connect-multitenancy.adoc[OIDC multitenancy], then if the OIDC tenantID and MongoDB +database are the same and must be extracted from the Vert.x `RoutingContext` you can pass the tenant id from the OIDC `TenantResolver` to the MongoDB with Panache `MongoDatabaseResolver` as a `RoutingContext` attribute, for example: [source,java] @@ -1367,7 +1369,7 @@ public class PersonResource { } ---- -From the classes above, we have enough to persist and fetch persons from different databases, so it's possible to see how it works. +From the classes above, we have enough to persist and fetch persons from different databases, so it's possible to see how it works. === Configuring the application @@ -1424,7 +1426,7 @@ public class PanacheMongoMultiTenancyTest { // creating person 1 Response createPerson1Response = callCreatePersonEndpoint(endpoint, TENANT_1, person1); assertResponse(createPerson1Response, 201); - + // checking person 1 creation Response getPerson1ByIdResponse = callGetPersonByIdEndpoint(endpoint, person1.id, TENANT_1); assertResponse(getPerson1ByIdResponse, 200, person1); diff --git a/_versions/main/guides/mongodb.adoc b/_versions/main/guides/mongodb.adoc index 34dd1e6b47..b653cca654 100644 --- a/_versions/main/guides/mongodb.adoc +++ b/_versions/main/guides/mongodb.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: This guide covers how to use MongoDB in Quarkus. +:topics: data,mongodb,nosql +:extensions: io.quarkus:quarkus-mongodb-client MongoDB is a well known NoSQL Database that is widely used. diff --git a/_versions/main/guides/mutiny-primer.adoc b/_versions/main/guides/mutiny-primer.adoc index 78753c348d..69c1c429af 100644 --- a/_versions/main/guides/mutiny-primer.adoc +++ b/_versions/main/guides/mutiny-primer.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Mutiny - Async for bare mortal include::_attributes.adoc[] +:categories: reactive +:topics: mutiny,reactive +:extensions: io.quarkus:quarkus-mutiny https://smallrye.io/smallrye-mutiny[Mutiny] is an intuitive, reactive programming library. It is the primary model to write reactive applications with Quarkus. diff --git a/_versions/main/guides/native-and-ssl.adoc b/_versions/main/guides/native-and-ssl.adoc index f61b72f2f2..8ba2bbaafc 100644 --- a/_versions/main/guides/native-and-ssl.adoc +++ b/_versions/main/guides/native-and-ssl.adoc @@ -8,6 +8,7 @@ include::_attributes.adoc[] :categories: core, native, security :summary: In this guide, we will discuss how you can get your native images to support SSL, as native images don't support it out of the box. :devtools-no-gradle: +:topics: native,ssl We are quickly moving to an SSL-everywhere world so being able to use SSL is crucial. diff --git a/_versions/main/guides/native-reference.adoc b/_versions/main/guides/native-reference.adoc index 8d712e120a..6721c87480 100644 --- a/_versions/main/guides/native-reference.adoc +++ b/_versions/main/guides/native-reference.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Native Reference Guide include::_attributes.adoc[] :categories: native +:topics: native This guide is a companion to the xref:building-native-image.adoc[Building a Native Executable], diff --git a/_versions/main/guides/openapi-swaggerui.adoc b/_versions/main/guides/openapi-swaggerui.adoc index f295e4e5bc..1f62773762 100644 --- a/_versions/main/guides/openapi-swaggerui.adoc +++ b/_versions/main/guides/openapi-swaggerui.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: web :summary: This guide explains how to use the OpenAPI extension to generate an OpenAPI descriptor and get a Swagger UI frontend to test your REST endpoints. +:topics: rest,openapi,swagger-ui,dev-ui +:extensions: io.quarkus:quarkus-smallrye-openapi This guide explains how your Quarkus application can expose its API description through an OpenAPI specification and how you can test it via a user-friendly UI named Swagger UI. @@ -511,7 +513,7 @@ To supply your own logo, you need to place a file called `logo.png` in `src/main This will set the logo for all UIs (not just swagger ui), so in this case also GraphQL-UI and Health-UI (if included). -If you only want to apply this logo to swagger-ui (and not globally to all UIs) call the file `smallrye-open-api-ui.png` +If you only want to apply this logo to swagger-ui (and not globally to all UIs) call the file `smallrye-open-api-ui.png` rather than `logo.png`. ==== CSS @@ -520,7 +522,7 @@ To supply your own css that override/enhance style in the html, you need to plac This will add that css to all UIs (not just swagger ui), so in this case also GraphQL-UI and Health-UI (if included). -If you only want to apply this style to swagger-ui (and not globally to all UIs) call the file `smallrye-open-api-ui.css` +If you only want to apply this style to swagger-ui (and not globally to all UIs) call the file `smallrye-open-api-ui.css` rather than `style.css`. For more information on styling, read this blog entry: https://quarkus.io/blog/stylish-api/ diff --git a/_versions/main/guides/opentelemetry.adoc b/_versions/main/guides/opentelemetry.adoc index 796c68a95a..956cceb784 100644 --- a/_versions/main/guides/opentelemetry.adoc +++ b/_versions/main/guides/opentelemetry.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: observability :summary: This guide explains how your Quarkus application can utilize OpenTelemetry to provide distributed tracing for interactive web applications. +:topics: observability,opentelemetry +:extensions: io.quarkus:quarkus-opentelemetry This guide explains how your Quarkus application can utilize https://opentelemetry.io/[OpenTelemetry] (OTel) to provide distributed tracing for interactive web applications. diff --git a/_versions/main/guides/opentracing.adoc b/_versions/main/guides/opentracing.adoc index 999a41adbc..88fb99d143 100644 --- a/_versions/main/guides/opentracing.adoc +++ b/_versions/main/guides/opentracing.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: observability :summary: This guide explains how your Quarkus application can utilize OpenTracing to provide distributed tracing for interactive web applications. +:topics: observability,opentracing +:extensions: io.quarkus:quarkus-smallrye-opentracing This guide explains how your Quarkus application can utilize OpenTracing to provide distributed tracing for interactive web applications. @@ -314,7 +316,7 @@ Following the xref:mongodb.adoc[MongoDB guide], the command listener will be reg [source, properties] ---- -# Enable tracing commands in mongodb client +# Enable tracing commands in mongodb client quarkus.mongodb.tracing.enabled=true ---- @@ -342,8 +344,8 @@ The zipkin compatibility mode will be activated after defining the config proper [source, properties] ---- -# Enable zipkin compatibility mode -quarkus.jaeger.zipkin.compatibility-mode=true +# Enable zipkin compatibility mode +quarkus.jaeger.zipkin.compatibility-mode=true ---- [[configuration-reference]] diff --git a/_versions/main/guides/optaplanner.adoc b/_versions/main/guides/optaplanner.adoc deleted file mode 100644 index 07bdf01fba..0000000000 --- a/_versions/main/guides/optaplanner.adoc +++ /dev/null @@ -1,1100 +0,0 @@ -//// -This guide is maintained in the main Quarkus repository -and pull requests should be submitted there: -https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc -//// -= OptaPlanner - Using AI to optimize a schedule with OptaPlanner -include::_attributes.adoc[] -:categories: business-automation -:summary: This guide walks you through the process of creating a Quarkus application with OptaPlanner's constraint solving Artificial Intelligence (AI). -:config-file: application.properties - -This guide walks you through the process of creating a Quarkus application -with https://www.optaplanner.org/[OptaPlanner]'s constraint solving Artificial Intelligence (AI). - -== What you will build - -You will build a REST application that optimizes a school timetable for students and teachers: - -image::optaplanner-time-table-app-screenshot.png[] - -Your service will assign `Lesson` instances to `Timeslot` and `Room` instances automatically -by using AI to adhere to hard and soft scheduling _constraints_, such as the following examples: - -* A room can have at most one lesson at the same time. -* A teacher can teach at most one lesson at the same time. -* A student can attend at most one lesson at the same time. -* A teacher prefers to teach all lessons in the same room. -* A teacher prefers to teach sequential lessons and dislikes gaps between lessons. -* A student dislikes sequential lessons on the same subject. - -Mathematically speaking, school timetabling is an _NP-hard_ problem. -This means it is difficult to scale. -Simply brute force iterating through all possible combinations takes millions of years -for a non-trivial dataset, even on a supercomputer. -Luckily, AI constraint solvers such as OptaPlanner have advanced algorithms -that deliver a near-optimal solution in a reasonable amount of time. - -[[solution]] -== Solution - -We recommend that you follow the instructions in the next sections and create the application step by step. -However, you can go right to the completed example. - -Clone the Git repository: `git clone {quickstarts-clone-url}`, or download an {quickstarts-archive-url}[archive]. - -The solution is located in link:{quickstarts-tree-url}/optaplanner-quickstart[the `optaplanner-quickstart` directory]. - -== Prerequisites - -:prerequisites-time: 30 minutes -:prerequisites-no-graalvm: -include::{includes}/prerequisites.adoc[] - -== The build file and the dependencies - -Use https://code.quarkus.io/[code.quarkus.io] to generate an application -with the following extensions, for Maven or Gradle: - -* RESTEasy Reactive (`quarkus-resteasy-reactive`) -* RESTEasy Reactive Jackson (`quarkus-resteasy-reactive-jackson`) -* OptaPlanner (`optaplanner-quarkus`) -* OptaPlanner Jackson (`optaplanner-quarkus-jackson`) - -Alternatively, generate it from the command line: - -:create-app-artifact-id: optaplanner-quickstart -:create-app-extensions: resteasy-reactive,resteasy-reactive-jackson,optaplanner-quarkus,optaplanner-quarkus-jackson -include::{includes}/devtools/create-app.adoc[] - -This will include the following dependencies in your build file: - -[source,xml,subs=attributes+,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] -.pom.xml ----- - - - - {quarkus-platform-groupid} - quarkus-bom - {quarkus-version} - pom - import - - - {quarkus-platform-groupid} - quarkus-optaplanner-bom - {quarkus-version} - pom - import - - - - - - io.quarkus - quarkus-resteasy-reactive - - - io.quarkus - quarkus-resteasy-reactive-jackson - - - org.optaplanner - optaplanner-quarkus - - - org.optaplanner - optaplanner-quarkus-jackson - - - - io.quarkus - quarkus-junit5 - test - - ----- - -[source,gradle,subs=attributes+,role="secondary asciidoc-tabs-target-sync-gradle"] -.build.gradle ----- -dependencies { - implementation enforcedPlatform("{quarkus-platform-groupid}:quarkus-bom:{quarkus-version}") - implementation enforcedPlatform("{quarkus-platform-groupid}:quarkus-optaplanner-bom:{quarkus-version}") - implementation 'io.quarkus:quarkus-resteasy-reactive' - implementation 'io.quarkus:quarkus-resteasy-reactive-jackson' - implementation 'org.optaplanner:optaplanner-quarkus' - implementation 'org.optaplanner:optaplanner-quarkus-jackson' - - testImplementation 'io.quarkus:quarkus-junit5' -} ----- - -== Model the domain objects - -Your goal is to assign each lesson to a time slot and a room. -You will create these classes: - -image::optaplanner-time-table-class-diagram-pure.png[] - -=== Timeslot - -The `Timeslot` class represents a time interval when lessons are taught, -for example, `Monday 10:30 - 11:30` or `Tuesday 13:30 - 14:30`. -For simplicity's sake, all time slots have the same duration -and there are no time slots during lunch or other breaks. - -A time slot has no date, because a high school schedule just repeats every week. -So there is no need for https://docs.optaplanner.org/latestFinal/optaplanner-docs/html_single/index.html#continuousPlanning[continuous planning]. - -Create the `src/main/java/org/acme/optaplanner/domain/Timeslot.java` class: - -[source,java] ----- -package org.acme.optaplanner.domain; - -import java.time.DayOfWeek; -import java.time.LocalTime; - -public class Timeslot { - - private DayOfWeek dayOfWeek; - private LocalTime startTime; - private LocalTime endTime; - - public Timeslot() { - } - - public Timeslot(DayOfWeek dayOfWeek, LocalTime startTime, LocalTime endTime) { - this.dayOfWeek = dayOfWeek; - this.startTime = startTime; - this.endTime = endTime; - } - - public DayOfWeek getDayOfWeek() { - return dayOfWeek; - } - - public LocalTime getStartTime() { - return startTime; - } - - public LocalTime getEndTime() { - return endTime; - } - - @Override - public String toString() { - return dayOfWeek + " " + startTime; - } - -} ----- - -Because no `Timeslot` instances change during solving, a `Timeslot` is called a _problem fact_. -Such classes do not require any OptaPlanner specific annotations. - -Notice the `toString()` method keeps the output short, -so it is easier to read OptaPlanner's `DEBUG` or `TRACE` log, as shown later. - -=== Room - -The `Room` class represents a location where lessons are taught, -for example, `Room A` or `Room B`. -For simplicity's sake, all rooms are without capacity limits -and they can accommodate all lessons. - -Create the `src/main/java/org/acme/optaplanner/domain/Room.java` class: - -[source,java] ----- -package org.acme.optaplanner.domain; - -public class Room { - - private String name; - - public Room() { - } - - public Room(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return name; - } - -} ----- - -`Room` instances do not change during solving, so `Room` is also a _problem fact_. - -=== Lesson - -During a lesson, represented by the `Lesson` class, -a teacher teaches a subject to a group of students, -for example, `Math by A.Turing for 9th grade` or `Chemistry by M.Curie for 10th grade`. -If a subject is taught multiple times per week by the same teacher to the same student group, -there are multiple `Lesson` instances that are only distinguishable by `id`. -For example, the 9th grade has six math lessons a week. - -During solving, OptaPlanner changes the `timeslot` and `room` fields of the `Lesson` class, -to assign each lesson to a time slot and a room. -Because OptaPlanner changes these fields, `Lesson` is a _planning entity_: - -image::optaplanner-time-table-class-diagram-annotated.png[] - -Most of the fields in the previous diagram contain input data, except for the orange fields: -A lesson's `timeslot` and `room` fields are unassigned (`null`) in the input data -and assigned (not `null`) in the output data. -OptaPlanner changes these fields during solving. -Such fields are called planning variables. -In order for OptaPlanner to recognize them, -both the `timeslot` and `room` fields require an `@PlanningVariable` annotation. -Their containing class, `Lesson`, requires an `@PlanningEntity` annotation. - -Create the `src/main/java/org/acme/optaplanner/domain/Lesson.java` class: - -[source,java] ----- -package org.acme.optaplanner.domain; - -import org.optaplanner.core.api.domain.entity.PlanningEntity; -import org.optaplanner.core.api.domain.lookup.PlanningId; -import org.optaplanner.core.api.domain.variable.PlanningVariable; - -@PlanningEntity -public class Lesson { - - @PlanningId - private Long id; - - private String subject; - private String teacher; - private String studentGroup; - - @PlanningVariable - private Timeslot timeslot; - @PlanningVariable - private Room room; - - public Lesson() { - } - - public Lesson(Long id, String subject, String teacher, String studentGroup) { - this.id = id; - this.subject = subject; - this.teacher = teacher; - this.studentGroup = studentGroup; - } - - public Long getId() { - return id; - } - - public String getSubject() { - return subject; - } - - public String getTeacher() { - return teacher; - } - - public String getStudentGroup() { - return studentGroup; - } - - public Timeslot getTimeslot() { - return timeslot; - } - - public void setTimeslot(Timeslot timeslot) { - this.timeslot = timeslot; - } - - public Room getRoom() { - return room; - } - - public void setRoom(Room room) { - this.room = room; - } - - @Override - public String toString() { - return subject + "(" + id + ")"; - } - -} ----- - -The `Lesson` class has an `@PlanningEntity` annotation, -so OptaPlanner knows that this class changes during solving -because it contains one or more planning variables. - -The `timeslot` field has an `@PlanningVariable` annotation, so OptaPlanner knows that it can change its value. -In order to find potential Timeslot instances to assign to this field, OptaPlanner uses the variable type to connect to a value range provider that provides a List to pick from. - -The `room` field also has an `@PlanningVariable` annotation, for the same reasons. - -[NOTE] -==== -Determining the `@PlanningVariable` fields for an arbitrary constraint solving use case -is often challenging the first time. -Read https://docs.optaplanner.org/latestFinal/optaplanner-docs/html_single/index.html#domainModelingGuide[the domain modeling guidelines] -to avoid common pitfalls. -==== - -== Define the constraints and calculate the score - -A _score_ represents the quality of a specific solution. -The higher, the better. -OptaPlanner looks for the best solution, which is the solution with the highest score found in the available time. -It might be the _optimal_ solution. - -Because this use case has hard and soft constraints, -use the `HardSoftScore` class to represent the score: - -* Hard constraints must not be broken. For example: _A room can have at most one lesson at the same time._ -* Soft constraints should not be broken. For example: _A teacher prefers to teach in a single room._ - -Hard constraints are weighted against other hard constraints. -Soft constraints are weighted too, against other soft constraints. -*Hard constraints always outweigh soft constraints*, regardless of their respective weights. - -To calculate the score, you could implement an `EasyScoreCalculator` class: - -[source,java] ----- -public class TimeTableEasyScoreCalculator implements EasyScoreCalculator { - - @Override - public HardSoftScore calculateScore(TimeTable timeTable) { - List lessonList = timeTable.getLessonList(); - int hardScore = 0; - for (Lesson a : lessonList) { - for (Lesson b : lessonList) { - if (a.getTimeslot() != null && a.getTimeslot().equals(b.getTimeslot()) - && a.getId() < b.getId()) { - // A room can accommodate at most one lesson at the same time. - if (a.getRoom() != null && a.getRoom().equals(b.getRoom())) { - hardScore--; - } - // A teacher can teach at most one lesson at the same time. - if (a.getTeacher().equals(b.getTeacher())) { - hardScore--; - } - // A student can attend at most one lesson at the same time. - if (a.getStudentGroup().equals(b.getStudentGroup())) { - hardScore--; - } - } - } - } - int softScore = 0; - // Soft constraints are only implemented in the optaplanner-quickstarts code - return HardSoftScore.of(hardScore, softScore); - } - -} ----- - -Unfortunately **that does not scale well**, because it is non-incremental: -every time a lesson is assigned to a different time slot or room, -all lessons are re-evaluated to calculate the new score. - -Instead, create a `src/main/java/org/acme/optaplanner/solver/TimeTableConstraintProvider.java` class -to perform incremental score calculation. -It uses OptaPlanner's ConstraintStream API which is inspired by Java Streams and SQL: - -[source,java] ----- -package org.acme.optaplanner.solver; - -import org.acme.optaplanner.domain.Lesson; -import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; -import org.optaplanner.core.api.score.stream.Constraint; -import org.optaplanner.core.api.score.stream.ConstraintFactory; -import org.optaplanner.core.api.score.stream.ConstraintProvider; -import org.optaplanner.core.api.score.stream.Joiners; - -public class TimeTableConstraintProvider implements ConstraintProvider { - - @Override - public Constraint[] defineConstraints(ConstraintFactory constraintFactory) { - return new Constraint[] { - // Hard constraints - roomConflict(constraintFactory), - teacherConflict(constraintFactory), - studentGroupConflict(constraintFactory), - // Soft constraints are only implemented in the optaplanner-quickstarts code - }; - } - - Constraint roomConflict(ConstraintFactory constraintFactory) { - // A room can accommodate at most one lesson at the same time. - - // Select a lesson ... - return constraintFactory - .forEach(Lesson.class) - // ... and pair it with another lesson ... - .join(Lesson.class, - // ... in the same timeslot ... - Joiners.equal(Lesson::getTimeslot), - // ... in the same room ... - Joiners.equal(Lesson::getRoom), - // ... and the pair is unique (different id, no reverse pairs) ... - Joiners.lessThan(Lesson::getId)) - // ... then penalize each pair with a hard weight. - .penalize(HardSoftScore.ONE_HARD) - .asConstraint("Room conflict"); - } - - Constraint teacherConflict(ConstraintFactory constraintFactory) { - // A teacher can teach at most one lesson at the same time. - return constraintFactory.forEach(Lesson.class) - .join(Lesson.class, - Joiners.equal(Lesson::getTimeslot), - Joiners.equal(Lesson::getTeacher), - Joiners.lessThan(Lesson::getId)) - .penalize(HardSoftScore.ONE_HARD) - .asConstraint("Teacher conflict"); - } - - Constraint studentGroupConflict(ConstraintFactory constraintFactory) { - // A student can attend at most one lesson at the same time. - return constraintFactory.forEach(Lesson.class) - .join(Lesson.class, - Joiners.equal(Lesson::getTimeslot), - Joiners.equal(Lesson::getStudentGroup), - Joiners.lessThan(Lesson::getId)) - .penalize(HardSoftScore.ONE_HARD) - .asConstraint("Student group conflict"); - } - -} ----- - -The `ConstraintProvider` scales an order of magnitude better than the `EasyScoreCalculator`: __O__(n) instead of __O__(n²). - -== Gather the domain objects in a planning solution - -A `TimeTable` wraps all `Timeslot`, `Room`, and `Lesson` instances of a single dataset. -Furthermore, because it contains all lessons, each with a specific planning variable state, -it is a _planning solution_ and it has a score: - -* If lessons are still unassigned, then it is an _uninitialized_ solution, -for example, a solution with the score `-4init/0hard/0soft`. -* If it breaks hard constraints, then it is an _infeasible_ solution, -for example, a solution with the score `-2hard/-3soft`. -* If it adheres to all hard constraints, then it is a _feasible_ solution, -for example, a solution with the score `0hard/-7soft`. - -Create the `src/main/java/org/acme/optaplanner/domain/TimeTable.java` class: - -[source,java] ----- -package org.acme.optaplanner.domain; - -import java.util.List; - -import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty; -import org.optaplanner.core.api.domain.solution.PlanningScore; -import org.optaplanner.core.api.domain.solution.PlanningSolution; -import org.optaplanner.core.api.domain.solution.ProblemFactCollectionProperty; -import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider; -import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; - -@PlanningSolution -public class TimeTable { - - @ValueRangeProvider - @ProblemFactCollectionProperty - private List timeslotList; - @ValueRangeProvider - @ProblemFactCollectionProperty - private List roomList; - @PlanningEntityCollectionProperty - private List lessonList; - - @PlanningScore - private HardSoftScore score; - - public TimeTable() { - } - - public TimeTable(List timeslotList, List roomList, List lessonList) { - this.timeslotList = timeslotList; - this.roomList = roomList; - this.lessonList = lessonList; - } - - public List getTimeslotList() { - return timeslotList; - } - - public List getRoomList() { - return roomList; - } - - public List getLessonList() { - return lessonList; - } - - public HardSoftScore getScore() { - return score; - } - -} ----- - -The `TimeTable` class has an `@PlanningSolution` annotation, -so OptaPlanner knows that this class contains all the input and output data. - -Specifically, this class is the input of the problem: - -* A `timeslotList` field with all time slots -** This is a list of problem facts, because they do not change during solving. -* A `roomList` field with all rooms -** This is a list of problem facts, because they do not change during solving. -* A `lessonList` field with all lessons -** This is a list of planning entities, because they change during solving. -** Of each `Lesson`: -*** The values of the `timeslot` and `room` fields are typically still `null`, so unassigned. -They are planning variables. -*** The other fields, such as `subject`, `teacher` and `studentGroup`, are filled in. -These fields are problem properties. - -However, this class is also the output of the solution: - -* A `lessonList` field for which each `Lesson` instance has non-null `timeslot` and `room` fields after solving -* A `score` field that represents the quality of the output solution, for example, `0hard/-5soft` - -=== The value range providers - -The `timeslotList` field is a value range provider. -It holds the `Timeslot` instances which OptaPlanner can pick from to assign to the `timeslot` field of `Lesson` instances. -The `timeslotList` field has an `@ValueRangeProvider` annotation to connect the `@PlanningVariable` with the `@ValueRangeProvider`, -by matching the type of the planning variable with the type returned by the value range provider. - -Following the same logic, the `roomList` field also has an `@ValueRangeProvider` annotation. - -=== The problem fact and planning entity properties - -Furthermore, OptaPlanner needs to know which `Lesson` instances it can change -as well as how to retrieve the `Timeslot` and `Room` instances used for score calculation -by your `TimeTableConstraintProvider`. - -The `timeslotList` and `roomList` fields have an `@ProblemFactCollectionProperty` annotation, -so your `TimeTableConstraintProvider` can select _from_ those instances. - -The `lessonList` has an `@PlanningEntityCollectionProperty` annotation, -so OptaPlanner can change them during solving -and your `TimeTableConstraintProvider` can select _from_ those too. - -== Create the solver service - -Now you are ready to put everything together and create a REST service. -But solving planning problems on REST threads causes HTTP timeout issues. -Therefore, the Quarkus extension injects a `SolverManager` instance, -which runs solvers in a separate thread pool -and can solve multiple datasets in parallel. - -Create the `src/main/java/org/acme/optaplanner/rest/TimeTableResource.java` class: - -[source,java] ----- -package org.acme.optaplanner.rest; - -import java.util.UUID; -import java.util.concurrent.ExecutionException; -import jakarta.inject.Inject; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.Path; - -import org.acme.optaplanner.domain.TimeTable; -import org.optaplanner.core.api.solver.SolverJob; -import org.optaplanner.core.api.solver.SolverManager; - -@Path("/timeTable") -public class TimeTableResource { - - @Inject - SolverManager solverManager; - - @POST - @Path("/solve") - public TimeTable solve(TimeTable problem) { - UUID problemId = UUID.randomUUID(); - // Submit the problem to start solving - SolverJob solverJob = solverManager.solve(problemId, problem); - TimeTable solution; - try { - // Wait until the solving ends - solution = solverJob.getFinalBestSolution(); - } catch (InterruptedException | ExecutionException e) { - throw new IllegalStateException("Solving failed.", e); - } - return solution; - } - -} ----- - -For simplicity's sake, this initial implementation waits for the solver to finish, -which can still cause an HTTP timeout. -The _complete_ implementation avoids HTTP timeouts much more elegantly. - -== Set the termination time - -Without a termination setting or a termination event, the solver runs forever. -To avoid that, limit the solving time to five seconds. -That is short enough to avoid the HTTP timeout. - -Create the `src/main/resources/application.properties` file: - -[source,properties] ----- -# The solver runs only for 5 seconds to avoid an HTTP timeout in this simple implementation. -# It's recommended to run for at least 5 minutes ("5m") otherwise. -quarkus.optaplanner.solver.termination.spent-limit=5s ----- - - -== Run the application - -First start the application: - -include::{includes}/devtools/dev.adoc[] - -=== Try the application - -Now that the application is running, you can test the REST service. -You can use any REST client you wish. -The following example uses the Linux command `curl` to send a POST request: - -[source,shell] ----- -$ curl -i -X POST http://localhost:8080/timeTable/solve -H "Content-Type:application/json" -d '{"timeslotList":[{"dayOfWeek":"MONDAY","startTime":"08:30:00","endTime":"09:30:00"},{"dayOfWeek":"MONDAY","startTime":"09:30:00","endTime":"10:30:00"}],"roomList":[{"name":"Room A"},{"name":"Room B"}],"lessonList":[{"id":1,"subject":"Math","teacher":"A. Turing","studentGroup":"9th grade"},{"id":2,"subject":"Chemistry","teacher":"M. Curie","studentGroup":"9th grade"},{"id":3,"subject":"French","teacher":"M. Curie","studentGroup":"10th grade"},{"id":4,"subject":"History","teacher":"I. Jones","studentGroup":"10th grade"}]}' ----- - -After about five seconds, according to the termination spent time defined in your `application.properties`, -the service returns an output similar to the following example: - -[source] ----- -HTTP/1.1 200 -Content-Type: application/json -... - -{"timeslotList":...,"roomList":...,"lessonList":[{"id":1,"subject":"Math","teacher":"A. Turing","studentGroup":"9th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"08:30:00","endTime":"09:30:00"},"room":{"name":"Room A"}},{"id":2,"subject":"Chemistry","teacher":"M. Curie","studentGroup":"9th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"09:30:00","endTime":"10:30:00"},"room":{"name":"Room A"}},{"id":3,"subject":"French","teacher":"M. Curie","studentGroup":"10th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"08:30:00","endTime":"09:30:00"},"room":{"name":"Room B"}},{"id":4,"subject":"History","teacher":"I. Jones","studentGroup":"10th grade","timeslot":{"dayOfWeek":"MONDAY","startTime":"09:30:00","endTime":"10:30:00"},"room":{"name":"Room B"}}],"score":"0hard/0soft"} ----- - -Notice that your application assigned all four lessons to one of the two time slots and one of the two rooms. -Also notice that it conforms to all hard constraints. -For example, M. Curie's two lessons are in different time slots. - -On the server side, the `info` log show what OptaPlanner did in those five seconds: - -[source,options="nowrap"] ----- -... Solving started: time spent (33), best score (-8init/0hard/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0). -... Construction Heuristic phase (0) ended: time spent (73), best score (0hard/0soft), score calculation speed (459/sec), step total (4). -... Local Search phase (1) ended: time spent (5000), best score (0hard/0soft), score calculation speed (28949/sec), step total (28398). -... Solving ended: time spent (5000), best score (0hard/0soft), score calculation speed (28524/sec), phase total (2), environment mode (REPRODUCIBLE). ----- - -=== Test the application - -A good application includes test coverage. - -==== Test the constraints - -To test each constraint in isolation, use a `ConstraintVerifier` in unit tests. -It tests each constraint's corner cases in isolation from the other tests, -which lowers maintenance when adding a new constraint with proper test coverage. - -Add a `optaplanner-test` dependency in your build file: - -[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] -.pom.xml ----- - - org.optaplanner - optaplanner-test - test - ----- - -[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] -.build.gradle ----- -testImplementation("org.optaplanner:optaplanner-test") ----- - -Create the `src/test/java/org/acme/optaplanner/solver/TimeTableConstraintProviderTest.java` class: - -[source,java] ----- -package org.acme.optaplanner.solver; - -import java.time.DayOfWeek; -import java.time.LocalTime; - -import jakarta.inject.Inject; - -import io.quarkus.test.junit.QuarkusTest; -import org.acme.optaplanner.domain.Lesson; -import org.acme.optaplanner.domain.Room; -import org.acme.optaplanner.domain.TimeTable; -import org.acme.optaplanner.domain.Timeslot; -import org.junit.jupiter.api.Test; -import org.optaplanner.test.api.score.stream.ConstraintVerifier; - -@QuarkusTest -class TimeTableConstraintProviderTest { - - private static final Room ROOM = new Room("Room1"); - private static final Timeslot TIMESLOT1 = new Timeslot(DayOfWeek.MONDAY, LocalTime.of(9,0), LocalTime.NOON); - private static final Timeslot TIMESLOT2 = new Timeslot(DayOfWeek.TUESDAY, LocalTime.of(9,0), LocalTime.NOON); - - @Inject - ConstraintVerifier constraintVerifier; - - @Test - void roomConflict() { - Lesson firstLesson = new Lesson(1, "Subject1", "Teacher1", "Group1"); - Lesson conflictingLesson = new Lesson(2, "Subject2", "Teacher2", "Group2"); - Lesson nonConflictingLesson = new Lesson(3, "Subject3", "Teacher3", "Group3"); - - firstLesson.setRoom(ROOM); - firstLesson.setTimeslot(TIMESLOT1); - - conflictingLesson.setRoom(ROOM); - conflictingLesson.setTimeslot(TIMESLOT1); - - nonConflictingLesson.setRoom(ROOM); - nonConflictingLesson.setTimeslot(TIMESLOT2); - - constraintVerifier.verifyThat(TimeTableConstraintProvider::roomConflict) - .given(firstLesson, conflictingLesson, nonConflictingLesson) - .penalizesBy(1); - } - -} ----- - -This test verifies that the constraint `TimeTableConstraintProvider::roomConflict`, -when given three lessons in the same room, where two lessons have the same timeslot, -it penalizes with a match weight of `1`. -So with a constraint weight of `10hard` it would reduce the score by `-10hard`. - -Notice how `ConstraintVerifier` ignores the constraint weight during testing - even -if those constraint weights are hard coded in the `ConstraintProvider` - because -constraints weights change regularly before going into production. -This way, constraint weight tweaking does not break the unit tests. - -==== Test the solver - -In a JUnit test, generate a test dataset and send it to the `TimeTableResource` to solve. - -Create the `src/test/java/org/acme/optaplanner/rest/TimeTableResourceTest.java` class: - -[source,java] ----- -package org.acme.optaplanner.rest; - -import java.time.DayOfWeek; -import java.time.LocalTime; -import java.util.ArrayList; -import java.util.List; - -import jakarta.inject.Inject; - -import io.quarkus.test.junit.QuarkusTest; -import org.acme.optaplanner.domain.Room; -import org.acme.optaplanner.domain.Timeslot; -import org.acme.optaplanner.domain.Lesson; -import org.acme.optaplanner.domain.TimeTable; -import org.acme.optaplanner.rest.TimeTableResource; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@QuarkusTest -public class TimeTableResourceTest { - - @Inject - TimeTableResource timeTableResource; - - @Test - @Timeout(600_000) - public void solve() { - TimeTable problem = generateProblem(); - TimeTable solution = timeTableResource.solve(problem); - assertFalse(solution.getLessonList().isEmpty()); - for (Lesson lesson : solution.getLessonList()) { - assertNotNull(lesson.getTimeslot()); - assertNotNull(lesson.getRoom()); - } - assertTrue(solution.getScore().isFeasible()); - } - - private TimeTable generateProblem() { - List timeslotList = new ArrayList<>(); - timeslotList.add(new Timeslot(DayOfWeek.MONDAY, LocalTime.of(8, 30), LocalTime.of(9, 30))); - timeslotList.add(new Timeslot(DayOfWeek.MONDAY, LocalTime.of(9, 30), LocalTime.of(10, 30))); - timeslotList.add(new Timeslot(DayOfWeek.MONDAY, LocalTime.of(10, 30), LocalTime.of(11, 30))); - timeslotList.add(new Timeslot(DayOfWeek.MONDAY, LocalTime.of(13, 30), LocalTime.of(14, 30))); - timeslotList.add(new Timeslot(DayOfWeek.MONDAY, LocalTime.of(14, 30), LocalTime.of(15, 30))); - - List roomList = new ArrayList<>(); - roomList.add(new Room("Room A")); - roomList.add(new Room("Room B")); - roomList.add(new Room("Room C")); - - List lessonList = new ArrayList<>(); - lessonList.add(new Lesson(101L, "Math", "B. May", "9th grade")); - lessonList.add(new Lesson(102L, "Physics", "M. Curie", "9th grade")); - lessonList.add(new Lesson(103L, "Geography", "M. Polo", "9th grade")); - lessonList.add(new Lesson(104L, "English", "I. Jones", "9th grade")); - lessonList.add(new Lesson(105L, "Spanish", "P. Cruz", "9th grade")); - - lessonList.add(new Lesson(201L, "Math", "B. May", "10th grade")); - lessonList.add(new Lesson(202L, "Chemistry", "M. Curie", "10th grade")); - lessonList.add(new Lesson(203L, "History", "I. Jones", "10th grade")); - lessonList.add(new Lesson(204L, "English", "P. Cruz", "10th grade")); - lessonList.add(new Lesson(205L, "French", "M. Curie", "10th grade")); - return new TimeTable(timeslotList, roomList, lessonList); - } - -} ----- - -This test verifies that after solving, all lessons are assigned to a time slot and a room. -It also verifies that it found a feasible solution (no hard constraints broken). - -Add test properties to the `src/main/resources/application.properties` file: - -[source,properties] ----- -quarkus.optaplanner.solver.termination.spent-limit=5s - -# Effectively disable spent-time termination in favor of the best-score-limit -%test.quarkus.optaplanner.solver.termination.spent-limit=1h -%test.quarkus.optaplanner.solver.termination.best-score-limit=0hard/*soft ----- - -Normally, the solver finds a feasible solution in less than 200 milliseconds. -Notice how the `application.properties` overwrites the solver termination during tests -to terminate as soon as a feasible solution (`0hard/*soft`) is found. -This avoids hard coding a solver time, because the unit test might run on arbitrary hardware. -This approach ensures that the test runs long enough to find a feasible solution, even on slow machines. -But it does not run a millisecond longer than it strictly must, even on fast machines. - -=== Logging - -When adding constraints in your `ConstraintProvider`, -keep an eye on the _score calculation speed_ in the `info` log, -after solving for the same amount of time, to assess the performance impact: - -[source] ----- -... Solving ended: ..., score calculation speed (29455/sec), ... ----- - -To understand how OptaPlanner is solving your problem internally, -change the logging in the `application.properties` file or with a `-D` system property: - -[source,properties] ----- -quarkus.log.category."org.optaplanner".level=debug ----- - -Use `debug` logging to show every _step_: - -[source,options="nowrap"] ----- -... Solving started: time spent (67), best score (-20init/0hard/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0). -... CH step (0), time spent (128), score (-18init/0hard/0soft), selected move count (15), picked move ([Math(101) {null -> Room A}, Math(101) {null -> MONDAY 08:30}]). -... CH step (1), time spent (145), score (-16init/0hard/0soft), selected move count (15), picked move ([Physics(102) {null -> Room A}, Physics(102) {null -> MONDAY 09:30}]). -... ----- - -Use `trace` logging to show every _step_ and every _move_ per step. - -== Summary - -Congratulations! -You have just developed a Quarkus application with https://www.optaplanner.org/[OptaPlanner]! - -== Further improvements: Database and UI integration - -Now try adding database and UI integration: - -. Store `Timeslot`, `Room`, and `Lesson` in the database with xref:hibernate-orm-panache.adoc[Hibernate and Panache]. - -. xref:rest-json.adoc[Expose them through REST]. - -. Adjust the `TimeTableResource` to read and write a `TimeTable` instance in a single transaction -and use those accordingly: -+ -[source,java] ----- -package org.acme.optaplanner.rest; - -import jakarta.inject.Inject; -import jakarta.transaction.Transactional; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.Path; - -import io.quarkus.panache.common.Sort; -import org.acme.optaplanner.domain.Lesson; -import org.acme.optaplanner.domain.Room; -import org.acme.optaplanner.domain.TimeTable; -import org.acme.optaplanner.domain.Timeslot; -import org.optaplanner.core.api.score.ScoreManager; -import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; -import org.optaplanner.core.api.solver.SolverManager; -import org.optaplanner.core.api.solver.SolverStatus; - -@Path("/timeTable") -public class TimeTableResource { - - public static final Long SINGLETON_TIME_TABLE_ID = 1L; - - @Inject - SolverManager solverManager; - @Inject - ScoreManager scoreManager; - - // To try, open http://localhost:8080/timeTable - @GET - public TimeTable getTimeTable() { - // Get the solver status before loading the solution - // to avoid the race condition that the solver terminates between them - SolverStatus solverStatus = getSolverStatus(); - TimeTable solution = findById(SINGLETON_TIME_TABLE_ID); - scoreManager.updateScore(solution); // Sets the score - solution.setSolverStatus(solverStatus); - return solution; - } - - @POST - @Path("/solve") - public void solve() { - solverManager.solveAndListen(SINGLETON_TIME_TABLE_ID, - this::findById, - this::save); - } - - public SolverStatus getSolverStatus() { - return solverManager.getSolverStatus(SINGLETON_TIME_TABLE_ID); - } - - @POST - @Path("/stopSolving") - public void stopSolving() { - solverManager.terminateEarly(SINGLETON_TIME_TABLE_ID); - } - - @Transactional - protected TimeTable findById(Long id) { - if (!SINGLETON_TIME_TABLE_ID.equals(id)) { - throw new IllegalStateException("There is no timeTable with id (" + id + ")."); - } - // Occurs in a single transaction, so each initialized lesson references the same timeslot/room instance - // that is contained by the timeTable's timeslotList/roomList. - return new TimeTable( - Timeslot.listAll(Sort.by("dayOfWeek").and("startTime").and("endTime").and("id")), - Room.listAll(Sort.by("name").and("id")), - Lesson.listAll(Sort.by("subject").and("teacher").and("studentGroup").and("id"))); - } - - @Transactional - protected void save(TimeTable timeTable) { - for (Lesson lesson : timeTable.getLessonList()) { - // TODO this is awfully naive: optimistic locking causes issues if called by the SolverManager - Lesson attachedLesson = Lesson.findById(lesson.getId()); - attachedLesson.setTimeslot(lesson.getTimeslot()); - attachedLesson.setRoom(lesson.getRoom()); - } - } - -} ----- -+ -For simplicity's sake, this code handles only one `TimeTable` instance, -but it is straightforward to enable multi-tenancy and handle multiple `TimeTable` instances of different high schools in parallel. -+ -The `getTimeTable()` method returns the latest timetable from the database. -It uses the `ScoreManager` (which is automatically injected) -to calculate the score of that timetable, so the UI can show the score. -+ -The `solve()` method starts a job to solve the current timetable and store the time slot and room assignments in the database. -It uses the `SolverManager.solveAndListen()` method to listen to intermediate best solutions -and update the database accordingly. -This enables the UI to show progress while the backend is still solving. - -. Adjust the `TimeTableResourceTest` instance accordingly, now that the `solve()` method returns immediately. -Poll for the latest solution until the solver finishes solving: -+ -[source,java] ----- -package org.acme.optaplanner.rest; - -import jakarta.inject.Inject; - -import io.quarkus.test.junit.QuarkusTest; -import org.acme.optaplanner.domain.Lesson; -import org.acme.optaplanner.domain.TimeTable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; -import org.optaplanner.core.api.solver.SolverStatus; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@QuarkusTest -public class TimeTableResourceTest { - - @Inject - TimeTableResource timeTableResource; - - @Test - @Timeout(600_000) - public void solveDemoDataUntilFeasible() throws InterruptedException { - timeTableResource.solve(); - TimeTable timeTable = timeTableResource.getTimeTable(); - while (timeTable.getSolverStatus() != SolverStatus.NOT_SOLVING) { - // Quick polling (not a Test Thread Sleep anti-pattern) - // Test is still fast on fast machines and doesn't randomly fail on slow machines. - Thread.sleep(20L); - timeTable = timeTableResource.getTimeTable(); - } - assertFalse(timeTable.getLessonList().isEmpty()); - for (Lesson lesson : timeTable.getLessonList()) { - assertNotNull(lesson.getTimeslot()); - assertNotNull(lesson.getRoom()); - } - assertTrue(timeTable.getScore().isFeasible()); - } - -} ----- - -. Build an attractive web UI on top of these REST methods to visualize the timetable. - -Take a look at link:{quickstarts-tree-url}/optaplanner-quickstart[the quickstart source code] to see how this all turns out. diff --git a/_versions/main/guides/performance-measure.adoc b/_versions/main/guides/performance-measure.adoc index 51ca1c4b1e..f18d708c94 100644 --- a/_versions/main/guides/performance-measure.adoc +++ b/_versions/main/guides/performance-measure.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: miscellaneous :summary: This guide explains how to best measure the footprint of a Quarkus application. +:topics: internals,performance This guide covers: @@ -54,7 +55,7 @@ it is very misleading in environments like Kubernetes/OpenShift. === Measuring Memory Correctly on Docker -In order to measure memory correctly **DO NOT use docker stat or anything derived from it** (e.g. ctop). This approach only measures a subset of the in-use resident pages, while the Linux Kernel, cgroups and cloud orchestration providers will utilize the full resident set in their accounting (determining whether a process is over the limits and should be killed). +In order to measure memory correctly **DO NOT use docker stat or anything derived from it** (e.g. ctop). This approach only measures a subset of the in-use resident pages, while the Linux Kernel, cgroups and cloud orchestration providers will utilize the full resident set in their accounting (determining whether a process is over the limits and should be killed). To measure accurately, a similar set of steps for measuring RSS on Linux should be performed. The docker `top` command allows running a `ps` command on the container host machine against the processes in the container instance. By utilizing this in combination with formatting output parameters, the rss value can be returned: @@ -69,7 +70,7 @@ For example: PID RSS COMMAND 2531 27m ./application -Dquarkus.http.host=0.0.0.0 ---- - + Alternatively, one can jump directly into a privileged shell (root on the host), and execute a `ps` command directly: [source,shell] diff --git a/_versions/main/guides/picocli.adoc b/_versions/main/guides/picocli.adoc index fc950d446b..d5c16186b0 100644 --- a/_versions/main/guides/picocli.adoc +++ b/_versions/main/guides/picocli.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: command-line :summary: Simplify command line applications creation with the Picocli extension. +:topics: command-line,cli,picocli +:extensions: io.quarkus:quarkus-picocli https://picocli.info/[Picocli] is an open source tool for creating rich command line applications. @@ -202,7 +204,7 @@ This event will be generated in `QuarkusApplication` class created by this exten ---- @CommandLine.Command public class EntryCommand implements Runnable { - + @CommandLine.Option(names = "-c", description = "JDBC connection string") String connectionString; diff --git a/_versions/main/guides/platform.adoc b/_versions/main/guides/platform.adoc index 70609cb220..2b0d938dae 100644 --- a/_versions/main/guides/platform.adoc +++ b/_versions/main/guides/platform.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: architecture :summary: Learn more about what we call a Platform in the Quarkus world. +:topics: internals,platform The Quarkus extension ecosystem consists of the Quarkus extensions developed and maintained by the community, including the Quarkus core development team. While the Quarkus ecosystem (sometimes also referred to as the "Quarkus universe") includes all the Quarkus extensions ever developed, there is also a concept of a Quarkus platform. diff --git a/_versions/main/guides/podman.adoc b/_versions/main/guides/podman.adoc index da73b95fb9..fedc6a2767 100644 --- a/_versions/main/guides/podman.adoc +++ b/_versions/main/guides/podman.adoc @@ -4,6 +4,8 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Using Podman with Quarkus +:categories: tooling +:topics: podman,devops,tooling include::_attributes.adoc[] https://podman.io/[Podman] is a daemonless and rootless container engine for developing, managing, and running OCI Containers on your Linux system or other OS. diff --git a/_versions/main/guides/pulsar-dev-services.adoc b/_versions/main/guides/pulsar-dev-services.adoc index 3a40ab216d..302f470f37 100644 --- a/_versions/main/guides/pulsar-dev-services.adoc +++ b/_versions/main/guides/pulsar-dev-services.adoc @@ -4,6 +4,10 @@ and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Dev Services for Pulsar +include::_attributes.adoc[] +:categories: messaging +:topics: messaging,reactive-messaging,pulsar,devservices,tooling,testing,devmode +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-pulsar With Quarkus Smallrye Reactive Messaging Pulsar extension (`quarkus-smallrye-reactive-messaging-pulsar`) Dev Services for Pulsar automatically starts a Pulsar broker in dev mode and when running tests. diff --git a/_versions/main/guides/pulsar-getting-started.adoc b/_versions/main/guides/pulsar-getting-started.adoc index 22525f7a75..2a0dfde3ba 100644 --- a/_versions/main/guides/pulsar-getting-started.adoc +++ b/_versions/main/guides/pulsar-getting-started.adoc @@ -6,6 +6,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Getting Started to SmallRye Reactive Messaging with Apache Pulsar include::_attributes.adoc[] :categories: messaging +:topics: messaging,reactive-messaging,pulsar +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-pulsar :summary: This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with Apache Pulsar. This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with Apache Pulsar. diff --git a/_versions/main/guides/pulsar.adoc b/_versions/main/guides/pulsar.adoc index 4cd1f601a5..cc96c1f5e6 100644 --- a/_versions/main/guides/pulsar.adoc +++ b/_versions/main/guides/pulsar.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: messaging,reactive-messaging,pulsar +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-pulsar This reference guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with Apache Pulsar. diff --git a/_versions/main/guides/quarkus-maven-plugin.adoc b/_versions/main/guides/quarkus-maven-plugin.adoc index ae1c766b26..3201dca12a 100644 --- a/_versions/main/guides/quarkus-maven-plugin.adoc +++ b/_versions/main/guides/quarkus-maven-plugin.adoc @@ -5,6 +5,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Quarkus Maven Plugin include::_attributes.adoc[] +:topics: maven,tooling The Quarkus Maven Plugin builds the Quarkus applications, and provides helpers to launch dev mode or build native executables. For more information about how to use the Quarkus Maven Plugin, please refer to the xref:maven-tooling.adoc[Maven Tooling guide]. diff --git a/_versions/main/guides/quarkus-reactive-architecture.adoc b/_versions/main/guides/quarkus-reactive-architecture.adoc index 486e48f4bd..5a35c153f4 100644 --- a/_versions/main/guides/quarkus-reactive-architecture.adoc +++ b/_versions/main/guides/quarkus-reactive-architecture.adoc @@ -7,6 +7,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: architecture :summary: Learn more about Quarkus reactive architecture. +:topics: internals,reactive Quarkus is reactive. It's even more than this: Quarkus unifies reactive and imperative programming. diff --git a/_versions/main/guides/quarkus-runtime-base-image.adoc b/_versions/main/guides/quarkus-runtime-base-image.adoc index 9cbb93d08e..7b6b20c817 100644 --- a/_versions/main/guides/quarkus-runtime-base-image.adoc +++ b/_versions/main/guides/quarkus-runtime-base-image.adoc @@ -5,6 +5,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Quarkus Base Runtime Image include::_attributes.adoc[] +:categories: tooling +:topics: docker,podman,images To ease the containerization of native executables, Quarkus provides a base image providing the requirements to run these executables. The `quarkus-micro-image:2.0` image is: diff --git a/_versions/main/guides/quartz.adoc b/_versions/main/guides/quartz.adoc index 7dd39a6915..60aa9b9da8 100644 --- a/_versions/main/guides/quartz.adoc +++ b/_versions/main/guides/quartz.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: miscellaneous :summary: You need clustering support for your scheduled tasks? This guide explains how to use the Quartz extension for that. :extension-status: preview +:topics: scheduling,cronjob,quartz +:extensions: io.quarkus:quarkus-quartz Modern applications often need to run specific tasks periodically. In this guide, you learn how to schedule periodic clustered tasks using the http://www.quartz-scheduler.org/[Quartz] extension. @@ -154,7 +156,7 @@ public class TaskBean { @Inject org.quartz.Scheduler quartz; <1> - + void onStart(@Observes StartupEvent event) throws SchedulerException { JobDetail job = JobBuilder.newJob(MyJob.class) .withIdentity("myJob", "myGroup") @@ -169,23 +171,23 @@ public class TaskBean { .build(); quartz.scheduleJob(job, trigger); <2> } - + @Transactional void performTask() { Task task = new Task(); task.persist(); } - + // A new instance of MyJob is created by Quartz for every job execution public static class MyJob implements Job { @Inject TaskBean taskBean; - + public void execute(JobExecutionContext context) throws JobExecutionException { taskBean.performTask(); <3> } - + } } ---- @@ -193,7 +195,7 @@ public class TaskBean { <2> Schedule a new job using the Quartz API. <3> Invoke the `TaskBean#performTask()` method from the job. Jobs are also xref:cdi.adoc[container-managed] beans if they belong to a link:cdi-reference[bean archive]. -NOTE: By default, the scheduler is not started unless a `@Scheduled` business method is found. You may need to force the start of the scheduler for "pure" programmatic scheduling. See also xref:quartz-configuration-reference[Quartz Configuration Reference]. +NOTE: By default, the scheduler is not started unless a `@Scheduled` business method is found. You may need to force the start of the scheduler for "pure" programmatic scheduling. See also xref:quartz-configuration-reference[Quartz Configuration Reference]. == Updating the application configuration file diff --git a/_versions/main/guides/qute-reference.adoc b/_versions/main/guides/qute-reference.adoc index 3c0bcdfce0..935d410a49 100644 --- a/_versions/main/guides/qute-reference.adoc +++ b/_versions/main/guides/qute-reference.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: templating,qute +:extensions: io.quarkus:quarkus-qute,io.quarkus:quarkus-resteasy-qute,io.quarkus:quarkus-resteasy-reactive-qute Qute is a templating engine designed specifically to meet the Quarkus needs. The usage of reflection is minimized to reduce the size of native images. @@ -67,7 +69,7 @@ LOG.info(Qute.fmt("Hello {name}!").data("name", "Foo")); // => Hello Foo! and the message template is only evaluated if the log level INFO is used for the specific logger ---- -NOTE: Please read the javadoc of the `io.quarkus.qute.Qute` class for more details. +NOTE: Please read the javadoc of the `io.quarkus.qute.Qute` class for more details. [[hello_world_example]] == Hello World Example @@ -89,7 +91,7 @@ Then, we will need to parse the contents into a *template definition* Java objec A template definition is an instance of `io.quarkus.qute.Template`. If using Qute "standalone" you'll need to create an instance of `io.quarkus.qute.Engine` first. -The `Engine` represents a central point for template management with dedicated configuration. +The `Engine` represents a central point for template management with dedicated configuration. Let's use the convenient builder: [source,java] @@ -118,7 +120,7 @@ hello.data("name", "Jim").render(); <1> <2> <1> `Template.data(String, Object)` is a convenient method that creates a template instance and sets the data in one step. <2> `TemplateInstance.render()` triggers a synchronous rendering, i.e. the current thread is blocked until the rendering is finished. However, there are also asynchronous ways to trigger the rendering and consume the results. For example, there is the `TemplateInstance.renderAsync()` method that returns `CompletionStage` or `TemplateInstance.createMulti()` that returns Mutiny's `Multi`. -So the workflow is simple: +So the workflow is simple: 1. Create the template contents (`hello.html`), 2. Parse the template definition (`io.quarkus.qute.Template`), @@ -177,11 +179,11 @@ The content of a tag must start with: * a digit, or * an alphabet character, or -* underscore, or +* underscore, or * a built-in command: `#`, `!`, `@`, `/`. If it does not start with any of the above it is ignored by the parser. - + .Tag Examples [source,html] ---- @@ -197,7 +199,7 @@ If it does not start with any of the above it is ignored by the parser. ---- <1> Parsed: an expression that starts with underscore. <2> Parsed: a comment -<3> Ignored: starts with whitespace. +<3> Ignored: starts with whitespace. <4> Ignored: starts with `{`. <5> Ignored: starts with `"`. @@ -225,7 +227,7 @@ Likewise, a line that contains an _expression_ or a _non-whitespace character_ i ---- <1> This is a standalone line and will be removed. -<2> Not a standalone line - contains an expression and non-whitespace characters +<2> Not a standalone line - contains an expression and non-whitespace characters <3> Not a standalone line - contains no section tag/parameter declaration <4> This is a standalone line. @@ -235,8 +237,8 @@ Likewise, a line that contains an _expression_ or a _non-whitespace character_ i
    -
  • Foo 100
  • - +
  • Foo 100
  • +
@@ -251,10 +253,10 @@ In this case, all whitespace characters from a standalone line will be printed t
    - +
  • Foo 100
  • - - + +
@@ -280,14 +282,14 @@ Namespace expressions are resolved differently - see also xref:expression_resolu {name} <1> {item.name} <2> {item['name']} <3> -{global:colors} <4> +{global:colors} <4> ---- <1> no namespace, one part: `name` <2> no namespace, two parts: `item`, `name` <3> equivalent to `{item.name}` but using the bracket notation <4> namespace `global`, one part: `colors` -A part of an expression can be a _virtual method_ in which case the name can be followed by a list of comma-separated parameters in parentheses. +A part of an expression can be a _virtual method_ in which case the name can be followed by a list of comma-separated parameters in parentheses. A parameter of a virtual method can be either a nested expression or a xref:literals[literal] value. We call these methods _"virtual"_ because they do not have to be backed by a real Java method. You can learn more about virtual methods in the xref:virtual_methods[following section]. @@ -307,16 +309,16 @@ You can learn more about virtual methods in the xref:virtual_methods[following s |=== |Literal |Examples -|boolean +|boolean |`true`, `false` -|null +|null |`null` -|string +|string |`'value'`, `"string"` -|integer +|integer |`1`, `-5` |long @@ -343,11 +345,11 @@ For example, expression `{name}` has no namespace and single part - `name`. The "name" will be resolved using all available value resolvers against the current context object. However, the expression `{global:colors}` has the namespace `global` and single part - `colors`. First, all available ``NamespaceResolver``s will be used to find the current context object. -And afterwards value resolvers will be used to resolve "colors" against the context object found. +And afterwards value resolvers will be used to resolve "colors" against the context object found. [TIP] ==== -Data passed to the template instance are always accessible using the `data` namespace. +Data passed to the template instance are always accessible using the `data` namespace. This could be useful to access data for which the key is overridden: [source,html] @@ -357,7 +359,7 @@ This could be useful to access data for which the key is overridden:
    {#for item in item.derivedItems} <2>
  • - {item.name} <3> + {item.name} <3> is derived from {data:item.name} <4>
  • @@ -490,7 +492,7 @@ The only difference is that for virtual methods a value resolver consumes parame

    {item.buildName(item.name,5)}

    <1> ---- -<1> `buildName(item.name,5)` represents a virtual method with name `buildName` and two parameters: `item.name` and `5` . The virtual method could be evaluated by a value resolver generated for the following Java class: +<1> `buildName(item.name,5)` represents a virtual method with name `buildName` and two parameters: `item.name` and `5` . The virtual method could be evaluated by a value resolver generated for the following Java class: + [source,java] ---- @@ -535,7 +537,7 @@ If a part of an expression resolves to a `Uni`, a `CompletionStage` is first cre IMPORTANT: Note that each `Uni#subscribeAsCompletionStage()` results in a new subscription. You might need to configure memoization of the `Uni` item or failure before it's used as template data, i.e. `myUni.memoize().indefinitely()`. -It can happen that a `CompletionStage` never completes or a `Uni` emits no item/failure. +It can happen that a `CompletionStage` never completes or a `Uni` emits no item/failure. In this case, the rendering methods (such as `TemplateInstance#render()` and `TemplateInstance#createUni()`) fail after a specific timeout. The timeout can be specified as a template instance `timeout` attribute. If no `timeout` attribute is set the global rendering timeout is used. @@ -639,11 +641,11 @@ A start tag can define parameters with optional names, e.g. `{#if item.isActive} Parameters are separated by one or more spaces. Names are separated from the values by the equals sign. Names and values can be prefixed and suffixed with any number of spaces, e.g. `{#let id='Foo'}` and `{#let id = 'Foo'}` are equivalents where the name of the parameter is `id` and the value is `Foo`. -Values can be grouped using parentheses, e.g. `{#let id=(item.id ?: 42)}` where the name is `id` and the value is `item.id ?: 42`. +Values can be grouped using parentheses, e.g. `{#let id=(item.id ?: 42)}` where the name is `id` and the value is `item.id ?: 42`. Sections can interpret parameter values in any way, e.g. take the value as is. However, in most cases, the parameter value is registered as an xref:expressions[expression] and evaluated before use. -A section may contain several content *blocks*. +A section may contain several content *blocks*. The "main" block is always present. Additional/nested blocks also start with `#` and can have parameters too - `{#else if item.isActive}`. A section helper that defines the logic of a section can "execute" any of the blocks and evaluate the parameters. @@ -685,7 +687,7 @@ The other form is using the name `for` and specifies the alias used to reference [source] ---- {#for item in items} <1> - {item.name} + {item.name} {/for} ---- <1> `item` is the alias used for the iteration element. @@ -714,7 +716,7 @@ For example, the `hasNext` key must be prefixed with `it_` inside an `{#each}` s {#if it_hasNext}
    {/if} <2> {/each} ---- -<1> `it_count` represents one-based index. +<1> `it_count` represents one-based index. <2> `
    ` is only rendered if the iteration has more elements. And must be used in a form of `{item_hasNext}` inside a `{#for}` section with the `item` element alias. @@ -727,12 +729,12 @@ And must be used in a form of `{item_hasNext}` inside a `{#for}` section with th {#if item_hasNext}
    {/if} <2> {/for} ---- -<1> `item_count` represents one-based index. +<1> `item_count` represents one-based index. <2> `
    ` is only rendered if the iteration has more elements. [TIP] ==== -The iteration metadata prefix is configurable either via `EngineBuilder.iterationMetadataPrefix()` for standalone Qute or via the `quarkus.qute.iteration-metadata-prefix` configuration property in a Quarkus application. Three special constants can be used: +The iteration metadata prefix is configurable either via `EngineBuilder.iterationMetadataPrefix()` for standalone Qute or via the `quarkus.qute.iteration-metadata-prefix` configuration property in a Quarkus application. Three special constants can be used: 1. `` - the alias of an iterated element suffixed with an underscore is used (default) 2. `` - the alias of an iterated element suffixed with a question mark is used @@ -787,11 +789,11 @@ You can also use the following operators in a condition: |=== |Operator |Aliases |Precedence (higher wins) -|logical complement -|`!` +|logical complement +|`!` | 4 -|greater than +|greater than |`gt`, `>` | 3 @@ -799,7 +801,7 @@ You can also use the following operators in a condition: |`ge`, `>=` | 3 -|less than +|less than |`lt`, `<` | 3 @@ -807,11 +809,11 @@ You can also use the following operators in a condition: |`le`, `\<=` | 3 -|equals -|`eq`, `==`, `is` +|equals +|`eq`, `==`, `is` | 2 -|not equals +|not equals |`ne`, `!=` | 2 @@ -844,7 +846,7 @@ Multiple conditions are also supported. ---- Precedence rules can be overridden by parentheses. - + .Parentheses example [source] ---- @@ -912,7 +914,7 @@ The parameters of an `is`/`case` block are not evaluated as expressions but comp [source] ---- {#when machine.status} - {#is ON} + {#is ON} It's running. <1> {#is in OFF BROKEN} It's broken or OFF. <2> @@ -930,11 +932,11 @@ The following operators are supported in `is`/`case` block conditions: |=== |Operator |Aliases |Example -|not equal -|`!=`, `not`, `ne` +|not equal +|`!=`, `not`, `ne` |`{#is not 10}`,`{#case != 10}` -|greater than +|greater than |`gt`, `>` |`{#case le 10}` @@ -942,7 +944,7 @@ The following operators are supported in `is`/`case` block conditions: |`ge`, `>=` |`{#is >= 10}` -|less than +|less than |`lt`, `<` |`{#is < 10}` @@ -982,7 +984,7 @@ If a key of a section parameter, such as the name of the local variable, ends wi [source,html] ---- {#let enabled?=true} <1> <2> - {#if enabled}ON{/if} + {#if enabled}ON{/if} {/let} ---- <1> `true` is effectively a _default value_ that is only used if the parent scope does not define `enabled` already. @@ -1061,7 +1063,7 @@ This section can be used to include another template and possibly override some ---- -<1> Include a template with id `foo`. The included template can reference data from the current context. +<1> Include a template with id `foo`. The included template can reference data from the current context. <2> It's also possible to define optional parameters that can be used in the included template. _Template inheritance_ makes it possible to reuse template layouts. @@ -1174,7 +1176,7 @@ For example, we can call the user tag defined below with `{#test 'Martin' readon ---- <1> `it` is replaced with the first unnamed parameter of the tag. <2> `readonly` is a named parameter. -<3> `_args` represents arguments metadata. +<3> `_args` represents arguments metadata. The result would be: @@ -1302,9 +1304,9 @@ An interesting use case would be a fragment that can be used multiple-times insi {/fragment}

    My page

    -

    This document +

    This document {#include $strong val='contains' /} <2> -a lot of +a lot of {#include $strong val='information' /} <3> !

    ---- @@ -1320,9 +1322,9 @@ The snippet above renders something like: [source,html] ----

    My page

    -

    This document +

    This document contains -a lot of +a lot of information !

    ---- @@ -1408,11 +1410,11 @@ template.data(foo).renderAsync().whenComplete((result, failure) -> { <1> } }; ---- -<1> Register a callback that is executed once the rendering is finished. +<1> Register a callback that is executed once the rendering is finished. There are also two methods that return https://smallrye.io/smallrye-mutiny/[Mutiny] types. `TemplateInstance.createUni()` returns a new `Uni` object. -If you call `createUni()` the template is not rendered right away. +If you call `createUni()` the template is not rendered right away. Instead, every time `Uni.subscribe()` is called a new rendering of the template is triggered. .`TemplateInstance.createUni()` Example @@ -1423,7 +1425,7 @@ template.data(foo).createUni().subscribe().with(System.out::println); `TemplateInstance.createMulti()` returns a new `Multi` object. Each item represents a part/chunk of the rendered template. -Again, `createMulti()` does not trigger rendering. +Again, `createMulti()` does not trigger rendering. Instead, every time a computation is triggered by a subscriber the template is rendered again. .`TemplateInstance.createMulti()` Example @@ -1492,7 +1494,7 @@ However, you can disable this functionality via `io.quarkus.qute.EngineBuilder.s TIP: In Quarkus, a dedicated config property can be used instead: `quarkus.qute.strict-rendering`. If you really need to use an expression which can potentially lead to a "not found" error, you can use _default values_ and _safe expressions_ in order to suppress the error. -A default value is used if the previous part of an expression cannot be resolved or resolves to `null`. +A default value is used if the previous part of an expression cannot be resolved or resolves to `null`. You can use the elvis operator to output the default value: `{foo.bar ?: 'baz'}`, which is effectively the same as the following virtual method: `{foo.bar.or('baz')}`. A safe expression ends with the `??` suffix and results in `null` if the expression cannot be resolved. It can be very useful e.g. in `{#if}` sections: `{#if valueNotFound??}Only rendered if valueNotFound is truthy!{/if}`. @@ -1512,7 +1514,7 @@ If you want to use Qute in your Quarkus application, add the following dependenc ---- In Quarkus, a preconfigured engine instance is provided and available for injection - a bean with scope `@ApplicationScoped`, bean type `io.quarkus.qute.Engine` and qualifier `@Default` is registered automatically. -Moreover, all templates located in the `src/main/resources/templates` directory are validated and can be easily injected. +Moreover, all templates located in the `src/main/resources/templates` directory are validated and can be easily injected. [source,java] ---- @@ -1522,7 +1524,7 @@ import io.quarkus.qute.Location; class MyBean { - @Inject + @Inject Template items; <1> @Location("detail/items2_v1.html") <2> @@ -1533,7 +1535,7 @@ class MyBean { } ---- <1> If there is no `Location` qualifier provided, the field name is used to locate the template. In this particular case, the container will attempt to locate a template with path `src/main/resources/templates/items.html`. -<2> The `Location` qualifier instructs the container to inject a template from a path relative from `src/main/resources/templates`. In this case, the full path is `src/main/resources/templates/detail/items2_v1.html`. +<2> The `Location` qualifier instructs the container to inject a template from a path relative from `src/main/resources/templates`. In this case, the full path is `src/main/resources/templates/detail/items2_v1.html`. <3> Inject the configured `Engine` instance. === Engine Customization @@ -1577,19 +1579,19 @@ public class CustomSectionFactory implements SectionHelperFactory getDefaultAliases() { return List.of("custom"); } - + @Override public ParametersInfo getParameters() { // Param "foo" is required return ParametersInfo.builder().addParameter("foo").build(); <3> } - + @Override public Scope initializeBlock(Scope outerScope, BlockInfo block) { block.addExpression("foo", block.getParameter("foo")); return outerScope; } - + @Override public CustomSectionHelper initialize(SectionInitContext context) { @@ -1597,7 +1599,7 @@ public class CustomSectionFactory implements SectionHelperFactory - + @Inject ItemManager manager; @@ -1693,7 +1695,7 @@ For the expression `inject:foo.price`, the implementation class of the injected NOTE: A `ValueResolver` is also generated for all beans annotated with `@Named` so that it's possible to access its properties without reflection. -TIP: If your application serves xref:http-reference.adoc[HTTP requests] you can also inject the current `io.vertx.core.http.HttpServerRequest` via the `inject` namespace, e.g. `{inject:vertxRequest.getParam('foo')}`. +TIP: If your application serves xref:http-reference.adoc[HTTP requests] you can also inject the current `io.vertx.core.http.HttpServerRequest` via the `inject` namespace, e.g. `{inject:vertxRequest.getParam('foo')}`. [[typesafe_expressions]] === Type-safe Expressions @@ -1730,7 +1732,7 @@ Type variables are not handled in a special way and should never be used. ---- <1> Parameter declaration - maps `foo` to `org.acme.Foo`. <2> Not validated - not matching a param declaration. -<3> This expression is validated. `org.acme.Foo` must have a property `message` or a matching template extension method must exist. +<3> This expression is validated. `org.acme.Foo` must have a property `message` or a matching template extension method must exist. <4> Likewise, the Java type of the object resolved from `foo.message` must have a property `toLowerCase` or a matching template extension method must exist. IMPORTANT: A value resolver is automatically generated for all types used in parameter declarations so that it's possible to access its properties without reflection. @@ -1773,7 +1775,7 @@ However, the infix notation is not supported in default values unless the parent IMPORTANT: The type of a default value is not validated in xref:standalone[Qute standalone]. -.More Parameter Declarations Examples +.More Parameter Declarations Examples [source] ---- {@int pages} <1> @@ -1786,8 +1788,8 @@ IMPORTANT: The type of a default value is not validated in xref:standalone[Qute <2> `String` is replaced with `java.lang.String`: `{@java.util.List strings}` <3> The wildcard is ignored and the upper bound is used instead: `{@java.util.Map}` <4> The wildcard is ignored and the `java.lang.Object` is used instead: `{@java.util.Optional}` -<5> The type is `java.lang.String`, the key is `name` and the default value is `Quarkus`. - +<5> The type is `java.lang.String`, the key is `name` and the default value is `Quarkus`. + [[typesafe_templates]] === Type-safe Templates @@ -1849,7 +1851,7 @@ public class ItemResource { TIP: By default, the templates defined in a class annotated with `@CheckedTemplate` can only contain type-safe expressions, i.e. expressions that can be validated at build time. You can use `@CheckedTemplate(requireTypeSafeExpressions = false)` to relax this requirement. ==== Top-level Type-safe Templates - + You can also declare a top-level Java class annotated with `@CheckedTemplate`: .Top-level checked templates @@ -1965,7 +1967,7 @@ public class ItemResource { You can also define a type-safe xref:fragments[fragment] in your Java code. A _native static_ method with the name that contains a dollar sign `$` denotes a method that represents a fragment of a type-safe template. -The name of the fragment is derived from the annotated method name. +The name of the fragment is derived from the annotated method name. The part before the last occurence of a dollar sign `$` is the method name of the related type-safe template. The part after the last occurence of a dollar sign is the fragment identifier. The strategy defined by the relevant `CheckedTemplate#defaultName()` is honored when constructing the defaulted names. @@ -2031,7 +2033,7 @@ Methods that do not meet the following requirements are ignored. A template extension method: * must not be `private` -* must be static, +* must be static, * must not return `void`. If there is no namespace defined the class of the first parameter that is not annotated with `@TemplateAttribute` is used to match the base object. Otherwise, the namespace is used to match an expression. @@ -2110,7 +2112,7 @@ static String itemProperty(Item item, String name) { <1> ---- <1> A additional string method parameter is used to pass the actual property name. -Finally, `matchNames()` can be used to specify a collection of matching names. +Finally, `matchNames()` can be used to specify a collection of matching names. An additional string method parameter is mandatory as well. @@ -2170,7 +2172,7 @@ public class StringExtensions { static String format(String fmt, Object... args) { return String.format(fmt, args); } - + static String reverse(String val) { return new StringBuilder(val).reverse().toString(); } @@ -2258,12 +2260,12 @@ TIP: A list element can be accessed directly via an index: `{list.10}` or even ` ** `{item.name + '_' + mySuffix}` ** `{name + 10}` -===== Config +===== Config * `config:` or `config:[]`: Returns the config value for the given property name ** `{config:foo}` or `{config:['property.with.dot.in.name']}` -* `config:property(name)`: Returns the config value for the given property name; the name can be obtained dynamically by an expression +* `config:property(name)`: Returns the config value for the given property name; the name can be obtained dynamically by an expression ** `{config:property('quarkus.foo')}` ** `{config:property(foo.getPropertyName())}` @@ -2315,7 +2317,7 @@ class Item { public Item(BigDecimal price) { this.price = price; } - + public BigDecimal getDiscountedPrice() { return price.multiply(new BigDecimal("0.9")); } @@ -2364,7 +2366,7 @@ By default, the namespace is the FQCN of the target class where dots and dollar For example, the namespace for a class with name `org.acme.Foo` is `org_acme_Foo`. The static field `Foo.AGE` can be accessed via `{org_acme_Foo:AGE}`. The static method `Foo.computeValue(int number)` can be accessed via `{org_acme_Foo:computeValue(10)}`. - + NOTE: A namespace can only consist of alphanumeric characters and underscores. .Class Annotated With `@TemplateData` @@ -2432,13 +2434,13 @@ enum Color { RED, GREEN, BLUE } @TemplateGlobal <1> public class Globals { - + static int age = 40; - + static Color[] myColors() { return new Color[] { Color.RED, Color.BLUE }; } - + @TemplateGlobal(name = "currentUser") <2> static String user() { return "Mia"; @@ -2671,7 +2673,7 @@ The message bundles can be used at runtime: ---- <1> `msg` is the default namespace. <2> `hello_name` is the message key. -<3> `Lucie` is the parameter of the message bundle interface method. +<3> `Lucie` is the parameter of the message bundle interface method. <4> It is also possible to obtain a localized message for a key resolved at runtime using a reserved key `message`. The validation is skipped in this case though. @@ -2703,14 +2705,14 @@ NOTE: The bundle name is also used as a part of the name of a localized file, e. ==== Bundle Name and Message Keys Message keys are used directly in templates. -The bundle name is used as a namespace in template expressions. -The `@MessageBundle` can be used to define the default strategy used to generate message keys from method names. +The bundle name is used as a namespace in template expressions. +The `@MessageBundle` can be used to define the default strategy used to generate message keys from method names. However, the `@Message` can override this strategy and even define a custom key. -By default, the annotated element's name is used as-is. +By default, the annotated element's name is used as-is. Other possibilities are: 1. De-camel-cased and hyphenated; e.g. `helloName()` -> `hello-name` -2. De-camel-cased and parts separated by underscores; e.g. `helloName()` -> `hello_name`. +2. De-camel-cased and parts separated by underscores; e.g. `helloName()` -> `hello_name`. ==== Validation @@ -2793,10 +2795,10 @@ Alternatively, you can specify the `locale` attribute of a template instance. ---- @Singleton public class MyBean { - + @Inject Template hello; - + String render() { return hello.instance().setAttribute("locale", Locale.forLanguageTag("cs")).render(); <1> } @@ -2814,10 +2816,10 @@ The `@Localized` qualifier can be used to inject a localized message bundle inte ---- @Singleton public class MyBean { - + @Localized("cs") <1> AppMessages msg; - + String render() { return msg.hello_name("Jachym"); } @@ -2870,7 +2872,7 @@ include::{generated-dir}/config/quarkus-qute.adoc[leveloffset=+1, opts=optional] [[standalone]] == Qute Used as a Standalone Library -Qute is primarily designed as a Quarkus extension. +Qute is primarily designed as a Quarkus extension. However. it is possible to use it as a "standalone" library. In this case, some features are not available and some additional configuration is needed. @@ -2890,14 +2892,14 @@ Sections:: * No section helpers are registered by default. * The default set of value resolvers can be registered via the convenient `EngineBuilder.addDefaultSectionHelpers()` method and the `EngineBuilder.addDefaults()` method respectively. -Value resolvers:: +Value resolvers:: * No xref:value-resolvers[``ValueResolver``s] are generated automatically. ** xref:template_extension_methods[`@TemplateExtension` methods] will not work. ** xref:template_data[`@TemplateData`] and xref:convenient-annotation-for-enums[`@TemplateEnum`] annotations are ignored. * The default set of value resolvers can be registered via the convenient `EngineBuilder.addDefaultValueResolvers()` method and the `EngineBuilder.addDefaults()` method respectively. + NOTE: Not all functionality provided by the built-in extension methods is covered by the default value resolvers. However, a custom value resolver can be easily built via the `ValueResolver.builder()`. -* It's recommended to register a `ReflectionValueResolver` instance via `Engine.addValueResolver(new ReflectionValueResolver())` so that Qute can access object properties and call public methods. +* It's recommended to register a `ReflectionValueResolver` instance via `Engine.addValueResolver(new ReflectionValueResolver())` so that Qute can access object properties and call public methods. + NOTE: Keep in mind that reflection may not work correctly in some restricted environments or may require additional configuration, e.g. registration in case of a GraalVM native image. diff --git a/_versions/main/guides/qute.adoc b/_versions/main/guides/qute.adoc index d8e9bdf415..00a841fda1 100644 --- a/_versions/main/guides/qute.adoc +++ b/_versions/main/guides/qute.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: miscellaneous :summary: Learn more about how you can use templating in your applications with the Qute template engine. +:topics: templating,qute +:extensions: io.quarkus:quarkus-qute,io.quarkus:quarkus-resteasy-qute,io.quarkus:quarkus-resteasy-reactive-qute Qute is a templating engine designed specifically to meet the Quarkus needs. The usage of reflection is minimized to reduce the size of native images. diff --git a/_versions/main/guides/rabbitmq-dev-services.adoc b/_versions/main/guides/rabbitmq-dev-services.adoc index 8454327bd5..c99349f7dd 100644 --- a/_versions/main/guides/rabbitmq-dev-services.adoc +++ b/_versions/main/guides/rabbitmq-dev-services.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Dev Services for RabbitMQ include::_attributes.adoc[] +:categories: messaging +:topics: messaging,reactive-messaging,rabbitmq,devservices,tooling,testing,devmode +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-rabbitmq Dev Services for RabbitMQ automatically starts a RabbitMQ broker in dev mode and when running tests. So, you don't have to start a broker manually. diff --git a/_versions/main/guides/rabbitmq-reference.adoc b/_versions/main/guides/rabbitmq-reference.adoc index 84271eff31..586e338c04 100644 --- a/_versions/main/guides/rabbitmq-reference.adoc +++ b/_versions/main/guides/rabbitmq-reference.adoc @@ -5,6 +5,10 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Reactive Messaging RabbitMQ Connector Reference Documentation include::_attributes.adoc[] +:extension-status: preview +:categories: messaging +:topics: messaging,reactive-messaging,rabbitmq,devservices,tooling,testing,devmode +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-rabbitmq This guide is the companion from the xref:rabbitmq.adoc[Getting Started with RabbitMQ]. It explains in more details the configuration and usage of the RabbitMQ connector for reactive messaging. @@ -19,6 +23,8 @@ IMPORTANT: The RabbitMQ connector supports AMQP 0-9-1, which is very different f AMQP 1.0 connector. You can use the AMQP 1.0 connector with RabbitMQ as described in the xref:amqp-reference.adoc[AMQP 1.0 connector reference], albeit with *reduced functionality*. +include::{includes}/extension-status.adoc[] + == RabbitMQ connector extension To use the connector, you need to add the `quarkus-smallrye-reactive-messaging-rabbitmq` extension. diff --git a/_versions/main/guides/rabbitmq.adoc b/_versions/main/guides/rabbitmq.adoc index f0d1117ff4..cdb57e8324 100644 --- a/_versions/main/guides/rabbitmq.adoc +++ b/_versions/main/guides/rabbitmq.adoc @@ -6,6 +6,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Getting Started to SmallRye Reactive Messaging with RabbitMQ :extension-status: preview include::_attributes.adoc[] +:categories: messaging +:topics: messaging,reactive-messaging,rabbitmq,devservices,tooling,testing,devmode +:extensions: io.quarkus:quarkus-smallrye-reactive-messaging-rabbitmq This guide demonstrates how your Quarkus application can utilize SmallRye Reactive Messaging to interact with RabbitMQ. diff --git a/_versions/main/guides/reactive-event-bus.adoc b/_versions/main/guides/reactive-event-bus.adoc index c7f4d069d8..8d6197323b 100644 --- a/_versions/main/guides/reactive-event-bus.adoc +++ b/_versions/main/guides/reactive-event-bus.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: messaging :summary: This guide explains how different beans can interact using the event bus. +:topics: messaging,event-bus,vert.x +:extensions: io.quarkus:quarkus-vertx Quarkus allows different beans to interact using asynchronous events, thus promoting loose-coupling. The messages are sent to _virtual addresses_. diff --git a/_versions/main/guides/reactive-routes.adoc b/_versions/main/guides/reactive-routes.adoc index cf37f6ac36..e5de1a93fb 100644 --- a/_versions/main/guides/reactive-routes.adoc +++ b/_versions/main/guides/reactive-routes.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: web :summary: This guide demonstrates how to use reactive routes. +:topics: http,web,routing +:extensions: io.quarkus:quarkus-reactive-routes Reactive routes propose an alternative approach to implement HTTP endpoints where you declare and chain _routes_. This approach became very popular in the JavaScript world, with frameworks like Express.Js or Hapi. @@ -78,8 +80,8 @@ public class MyDeclarativeRoutes { void hello(RoutingContext rc) { // <3> rc.response().end("hello"); } - - @Route(path = "/world") + + @Route(path = "/world") String helloWorld() { // <4> return "Hello world!"; } @@ -214,20 +216,20 @@ public class SimpleRoutes { } } ---- -<1> The `path` value is used as a prefix for any route method declared on the class where `Route#path()` is used. +<1> The `path` value is used as a prefix for any route method declared on the class where `Route#path()` is used. <2> The value of `produces()` is used for content-based routing for all routes where `Route#produces()` is empty. == Reactive Route Methods A route method must be a non-private non-static method of a CDI bean. -If the annotated method returns `void` then it has to accept at least one argument - see the supported types below. +If the annotated method returns `void` then it has to accept at least one argument - see the supported types below. If the annotated method does not return `void` then the arguments are optional. NOTE: Methods that return `void` must __end__ the response or the HTTP request to this route will never end. Some methods of `RoutingExchange` do it for you, others not and you must call the `end()` method of the response by yourself, please refer to its JavaDoc for more information. -A route method can accept arguments of the following types: +A route method can accept arguments of the following types: * `io.vertx.ext.web.RoutingContext` * `io.quarkus.vertx.web.RoutingExchange` @@ -240,10 +242,10 @@ Furthermore, it is possible to inject the `HttpServerRequest` parameters into me [options="header",cols="1,1"] |=== -|Parameter Type | Obtained via +|Parameter Type | Obtained via //------------- -|`java.lang.String` |`routingContext.request().getParam()` -|`java.util.Optional` |`routingContext.request().getParam()` +|`java.lang.String` |`routingContext.request().getParam()` +|`java.util.Optional` |`routingContext.request().getParam()` |`java.util.List` |`routingContext.request().params().getAll()` |=== @@ -260,10 +262,10 @@ The `HttpServerRequest` headers can be injected into method parameters annotated [options="header",cols="1,1"] |=== -|Parameter Type | Obtained via +|Parameter Type | Obtained via //------------- -|`java.lang.String` |`routingContext.request().getHeader()` -|`java.util.Optional` |`routingContext.request().getHeader()` +|`java.lang.String` |`routingContext.request().getHeader()` +|`java.util.Optional` |`routingContext.request().getHeader()` |`java.util.List` |`routingContext.request().headers().getAll()` |=== @@ -280,13 +282,13 @@ The request body can be injected into a method parameter annotated with `@io.qua [options="header",cols="1,1"] |=== -|Parameter Type | Obtained via +|Parameter Type | Obtained via //------------- -|`java.lang.String` |`routingContext.getBodyAsString()` -|`io.vertx.core.buffer.Buffer` |`routingContext.getBody()` -|`io.vertx.core.json.JsonObject` |`routingContext.getBodyAsJson()` -|`io.vertx.core.json.JsonArray` |`routingContext.getBodyAsJsonArray()` -|any other type |`routingContext.getBodyAsJson().mapTo(MyPojo.class)` +|`java.lang.String` |`routingContext.getBodyAsString()` +|`io.vertx.core.buffer.Buffer` |`routingContext.getBody()` +|`io.vertx.core.json.JsonObject` |`routingContext.getBodyAsJson()` +|`io.vertx.core.json.JsonArray` |`routingContext.getBodyAsJsonArray()` +|any other type |`routingContext.getBodyAsJson().mapTo(MyPojo.class)` |=== .Request Body Example @@ -299,7 +301,7 @@ Person createPerson(@Body Person person, @Param("id") Optional primaryKe } ---- -A failure handler can declare a single method parameter whose type extends `Throwable`. +A failure handler can declare a single method parameter whose type extends `Throwable`. The type of the parameter is used to match the result of `RoutingContext#failure()`. .Failure Handler Example @@ -781,7 +783,7 @@ Also see xref:openapi-swaggerui.adoc[the OpenAPI Guide]. === Adding MicroProfile OpenAPI Annotations -You can use link:https://github.com/eclipse/microprofile-open-api[MicroProfile OpenAPI] to better document your schema, +You can use link:https://github.com/eclipse/microprofile-open-api[MicroProfile OpenAPI] to better document your schema, for instance, adding header info, or specifying the return type on `void` methods might be useful: [source, java] @@ -803,21 +805,21 @@ public class MyDeclarativeRoutes { // neither path nor regex is set - match a path derived from the method name @Route(methods = Route.HttpMethod.GET) - @APIResponse(responseCode="200", - description="Say hello", + @APIResponse(responseCode="200", + description="Say hello", content=@Content(mediaType="application/json", schema=@Schema(type=SchemaType.STRING))) // <2> void hello(RoutingContext rc) { rc.response().end("hello"); } - - @Route(path = "/world") + + @Route(path = "/world") String helloWorld() { return "Hello world!"; } @Route(path = "/greetings", methods = HttpMethod.GET) - @APIResponse(responseCode="200", - description="Greeting", + @APIResponse(responseCode="200", + description="Greeting", content=@Content(mediaType="application/json", schema=@Schema(type=SchemaType.STRING))) void greetings(RoutingExchange ex) { ex.ok("hello " + ex.getParam("name").orElse("world")); diff --git a/_versions/main/guides/reactive-sql-clients.adoc b/_versions/main/guides/reactive-sql-clients.adoc index 96f23519cc..c81c84d7f0 100644 --- a/_versions/main/guides/reactive-sql-clients.adoc +++ b/_versions/main/guides/reactive-sql-clients.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: data :summary: This guide covers how to use the Reactive SQL Clients in Quarkus. :config-file: application.properties +:topics: data,database,reactive,sql +:extensions: io.quarkus:quarkus-reactive-mysql-client,io.quarkus:quarkus-reactive-oracle-client,io.quarkus:quarkus-reactive-pg-client,io.quarkus:quarkus-reactive-db2-client,io.quarkus:quarkus-reactive-pg-client,io.quarkus:quarkus-reactive-mssql-client The Reactive SQL Clients have a straightforward API focusing on scalability and low-overhead. Currently, the following database servers are supported: diff --git a/_versions/main/guides/reaugmentation.adoc b/_versions/main/guides/reaugmentation.adoc index d95d0bee6b..4e36e653da 100644 --- a/_versions/main/guides/reaugmentation.adoc +++ b/_versions/main/guides/reaugmentation.adoc @@ -7,10 +7,11 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: tooling :summary: Use mutable jars to rebuild your application with different build time configurations. +:topics: mutable-jars,tooling == What is augmentation? -Quarkus application configuration may include two types of configuration options: +Quarkus application configuration may include two types of configuration options: - Build time options, handled during the application build time; - Runtime options, that may be adjusted after the application has been built but before it has been launched. diff --git a/_versions/main/guides/redis-dev-services.adoc b/_versions/main/guides/redis-dev-services.adoc index 1daf74defb..0572c08e43 100644 --- a/_versions/main/guides/redis-dev-services.adoc +++ b/_versions/main/guides/redis-dev-services.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: data :summary: Start Redis automatically in dev and test modes. +:topics: data,redis,nosql,devservices,tooling,testing,devmode +:extensions: io.quarkus:quarkus-redis-client Quarkus supports a feature called Dev Services that allows you to create various datasources without any config. What that means practically, is that if you have docker running and have not configured `quarkus.redis.hosts`, diff --git a/_versions/main/guides/redis-reference.adoc b/_versions/main/guides/redis-reference.adoc index 7b43a51a12..1b6c49c19a 100644 --- a/_versions/main/guides/redis-reference.adoc +++ b/_versions/main/guides/redis-reference.adoc @@ -8,6 +8,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :numbered: :sectnums: +:categories: data +:topics: data,redis,nosql +:extensions: io.quarkus:quarkus-redis-client Redis is an in-memory data store used as a database, cache, streaming engine, and message broker. The Quarkus Redis extension allows integrating Quarkus applications with Redis. diff --git a/_versions/main/guides/redis.adoc b/_versions/main/guides/redis.adoc index 71a3beca1d..12afc6a99e 100644 --- a/_versions/main/guides/redis.adoc +++ b/_versions/main/guides/redis.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc :extension-status: preview include::_attributes.adoc[] :categories: data +:topics: data,redis,nosql +:extensions: io.quarkus:quarkus-redis-client :summary: This guide covers how to use a Redis datastore in Quarkus. This guide demonstrates how your Quarkus application can connect to a Redis server using the Redis Client extension. diff --git a/_versions/main/guides/rest-client-multipart.adoc b/_versions/main/guides/rest-client-multipart.adoc index c6a15e0739..17def53f8e 100644 --- a/_versions/main/guides/rest-client-multipart.adoc +++ b/_versions/main/guides/rest-client-multipart.adoc @@ -6,7 +6,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Using the legacy REST Client with Multipart include::_attributes.adoc[] :categories: web -:summary: This guide explains how to use the RESTEasy REST Client to send multipart REST requests, typically to upload documents. +:summary: This guide explains how to use the RESTEasy Classic REST Client to send multipart REST requests, typically to upload documents. +:topics: rest,rest-client,multipart,resteasy-classic +:extensions: io.quarkus:quarkus-rest-client,io.quarkus:quarkus-resteasy-multipart [WARNING] ==== diff --git a/_versions/main/guides/rest-client-reactive.adoc b/_versions/main/guides/rest-client-reactive.adoc index 18b4bded6d..2dea767f94 100644 --- a/_versions/main/guides/rest-client-reactive.adoc +++ b/_versions/main/guides/rest-client-reactive.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: web :summary: This guide explains how to use the RESTEasy Reactive REST Client. +:topics: rest,rest-client,resteasy-reactive +:extensions: io.quarkus:quarkus-rest-client-reactive,io.quarkus:quarkus-rest-client-reactive-jackson,io.quarkus:quarkus-rest-client-reactive-jsonb This guide explains how to use the REST Client Reactive in order to interact with REST APIs. REST Client Reactive is the REST Client implementation compatible with RESTEasy Reactive. @@ -1103,7 +1105,7 @@ public class TestClientRequestFilter implements ResteasyReactiveClientRequestFil == Customizing the ObjectMapper in REST Client Reactive Jackson -The REST Client Reactive supports adding a custom ObjectMapper to be used only the Client using the annotation `@ClientObjectMapper`. +The REST Client Reactive supports adding a custom ObjectMapper to be used only the Client using the annotation `@ClientObjectMapper`. A simple example is to provide a custom ObjectMapper to the REST Client Reactive Jackson extension by doing: @@ -1127,7 +1129,7 @@ public interface ExtensionsService { <1> The method must be annotated with `@ClientObjectMapper`. <2> It's must be a static method. Also, the parameter `defaultObjectMapper` will be resolved via CDI. If not found, it will throw an exception at runtime. -<3> In this example, we're creating a copy of the default object mapper. You should *NEVER* modify the default object mapper, but create a copy instead. +<3> In this example, we're creating a copy of the default object mapper. You should *NEVER* modify the default object mapper, but create a copy instead. == Exception handling diff --git a/_versions/main/guides/rest-client.adoc b/_versions/main/guides/rest-client.adoc index bfdfb027ec..aaeb8dc432 100644 --- a/_versions/main/guides/rest-client.adoc +++ b/_versions/main/guides/rest-client.adoc @@ -6,7 +6,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Using the legacy REST Client include::_attributes.adoc[] :categories: web -:summary: This guide explains how to use the RESTEasy REST Client in order to interact with REST APIs (JSON and other) with very little effort. +:summary: This guide explains how to use the RESTEasy Classic REST Client in order to interact with REST APIs (JSON and other) with very little effort. +:topics: rest,rest-client,resteasy-classic +:extensions: io.quarkus:quarkus-rest-client,io.quarkus:quarkus-rest-client-jackson,io.quarkus:quarkus-rest-client-jsonb [WARNING] ==== @@ -347,11 +349,11 @@ A HTTP server can redirect a response to another location by sending a response - `quarkus.rest-client.follow-redirects` to enable redirection for all REST clients. - `quarkus.rest-client..follow-redirects` to enable redirection for a specific REST client. -If this property is true, then REST Client will perform a new request that it receives a redirection response from the HTTP server. +If this property is true, then REST Client will perform a new request that it receives a redirection response from the HTTP server. Additionally, we can limit the number of redirections using the property "max-redirects". -One important note is that according to the https://www.rfc-editor.org/rfc/rfc2616#section-10.3.8[RFC2616] specs, by default the redirection will only happen for GET or HEAD methods. +One important note is that according to the https://www.rfc-editor.org/rfc/rfc2616#section-10.3.8[RFC2616] specs, by default the redirection will only happen for GET or HEAD methods. == Async Support diff --git a/_versions/main/guides/rest-data-panache.adoc b/_versions/main/guides/rest-data-panache.adoc index df9a531a48..413275ad9a 100644 --- a/_versions/main/guides/rest-data-panache.adoc +++ b/_versions/main/guides/rest-data-panache.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: web :summary: Hibernate ORM REST Data with Panache simplifies the creation of CRUD applications based on Jakarta REST and Hibernate ORM. +:topics: rest,hibernate-orm,panache,mongodb,sql,jdbc,nosql +:extensions: io.quarkus:quarkus-hibernate-orm-rest-data-panache,io.quarkus:quarkus-hibernate-reactive-rest-data-panache,io.quarkus:quarkus-mongodb-rest-data-panache A lot of web applications are monotonous CRUD applications with REST APIs that are tedious to write. To streamline this task, REST Data with Panache extension can generate the basic CRUD endpoints for your entities and repositories. @@ -425,7 +427,7 @@ public class Person extends PanacheEntity { } ---- -In this example, we have added a named query to list all the persons that contains some text in the `name` field. +In this example, we have added a named query to list all the persons that contains some text in the `name` field. Next, we can set a query param `namedQuery` when listing the entities using the generated resource with the name of the named query that we want to use, for example, calling `http://localhost:8080/people?namedQuery=Person.containsInName&name=ter` would return all the persons which name contains the text "ter". @@ -433,7 +435,7 @@ For more information about how named queries work, go to the xref:hibernate-orm- == Resource Method Before/After Listeners -REST Data with Panache supports the subscription to the following resource method hooks: +REST Data with Panache supports the subscription to the following resource method hooks: * Before/After add resource * Before/After update resource diff --git a/_versions/main/guides/rest-json.adoc b/_versions/main/guides/rest-json.adoc index 5c4c6a2461..c55c6061ee 100644 --- a/_versions/main/guides/rest-json.adoc +++ b/_versions/main/guides/rest-json.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: web, serialization :summary: JSON is now the lingua franca between microservices. In this guide, we see how you can get your REST services to consume and produce JSON payloads. +:topics: rest,json,resteasy-reactive +:extensions: io.quarkus:quarkus-resteasy-reactive-jackson,io.quarkus:quarkus-resteasy-reactive-jsonb,io.quarkus:quarkus-resteasy-reactive JSON is now the _lingua franca_ between microservices. @@ -226,7 +228,7 @@ public class RegisterCustomModuleCustomizer implements ObjectMapperCustomizer { Users can even provide their own `ObjectMapper` bean if they so choose. If this is done, it is very important to manually inject and apply all `io.quarkus.jackson.ObjectMapperCustomizer` beans in the CDI producer that produces `ObjectMapper`. -Failure to do so will prevent Jackson specific customizations provided by various extensions from being applied. +Failure to do so will prevent Jackson specific customizations provided by various extensions from being applied. [source,java] ---- diff --git a/_versions/main/guides/resteasy-reactive-migration.adoc b/_versions/main/guides/resteasy-reactive-migration.adoc index e1296b1649..46680e65db 100644 --- a/_versions/main/guides/resteasy-reactive-migration.adoc +++ b/_versions/main/guides/resteasy-reactive-migration.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Migrating to RESTEasy Reactive include::_attributes.adoc[] +:categories: web +:topics: rest,rest-client,resteasy-reactive +:extensions: io.quarkus:quarkus-resteasy-reactive,io.quarkus:quarkus-resteasy-reactive-jackson,io.quarkus:quarkus-resteasy-reactive-jsonb,io.quarkus:quarkus-rest-client-reactive,io.quarkus:quarkus-rest-client-reactive-jackson,io.quarkus:quarkus-rest-client-reactive-jsonb Migrating from RESTEasy Classic to RESTEasy Reactive is straightforward in most cases, however there are a few cases that require some attention. This document provides a list of issues users attempting the migration should be aware of. diff --git a/_versions/main/guides/resteasy-reactive-virtual-threads.adoc b/_versions/main/guides/resteasy-reactive-virtual-threads.adoc index f35b685f04..9c807b08e0 100644 --- a/_versions/main/guides/resteasy-reactive-virtual-threads.adoc +++ b/_versions/main/guides/resteasy-reactive-virtual-threads.adoc @@ -9,6 +9,8 @@ include::_attributes.adoc[] :diataxis-type: howto :categories: web, core :summary: How to use virtual threads in a REST application +:topics: rest,resteasy-reactive,virtual-threads +:extensions: io.quarkus:quarkus-resteasy-reactive,io.quarkus:quarkus-resteasy-reactive-jackson,io.quarkus:quarkus-resteasy-reactive-jsonb,io.quarkus:quarkus-rest-client-reactive,io.quarkus:quarkus-rest-client-reactive-jackson,io.quarkus:quarkus-rest-client-reactive-jsonb In this guide, we see how you can use virtual threads in a REST application. Because virtual threads are all about I/O, we will also use the REST client. diff --git a/_versions/main/guides/resteasy-reactive.adoc b/_versions/main/guides/resteasy-reactive.adoc index 47267f8dd4..c941af7880 100644 --- a/_versions/main/guides/resteasy-reactive.adoc +++ b/_versions/main/guides/resteasy-reactive.adoc @@ -6,6 +6,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Writing REST Services with RESTEasy Reactive include::_attributes.adoc[] :categories: web +:topics: rest,resteasy-reactive,virtual-threads +:extensions: io.quarkus:quarkus-resteasy-reactive,io.quarkus:quarkus-resteasy-reactive-jackson,io.quarkus:quarkus-resteasy-reactive-jsonb,io.quarkus:quarkus-rest-client-reactive,io.quarkus:quarkus-rest-client-reactive-jackson,io.quarkus:quarkus-rest-client-reactive-jsonb :summary: Discover how to develop highly scalable reactive REST services with Jakarta REST and RESTEasy Reactive. :jaxrsapi: https://javadoc.io/doc/jakarta.ws.rs/jakarta.ws.rs-api/3.1.0/jakarta.ws.rs :jaxrsspec: https://jakarta.ee/specifications/restful-ws/3.1/jakarta-restful-ws-spec-3.1.html diff --git a/_versions/main/guides/resteasy.adoc b/_versions/main/guides/resteasy.adoc index 7d608174e0..7a61e59a37 100644 --- a/_versions/main/guides/resteasy.adoc +++ b/_versions/main/guides/resteasy.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = RESTEasy Classic include::_attributes.adoc[] +:categories: web +:topics: rest,resteasy-classic +:extensions: io.quarkus:quarkus-resteasy,io.quarkus:quarkus-resteasy-jackson,io.quarkus:quarkus-resteasy-jsonb [WARNING] ==== diff --git a/_versions/main/guides/scheduler-reference.adoc b/_versions/main/guides/scheduler-reference.adoc index 302ea483bc..cd3f4fe37a 100644 --- a/_versions/main/guides/scheduler-reference.adoc +++ b/_versions/main/guides/scheduler-reference.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :numbered: :sectnums: :sectnumlevels: 4 +:topics: scheduling,cronjob +:extensions: io.quarkus:quarkus-scheduler Modern applications often need to run specific tasks periodically. There are two scheduler extensions in Quarkus. @@ -17,7 +19,7 @@ The `quarkus-scheduler` extension brings the API and a lightweight in-memory sch The `quarkus-quartz` extension implements the API from the `quarkus-scheduler` extension and contains a scheduler implementation based on the Quartz library. You will only need `quarkus-quartz` for more advanced scheduling use cases, such as persistent tasks and clustering. -NOTE: If you add the `quarkus-quartz` dependency to your project the lightweight scheduler implementation from the `quarkus-scheduler` extension is automatically disabled. +NOTE: If you add the `quarkus-quartz` dependency to your project the lightweight scheduler implementation from the `quarkus-scheduler` extension is automatically disabled. == Scheduled Methods @@ -41,7 +43,7 @@ class Jobs { @Scheduled(every = "1s") void everySecond() { - // ..do something + // ..do something } } @@ -131,7 +133,7 @@ void myMethod() { } ==== Intervals An interval trigger defines a period between invocations. -The period expression is based on the ISO-8601 duration format `PnDTnHnMn.nS` and the value of `@Scheduled#every()` is parsed with `java.time.Duration#parse(CharSequence)`. +The period expression is based on the ISO-8601 duration format `PnDTnHnMn.nS` and the value of `@Scheduled#every()` is parsed with `java.time.Duration#parse(CharSequence)`. However, if an expression starts with a digit then the `PT` prefix is added automatically. So for example, `15m` can be used instead of `PT15M` and is parsed as "15 minutes". @@ -202,7 +204,7 @@ void everyTwoSeconds() { } NOTE: The final value is always rounded to full second. `@Scheduled#delayed()` is a text alternative to the properties above. -The period expression is based on the ISO-8601 duration format `PnDTnHnMn.nS` and the value is parsed with `java.time.Duration#parse(CharSequence)`. +The period expression is based on the ISO-8601 duration format `PnDTnHnMn.nS` and the value is parsed with `java.time.Duration#parse(CharSequence)`. However, if an expression starts with a digit, the `PT` prefix is added automatically. So for example, `15s` can be used instead of `PT15S` and is parsed as "15 seconds". @@ -256,7 +258,7 @@ The specified bean class must implement `io.quarkus.scheduler.Scheduled.SkipPred [source,java] ---- class Jobs { - + @Scheduled(every = "1s", skipExecutionIf = MyPredicate.class) <1> void everySecond() { // do something every second... @@ -286,7 +288,7 @@ class Jobs { @Inject MyService service; - + @Scheduled(every = "1s") void everySecond() { if (service.isStarted()) { @@ -303,14 +305,14 @@ TIP: A CDI event of type `io.quarkus.scheduler.SkippedExecution` is fired when a [[non-blocking-methods]] === Non-blocking Methods -By default, a scheduled method is executed on the main executor for blocking tasks. +By default, a scheduled method is executed on the main executor for blocking tasks. As a result, a technology that is designed to run on a Vert.x event loop (such as Hibernate Reactive) cannot be used inside the method body. For this reason, a scheduled method that returns `java.util.concurrent.CompletionStage` or `io.smallrye.mutiny.Uni`, or is annotated with `@io.smallrye.common.annotation.NonBlocking` is executed on the Vert.x event loop instead. [source,java] ---- class Jobs { - + @Scheduled(every = "1s") Uni everySecond() { <1> // ...do something async @@ -383,10 +385,10 @@ class MyJobs { }) .schedule(); <3> } - + void removeMyJob() { scheduler.unscheduleJob("myJob"); <4> - } + } } ---- <1> This is a programmatic alternative to a method annotated with `@Scheduled(identity = "myJob", cron = "0/5 * * * * ?")`. @@ -407,7 +409,7 @@ You can even disable the scheduler for particular xref:getting-started-testing.a == Metrics -Some basic metrics are published out of the box if `quarkus.scheduler.metrics.enabled` is set to `true` and a metrics extension is present. +Some basic metrics are published out of the box if `quarkus.scheduler.metrics.enabled` is set to `true` and a metrics extension is present. If the xref:telemetry-micrometer.adoc[Micrometer extension] is present, then a `@io.micrometer.core.annotation.Timed` interceptor binding is added to all `@Scheduled` methods automatically (unless it's already present) and a `io.micrometer.core.instrument.Timer` with name `scheduled.methods` and a `io.micrometer.core.instrument.LongTaskTimer` with name `scheduled.methods.running` are registered. The fully qualified name of the declaring class and the name of a `@Scheduled` method are used as tags. diff --git a/_versions/main/guides/scheduler.adoc b/_versions/main/guides/scheduler.adoc index b445bb75dd..b402f01251 100644 --- a/_versions/main/guides/scheduler.adoc +++ b/_versions/main/guides/scheduler.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: miscellaneous :summary: Modern applications often need to run specific tasks periodically. In this guide, you learn how to schedule periodic tasks. +:topics: scheduling,cronjob +:extensions: io.quarkus:quarkus-scheduler Modern applications often need to run specific tasks periodically. In this guide, you learn how to schedule periodic tasks. diff --git a/_versions/main/guides/scripting.adoc b/_versions/main/guides/scripting.adoc index a09fe783cf..4b7fa39202 100644 --- a/_versions/main/guides/scripting.adoc +++ b/_versions/main/guides/scripting.adoc @@ -8,6 +8,7 @@ include::_attributes.adoc[] :categories: command-line :summary: Easy Quarkus-based scripting with jbang. :extension-status: preview +:topics: scripting,jbang Quarkus provides integration with https://jbang.dev[jbang] which allows you to write Java scripts/applications requiring no Maven nor Gradle to get running. diff --git a/_versions/main/guides/security-architecture.adoc b/_versions/main/guides/security-architecture.adoc index ef3bcebd2d..9ed77730be 100644 --- a/_versions/main/guides/security-architecture.adoc +++ b/_versions/main/guides/security-architecture.adoc @@ -8,6 +8,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: concept :categories: security +:topics: security The Quarkus Security architecture provides several built-in authentication mechanisms and is highly customizable. The primary mechanism for securing HTTP applications in Quarkus is the `HttpAuthenticationMechanism` interface. diff --git a/_versions/main/guides/security-authentication-mechanisms.adoc b/_versions/main/guides/security-authentication-mechanisms.adoc index 64d144f783..a3fd149958 100644 --- a/_versions/main/guides/security-authentication-mechanisms.adoc +++ b/_versions/main/guides/security-authentication-mechanisms.adoc @@ -8,6 +8,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: concept :categories: security,web +:topics: security,authentication The Quarkus Security framework supports multiple authentication mechanisms, which you can use to secure your applications. You can also combine authentication mechanisms. diff --git a/_versions/main/guides/security-authorize-web-endpoints-reference.adoc b/_versions/main/guides/security-authorize-web-endpoints-reference.adoc index 6daf2ecf4c..ea559b8667 100644 --- a/_versions/main/guides/security-authorize-web-endpoints-reference.adoc +++ b/_versions/main/guides/security-authorize-web-endpoints-reference.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: reference :categories: security,web +:topics: security,authorization,http,rest +:extensions: io.quarkus:quarkus-vertx-http,io.quarkus:quarkus-resteasy-reactive,io.quarkus:quarkus-resteasy Quarkus has an integrated pluggable web security layer. If security is enabled, all HTTP requests have a permission check performed to verify that they are allowed to continue. @@ -725,7 +727,7 @@ CAUTION: Annotation permissions do not work with the custom xref:security-custom == References * xref:security-overview.adoc[Quarkus Security overview] -* xref:security-architecture.adoc[Quarkus Security architecture] +* xref:security-architecture.adoc[Quarkus Security architecture] * xref:security-authentication-mechanisms.adoc#other-supported-authentication-mechanisms[Authentication mechanisms in Quarkus] * xref:security-basic-authentication.adoc[Basic authentication] * xref:security-basic-authentication-tutorial.adoc[Secure a Quarkus application with Basic authentication and Jakarta Persistence] diff --git a/_versions/main/guides/security-basic-authentication-howto.adoc b/_versions/main/guides/security-basic-authentication-howto.adoc index f298a74372..aadcca73c6 100644 --- a/_versions/main/guides/security-basic-authentication-howto.adoc +++ b/_versions/main/guides/security-basic-authentication-howto.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: howto :categories: security +:topics: security,authentication,basic-authentication,http +:extensions: io.quarkus:quarkus-vertx-http,io.quarkus:quarkus-elytron-security-jdbc,io.quarkus:quarkus-elytron-security-ldap,io.quarkus:quarkus-security-jpa-reactive Enable xref:security-basic-authentication.adoc[Basic authentication] for your Quarkus project and allow users to authenticate with a username and password. diff --git a/_versions/main/guides/security-basic-authentication-tutorial.adoc b/_versions/main/guides/security-basic-authentication-tutorial.adoc index b89c9fdcb3..258f2df301 100644 --- a/_versions/main/guides/security-basic-authentication-tutorial.adoc +++ b/_versions/main/guides/security-basic-authentication-tutorial.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: tutorial :categories: security,getting-started +:topics: security,authentication,basic-authentication,http +:extensions: io.quarkus:quarkus-vertx-http,io.quarkus:quarkus-elytron-security-jdbc,io.quarkus:quarkus-elytron-security-ldap,io.quarkus:quarkus-security-jpa-reactive Secure your Quarkus application endpoints by combining the built-in Quarkus xref:security-basic-authentication.adoc[Basic authentication] with the Jakarta Persistence identity provider to enable role-based access control (RBAC). The Jakarta Persistence `IdentityProvider` creates a `SecurityIdentity` instance, which is used during user authentication to verify and authorize access requests making your Quarkus application secure. diff --git a/_versions/main/guides/security-basic-authentication.adoc b/_versions/main/guides/security-basic-authentication.adoc index 5962a78d6b..83e15cb7dd 100644 --- a/_versions/main/guides/security-basic-authentication.adoc +++ b/_versions/main/guides/security-basic-authentication.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: concept :categories: security,web +:topics: security,authentication,basic-authentication,http +:extensions: io.quarkus:quarkus-vertx-http,io.quarkus:quarkus-elytron-security-jdbc,io.quarkus:quarkus-elytron-security-ldap,io.quarkus:quarkus-security-jpa-reactive HTTP Basic authentication is one of the least resource-demanding techniques that enforce access controls to web resources. You can secure your Quarkus application endpoints with HTTP Basic authentication. diff --git a/_versions/main/guides/security-csrf-prevention.adoc b/_versions/main/guides/security-csrf-prevention.adoc index a417f5f086..e4a68aa44c 100644 --- a/_versions/main/guides/security-csrf-prevention.adoc +++ b/_versions/main/guides/security-csrf-prevention.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Cross-Site Request Forgery Prevention include::_attributes.adoc[] +:categories: security +:topics: security,csrf,http +:extensions: io.quarkus:quarkus-csrf-reactive https://owasp.org/www-community/attacks/csrf[Cross-Site Request Forgery (CSRF)] is an attack that forces an end user to execute unwanted actions on a web application in which they are currently authenticated. diff --git a/_versions/main/guides/security-customization.adoc b/_versions/main/guides/security-customization.adoc index fedc190135..f46f881338 100644 --- a/_versions/main/guides/security-customization.adoc +++ b/_versions/main/guides/security-customization.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Security Tips and Tricks include::_attributes.adoc[] +:categories: security +:topics: security +:extensions: io.quarkus:quarkus-security == Quarkus Security Dependency diff --git a/_versions/main/guides/security-identity-providers.adoc b/_versions/main/guides/security-identity-providers.adoc index 311846c251..af2e5b1231 100644 --- a/_versions/main/guides/security-identity-providers.adoc +++ b/_versions/main/guides/security-identity-providers.adoc @@ -7,6 +7,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: concept :categories: security +:topics: security,identity-providers +:extensions: io.quarkus:quarkus-elytron-security-jdbc,io.quarkus:quarkus-elytron-security-ldap,io.quarkus:quarkus-security-jpa-reactive + In the Quarkus Security framework, identity providers play a crucial role in authentication and authorization by verifying user identities. `IdentityProvider` creates a `SecurityIdentity` instance, which gets used during user authentication to verify and authorize access requests to your Quarkus application. diff --git a/_versions/main/guides/security-jdbc.adoc b/_versions/main/guides/security-jdbc.adoc index 555bea19bf..3368063817 100644 --- a/_versions/main/guides/security-jdbc.adoc +++ b/_versions/main/guides/security-jdbc.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: security :summary: This guide demonstrates how your Quarkus application can use a database to store your user identities. +:topics: security,identity-providers,jdbc,sql,database +:extensions: io.quarkus:quarkus-elytron-security-jdbc This guide demonstrates how your Quarkus application can use a database to store your user identities. diff --git a/_versions/main/guides/security-jpa.adoc b/_versions/main/guides/security-jpa.adoc index 8a5eaf4d13..6274244627 100644 --- a/_versions/main/guides/security-jpa.adoc +++ b/_versions/main/guides/security-jpa.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc = Quarkus Security with Jakarta Persistence include::_attributes.adoc[] :categories: security +:topics: security,identity-providers,sql,database,jpa,jdbc +:extensions: io.quarkus:quarkus-security-jpa-reactive Quarkus provides a Jakarta Persistence (formerly known as JPA) identity provider, similar to the xref:security-jdbc.adoc[JDBC identity provider], suitable for use with the xref:security-basic-authentication.adoc[Basic] and xref:security-authentication-mechanisms.adoc#form-auth[Form-based] Quarkus Security mechanisms, which require a combination of username and password credentials. diff --git a/_versions/main/guides/security-jwt-build.adoc b/_versions/main/guides/security-jwt-build.adoc index d96d1c1c8f..243e18466b 100644 --- a/_versions/main/guides/security-jwt-build.adoc +++ b/_versions/main/guides/security-jwt-build.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Build, Sign and Encrypt JSON Web Tokens include::_attributes.adoc[] +:categories: security +:topics: security,jwt +:extensions: io.quarkus:quarkus-smallrye-jwt-build According to link:https://datatracker.ietf.org/doc/html/rfc7519[RFC7519], JSON Web Token (JWT) is a compact, URL-safe means of representing claims which are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code(MAC) and/or encrypted. diff --git a/_versions/main/guides/security-jwt.adoc b/_versions/main/guides/security-jwt.adoc index 3eb7fbad7f..f1464d5cab 100644 --- a/_versions/main/guides/security-jwt.adoc +++ b/_versions/main/guides/security-jwt.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :summary: This guide explains how your application can utilize SmallRye JWT to provide secured access to the Jakarta REST endpoints. :extension-name: SmallRye JWT :mp-jwt: MicroProfile JWT RBAC +:topics: security,jwt +:extensions: io.quarkus:quarkus-smallrye-jwt This guide explains how your Quarkus application can utilize https://github.com/smallrye/smallrye-jwt/[SmallRye JWT] to verify https://tools.ietf.org/html/rfc7519[JSON Web Token]s, represent them as MicroProfile JWT `org.eclipse.microprofile.jwt.JsonWebToken` diff --git a/_versions/main/guides/security-keycloak-admin-client.adoc b/_versions/main/guides/security-keycloak-admin-client.adoc index 7a82118a0c..32841fdb5c 100644 --- a/_versions/main/guides/security-keycloak-admin-client.adoc +++ b/_versions/main/guides/security-keycloak-admin-client.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: security :keywords: sso oidc security keycloak +:topics: security,authentication,authorization,keycloak,sso +:extensions: io.quarkus:quarkus-keycloak-admin-client-reactive,io.quarkus:quarkus-keycloak-admin-client The Quarkus Keycloak Admin Client and its reactive twin support Keycloak Admin Client which can be used to configure a running Keycloak server. diff --git a/_versions/main/guides/security-keycloak-authorization.adoc b/_versions/main/guides/security-keycloak-authorization.adoc index f8b5024e74..26724e7e8e 100644 --- a/_versions/main/guides/security-keycloak-authorization.adoc +++ b/_versions/main/guides/security-keycloak-authorization.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: security :keywords: sso oidc security keycloak :summary: This guide demonstrates how your Quarkus application can authorize access to protected resources using Keycloak Authorization Services. +:topics: security,authentication,authorization,keycloak,sso,oidc +:extensions: io.quarkus:quarkus-oidc,io.quarkus:quarkus-keycloak-authorization This guide demonstrates how your Quarkus application can authorize a bearer token access to protected resources using https://www.keycloak.org/docs/latest/authorization_services/index.html[Keycloak Authorization Services]. diff --git a/_versions/main/guides/security-ldap.adoc b/_versions/main/guides/security-ldap.adoc index f35abecce8..c33a0e10a8 100644 --- a/_versions/main/guides/security-ldap.adoc +++ b/_versions/main/guides/security-ldap.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: security :summary: This guide demonstrates how your Quarkus application can use a LDAP directory to store your user identities. +:topics: security,identity-providers,ldap +:extensions: io.quarkus:quarkus-elytron-security-ldap This guide demonstrates how your Quarkus application can use an LDAP server to authenticate and authorize your user identities. diff --git a/_versions/main/guides/security-oauth2.adoc b/_versions/main/guides/security-oauth2.adoc index 47b4199a03..2038fd0966 100644 --- a/_versions/main/guides/security-oauth2.adoc +++ b/_versions/main/guides/security-oauth2.adoc @@ -9,6 +9,8 @@ include::_attributes.adoc[] :keywords: oauth :summary: This guide explains how your Quarkus application can utilize OAuth2 tokens to provide secured access to the Jakarta REST endpoints. :extension-name: Elytron Security OAuth2 +:topics: security,oauth2,identity-providers +:extensions: io.quarkus:quarkus-elytron-security-oauth2 This guide explains how your Quarkus application can utilize OAuth2 tokens to provide secured access to the Jakarta REST (formerly known as JAX-RS) endpoints. diff --git a/_versions/main/guides/security-oidc-bearer-token-authentication-tutorial.adoc b/_versions/main/guides/security-oidc-bearer-token-authentication-tutorial.adoc index d739b828c6..64ddabba25 100644 --- a/_versions/main/guides/security-oidc-bearer-token-authentication-tutorial.adoc +++ b/_versions/main/guides/security-oidc-bearer-token-authentication-tutorial.adoc @@ -8,6 +8,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: tutorial :categories: security +:topics: security,oidc,bearer-token,keycloak,authentication +:extensions: io.quarkus:quarkus-oidc + Use the Quarkus OpenID Connect (OIDC) extension to secure a Jakarta REST application with Bearer token authentication. The bearer tokens are issued by OIDC and OAuth 2.0 compliant authorization servers, such as link:https://www.keycloak.org[Keycloak]. diff --git a/_versions/main/guides/security-oidc-bearer-token-authentication.adoc b/_versions/main/guides/security-oidc-bearer-token-authentication.adoc index 3abdc2f70e..54ccf000af 100644 --- a/_versions/main/guides/security-oidc-bearer-token-authentication.adoc +++ b/_versions/main/guides/security-oidc-bearer-token-authentication.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: concept :categories: security,web +:topics: security,oidc,bearer-token,keycloak,authentication +:extensions: io.quarkus:quarkus-oidc Secure HTTP access to Jakarta REST (formerly known as JAX-RS) endpoints in your application with Bearer token authentication by using the Quarkus OpenID Connect (OIDC) extension. diff --git a/_versions/main/guides/security-oidc-code-flow-authentication-tutorial.adoc b/_versions/main/guides/security-oidc-code-flow-authentication-tutorial.adoc index da32b470a9..6351e7a439 100644 --- a/_versions/main/guides/security-oidc-code-flow-authentication-tutorial.adoc +++ b/_versions/main/guides/security-oidc-code-flow-authentication-tutorial.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: tutorial :categories: security,web +:topics: security,oidc,keycloak,authorization +:extensions: io.quarkus:quarkus-oidc With the Quarkus OpenID Connect (OIDC) extension, you can protect application HTTP endpoints by using the OIDC Authorization Code Flow mechanism. diff --git a/_versions/main/guides/security-oidc-code-flow-authentication.adoc b/_versions/main/guides/security-oidc-code-flow-authentication.adoc index fb2048a51b..c9cfa70ef5 100644 --- a/_versions/main/guides/security-oidc-code-flow-authentication.adoc +++ b/_versions/main/guides/security-oidc-code-flow-authentication.adoc @@ -9,6 +9,8 @@ include::_attributes.adoc[] :diataxis-type: concept :categories: security,web :toclevels: 4 +:topics: security,oidc,keycloak,authentication +:extensions: io.quarkus:quarkus-oidc To protect your web applications, you can use the industry-standard OpenID Connect (OIDC) Authorization Code Flow mechanism provided by the Quarkus OIDC extension. @@ -17,7 +19,7 @@ To protect your web applications, you can use the industry-standard OpenID Conne The Quarkus OpenID Connect (OIDC) extension can protect application HTTP endpoints by using the OIDC Authorization Code Flow mechanism supported by OIDC-compliant authorization servers, such as link:https://www.keycloak.org[Keycloak]. The Authorization Code Flow mechanism authenticates users of your web application by redirecting them to an OIDC provider, such as Keycloak, to log in. -After authentication, the OIDC provider redirects the user back to the application with an authorization code that confirms that authentication was successful. +After authentication, the OIDC provider redirects the user back to the application with an authorization code that confirms that authentication was successful. Then, the application exchanges this code with the OIDC provider for an ID token (which represents the authenticated user), an access token, and a refresh token to authorize the user's access to the application. The following diagram outlines the Authorization Code Flow mechanism in Quarkus. @@ -74,7 +76,7 @@ quarkus.oidc.introspection-path=/protocol/openid-connect/token/introspect quarkus.oidc.end-session-path=/protocol/openid-connect/logout ---- -Some OIDC providers support metadata discovery but do not return all the endpoint URL values required for the authorization code flow to complete or to support application functions, for example, user logout. +Some OIDC providers support metadata discovery but do not return all the endpoint URL values required for the authorization code flow to complete or to support application functions, for example, user logout. To work around this limitation, you can configure the missing endpoint URL values locally, as outlined in the following example: [source, properties] @@ -87,8 +89,8 @@ quarkus.oidc.auth-server-url=http://localhost:8180/oidcprovider/account quarkus.oidc.end-session-path=logout ---- -You can use this same configuration to override a discovered endpoint URL if that URL does not work for the local Quarkus endpoint and a more specific value is required. -For example, a provider that supports both global and application-specific end-session endpoints returns a global end-session URL such as `http://localhost:8180/oidcprovider/account/global-logout`. +You can use this same configuration to override a discovered endpoint URL if that URL does not work for the local Quarkus endpoint and a more specific value is required. +For example, a provider that supports both global and application-specific end-session endpoints returns a global end-session URL such as `http://localhost:8180/oidcprovider/account/global-logout`. This URL will log the user out of all of the applications that the user is currently logged into. However, if the requirement is for the current application to log the user out of only the specific application, you can override the global end-session URL, by setting the `quarkus.oidc.end-session-path=logout` parameter. @@ -282,8 +284,8 @@ quarkus.oidc.introspection-credentials.secret=introspection-user-secret When a user is redirected to the OpenID Connect provider to authenticate, the redirect URL includes a `redirect_uri` query parameter, which indicates to the provider where the user has to be redirected to when the authentication is complete. In our case, this is the Quarkus application. -Quarkus sets this parameter to the current application request URL by default. -For example, if a user is trying to access a Quarkus service endpoint at `http://localhost:8080/service/1` then the `redirect_uri` parameter is set to `http://localhost:8080/service/1`. +Quarkus sets this parameter to the current application request URL by default. +For example, if a user is trying to access a Quarkus service endpoint at `http://localhost:8080/service/1` then the `redirect_uri` parameter is set to `http://localhost:8080/service/1`. Similarly, if the request URL is `http://localhost:8080/service/2` then the `redirect_uri` parameter is set to `http://localhost:8080/service/2`. Some OIDC providers require the `redirect_uri` to have the same value for a given application, for example, `http://localhost:8080/service/callback`, for all the redirect URLs. @@ -296,7 +298,7 @@ This will restore the request URL such as `http://localhost:8080/service/1`. By default, only the `response_type` (set to `code`), `scope` (set to 'openid'), `client_id`, `redirect_uri` and `state` properties are passed as HTTP query parameters to the OpenID Connect provider's authorization endpoint when the user is redirected to it to authenticate. -You can add more properties to it with `quarkus.oidc.authentication.extra-params`. +You can add more properties to it with `quarkus.oidc.authentication.extra-params`. For example, some OIDC providers might choose to return the authorization code as part of the redirect URI's fragment, which would break the authentication process. The following example shows how you can work around this issue: @@ -310,7 +312,7 @@ quarkus.oidc.authentication.extra-params.response_mode=query If the user authentication fails at the OIDC authorization endpoint, then the provider will redirect the user back to Quarkus with `error` and `error_description` parameters instead of `code`. For example, this can happen when an invalid scope or other invalid parameters are included in the redirect to the provider. -In such cases, an HTTP `401`error will be returned by default. +In such cases, an HTTP `401`error will be returned by default. However, you can instead request that a custom public error endpoint is called to return a more user-friendly HTML error page. To do this, set the `quarkus.oidc.authentication.error-path` property, as shown in the following example: @@ -466,7 +468,7 @@ It applies to ID tokens but also to access tokens in a JWT format if the `web-ap link:https://datatracker.ietf.org/doc/html/rfc7636[Proof Key for Code Exchange] (PKCE) minimizes the risk of authorization code interception. -While PKCE is of primary importance to public OpenID Connect clients, such as SPA scripts running in a browser, it can also provide an extra level of protection to Quarkus OIDC `web-app` applications. +While PKCE is of primary importance to public OpenID Connect clients, such as SPA scripts running in a browser, it can also provide an extra level of protection to Quarkus OIDC `web-app` applications. With PKCE, Quarkus OIDC `web-app` applications are confidential OpenID Connect clients capable of securely storing the client secret and using it to exchange the code for the tokens. You can enable `PKCE` for your OIDC `web-app` endpoint with a `quarkus.oidc.authentication.pkce-required` property and a 32-character secret which is required to encrypt the PKCE code verifier in the state cookie, as shown in the following example: @@ -480,7 +482,7 @@ quarkus.oidc.authentication.state-secret=eUk1p7UB3nFiXZGUXi0uph1Y9p34YhBU If you already have a 32-characters client secret then you do not need to set the `quarkus.oidc.authentication.pkce-secret` property unless you prefer to use a different secret key. This secret will be auto-generated if it is not configured and if the fallback to the client secret is not possible in case of the client secret being less than 16 characters long. The secret key is required for encrypting a randomly generated `PKCE` `code_verifier` while the user is being redirected with the `code_challenge` query parameter to an OIDC provider to authenticate. -The `code_verifier` is decrypted when the user is redirected back to Quarkus and sent to the token endpoint alongside the `code`, client secret, and other parameters to complete the code exchange. +The `code_verifier` is decrypted when the user is redirected back to Quarkus and sent to the token endpoint alongside the `code`, client secret, and other parameters to complete the code exchange. The provider will fail the code exchange if a `SHA256` digest of the `code_verifier` does not match the `code_challenge` that was provided during the authentication request. @@ -535,14 +537,14 @@ An access token is only required if the endpoint needs to: * Use the roles associated with the access token, which are checked by default In such cases, use the `quarkus.oidc.token-state-manager.strategy` property to configure the token state strategy as follows: - + |=== -|To... |Set the property to ... - +|To... |Set the property to ... + |Keep the ID and refresh tokens only -|`quarkus.oidc.token-state-manager.strategy=id-refresh-token` +|`quarkus.oidc.token-state-manager.strategy=id-refresh-token` -|Keep the ID token only +|Keep the ID token only |`quarkus.oidc.token-state-manager.strategy=id-token` |=== @@ -564,7 +566,7 @@ quarkus.oidc.token-state-manager.split-tokens=true quarkus.oidc.token-state-manager.encryption-secret=eUk1p7UB3nFiXZGUXi0uph1Y9p34YhBU ---- -The token encryption secret must be at least 32 characters long. +The token encryption secret must be at least 32 characters long. If this key is not configured then either `quarkus.oidc.credentials.secret` or `quarkus.oidc.credentials.jwt.secret` will be hashed to create an encryption key. Configure the `quarkus.oidc.token-state-manager.encryption-secret` property if Quarkus authenticates to the OpenId Connect Provider by using one of the following authentication methods: @@ -790,7 +792,7 @@ For more information, see the xref:oidc-cookies[Cookies] section. [NOTE] ==== -Some OIDC providers do not support link:https://openid.net/specs/openid-connect-session-1_0.html#RPLogout[RP-initiated logout] specification and do not return an OpenID Connect well-known `end_session_endpoint` metadata property. +Some OIDC providers do not support link:https://openid.net/specs/openid-connect-session-1_0.html#RPLogout[RP-initiated logout] specification and do not return an OpenID Connect well-known `end_session_endpoint` metadata property. However, this is not a problem for Quarkus because the specific logout mechanisms of such OIDC providers only differ in how the logout URL query parameters are named. According to the https://openid.net/specs/openid-connect-session-1_0.html#RPLogout[RP-initiated logout] specification, the `quarkus.oidc.logout.post-logout-path` property is represented as a `post_logout_redirect_uri` query parameter, which is not recognized by the providers that do not support this specification. @@ -838,7 +840,7 @@ quarkus.oidc.application-type=web-app quarkus.oidc.logout.backchannel.path=/back-channel-logout ---- -The absolute `back-channel logout` URL is calculated by adding `quarkus.oidc.back-channel-logout.path` to the current endpoint URL, for example, `http://localhost:8080/back-channel-logout`. +The absolute `back-channel logout` URL is calculated by adding `quarkus.oidc.back-channel-logout.path` to the current endpoint URL, for example, `http://localhost:8080/back-channel-logout`. You will need to configure this URL in the admin console of your OIDC provider. You will also need to configure a token age property for the logout token verification to succeed if your OpenID Connect Provider does not set an expiry claim in the current logout token. @@ -906,10 +908,10 @@ More useful methods will be added to it over time. ==== Session management -By default, logout is based on the expiration time of the ID token issued by the OIDC provider. When the ID token expires, the current user session at the Quarkus endpoint is invalidated and the user is redirected to the OIDC provider again to authenticate. +By default, logout is based on the expiration time of the ID token issued by the OIDC provider. When the ID token expires, the current user session at the Quarkus endpoint is invalidated and the user is redirected to the OIDC provider again to authenticate. If the session at the OIDC provider is still active, users are automatically re-authenticated without needing to provide their credentials again. -The current user session can be automatically extended by enabling the `quarkus.oidc.token.refresh-expired` property. +The current user session can be automatically extended by enabling the `quarkus.oidc.token.refresh-expired` property. If set to `true`, when the current ID token expires, a refresh token grant will be used to refresh the ID token as well as access and refresh tokens. [TIP] @@ -922,25 +924,25 @@ If you work with a Quarkus OIDC `web-app` application, then it is the Quarkus OI To use the refresh token, you should carefully configure the session cookie age. The session age should be longer than the ID token lifespan and close to or equal to the refresh token lifespan. -You calculate the session age by adding the lifespan value of the current ID token and the values of the `quarkus.oidc.authentication.session-age-extension` and `quarkus.oidc.token.lifespan-grace` properties. +You calculate the session age by adding the lifespan value of the current ID token and the values of the `quarkus.oidc.authentication.session-age-extension` and `quarkus.oidc.token.lifespan-grace` properties. [TIP] -- -You use only the `quarkus.oidc.authentication.session-age-extension` property to significantly extend the session lifespan, if required. +You use only the `quarkus.oidc.authentication.session-age-extension` property to significantly extend the session lifespan, if required. You use the `quarkus.oidc.token.lifespan-grace` property only for taking some small clock skews into consideration. -- -When the current authenticated user returns to the protected Quarkus endpoint and the ID token associated with the session cookie has expired, then, by default, the user is automatically redirected to the OIDC Authorization endpoint to re-authenticate. +When the current authenticated user returns to the protected Quarkus endpoint and the ID token associated with the session cookie has expired, then, by default, the user is automatically redirected to the OIDC Authorization endpoint to re-authenticate. The OIDC provider might challenge the user again if the session between the user and this OIDC provider is still active, which might happen if the session is configured to last longer than the ID token. -If the `quarkus.oidc.token.refresh-expired` is set to `true`, then the expired ID token (as well as the access token) is refreshed by using the refresh token returned with the initial authorization code grant response. -This refresh token might also be recycled (refreshed) itself as part of this process. +If the `quarkus.oidc.token.refresh-expired` is set to `true`, then the expired ID token (as well as the access token) is refreshed by using the refresh token returned with the initial authorization code grant response. +This refresh token might also be recycled (refreshed) itself as part of this process. As a result, the new session cookie is created and the session is extended. [NOTE] -- -In instances where the user is not very active, you can use the `quarkus.oidc.authentication.session-age-extension` property to help handle expired ID tokens. -If the ID token expires, the session cookie might not be returned to the Quarkus endpoint during the next user request as the cookie lifespan would have elapsed. -Quarkus assumes that this request is the first authentication request. +In instances where the user is not very active, you can use the `quarkus.oidc.authentication.session-age-extension` property to help handle expired ID tokens. +If the ID token expires, the session cookie might not be returned to the Quarkus endpoint during the next user request as the cookie lifespan would have elapsed. +Quarkus assumes that this request is the first authentication request. Set `quarkus.oidc.authentication.session-age-extension` to be _reasonably_ long for your barely-active users and in accordance with your security policies. -- @@ -975,8 +977,8 @@ To support the integration with such OAuth2 servers, `quarkus-oidc` needs to be [NOTE] -- -Even though you configure the extension to support the authorization code flows without `IdToken`, an internal `IdToken` is generated to standardize the way `quarkus-oidc` operates. -You use an `IdToken` to support the authentication session and to avoid redirecting the user to the provider, such as GitHub, on every request. +Even though you configure the extension to support the authorization code flows without `IdToken`, an internal `IdToken` is generated to standardize the way `quarkus-oidc` operates. +You use an `IdToken` to support the authentication session and to avoid redirecting the user to the provider, such as GitHub, on every request. In this case, the session lifespan is set to 5 minutes, which you can can extend further as described in the xref:session-management[session management] section. This simplifies how you handle an application that supports multiple OIDC providers. @@ -985,7 +987,7 @@ This simplifies how you handle an application that supports multiple OIDC provid The next step is to ensure that the returned access token can be useful and is valid to the current Quarkus endpoint. The first way is to call the OAuth2 provider introspection endpoint by configuring `quarkus.oidc.introspection-path`, if the provider offers such an endpoint. In this case you can use the access token as a source of roles using `quarkus.oidc.roles.source=accesstoken`. -If no introspection endpoint is present, you can attempt instead to request xref:user-info[UserInfo] from the provider as it will at least validate the access token. +If no introspection endpoint is present, you can attempt instead to request xref:user-info[UserInfo] from the provider as it will at least validate the access token. To do so, specify `quarkus.oidc.token.verify-access-token-with-user-info=true`. You also need to set the `quarkus.oidc.user-info-path` property to a URL endpoint that fetches the user info (or to an endpoint protected by the access token). For GitHub, since it does not have an introspection endpoint, requesting the UserInfo is required. @@ -1138,8 +1140,8 @@ You must ensure that the callback path you enter in the GitHub OAuth application === Listening to important authentication events You can register the `@ApplicationScoped` bean which will observe important OIDC authentication events. -When a user logs in for the first time, reauthenticates, or refreshes the session, the listener is updated. -In the future, more events might be reported. +When a user logs in for the first time, reauthenticates, or refreshes the session, the listener is updated. +In the future, more events might be reported. For example: [source, java] @@ -1171,14 +1173,14 @@ For information about Authorization Code Flow access token propagation to downst == Integration considerations Your application secured by OIDC integrates in an environment where it can be called from single-page applications, needs to work with well-known OIDC providers, run behind HTTP Reverse Proxy, require external and internal access, etc. - + This section discusses these considerations. === Single-page applications You can check if implementing single-page applications (SPAs) the way it is suggested in the xref:security-oidc-bearer-token-authentication.adoc#single-page-applications[Single-page applications] section of the "OpenID Connect (OIDC) Bearer token authentication" guide meets your requirements. -If you prefer to use SPAs and JavaScript APIs such as `Fetch` or `XMLHttpRequest`(XHR) with Quarkus web applications, be aware that OpenID Connect providers might not support cross-origin resource sharing (CORS) for authorization endpoints where the users are authenticated after a redirect from Quarkus. +If you prefer to use SPAs and JavaScript APIs such as `Fetch` or `XMLHttpRequest`(XHR) with Quarkus web applications, be aware that OpenID Connect providers might not support cross-origin resource sharing (CORS) for authorization endpoints where the users are authenticated after a redirect from Quarkus. This will lead to authentication failures if the Quarkus application and the OpenID Connect provider are hosted on different HTTP domains, ports, or both. In such cases, set the `quarkus.oidc.authentication.java-script-auto-redirect` property to `false`, which will instruct Quarkus to return a `499` status code and a `WWW-Authenticate` header with the `OIDC` value. @@ -1227,7 +1229,7 @@ Future callQuarkusService() async { === Cross-origin resource sharing -If you plan to consume this application from a single-page application running on a different domain, you need to configure cross-origin resource sharing (CORS). +If you plan to consume this application from a single-page application running on a different domain, you need to configure cross-origin resource sharing (CORS). For more information, see the xref:http-reference.adoc#cors-filter[CORS filter] section of the "HTTP reference" guide. === Calling Cloud provider services @@ -1334,7 +1336,7 @@ Next, if you would like, you can register this Keycloak SAML Provider as a Defau Now configure the Quarkus OIDC `web-app` application to point to the Keycloak `quarkus` realm, `quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus` and you are ready to start authenticating your Quarkus users to the Okta SAML 2.0 provider using an OIDC to SAML bridge provided by Keycloak OIDC and Okta SAML 2.0 providers. -You can configure other OIDC providers to provide a SAML bridge similarly to how it can be done for Keycloak. +You can configure other OIDC providers to provide a SAML bridge similarly to how it can be done for Keycloak. [[integration-testing]] == Testing diff --git a/_versions/main/guides/security-oidc-configuration-properties-reference.adoc b/_versions/main/guides/security-oidc-configuration-properties-reference.adoc index ac56880885..438a9f72a3 100644 --- a/_versions/main/guides/security-oidc-configuration-properties-reference.adoc +++ b/_versions/main/guides/security-oidc-configuration-properties-reference.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: reference :categories: security +:topics: security,oidc +:extensions: io.quarkus:quarkus-oidc As a Quarkus developer, you configure the Quarkus OpenID Connect (OIDC) extension by setting the following properties in the `src/main/resources/application.properties` file. diff --git a/_versions/main/guides/security-openid-connect-client-reference.adoc b/_versions/main/guides/security-openid-connect-client-reference.adoc index 2012fe9d79..13a88a2cfc 100644 --- a/_versions/main/guides/security-openid-connect-client-reference.adoc +++ b/_versions/main/guides/security-openid-connect-client-reference.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = OpenID Connect (OIDC) and OAuth2 Client and Filters Reference Guide include::_attributes.adoc[] +:categories: security +:topics: security,oidc,client +:extensions: io.quarkus:quarkus-oidc-client This reference guide explains how to use: @@ -1117,6 +1120,66 @@ The `quarkus-oidc-token-propagation-reactive` extension provides `io.quarkus.oid The `quarkus-oidc-token-propagation-reactive` extension (as opposed to the non-reactive `quarkus-oidc-token-propagation` extension) does not currently support the exchanging or resigning the tokens before the propagation. However, these features may be added in the future. +[[oidc-client-graphql-client]] +== GraphQL client integration + +The `quarkus-oidc-client-graphql` extension provides a way to integrate an +OIDC client into xref:smallrye-graphql-client.adoc[GraphQL clients]. This +works similarly as with REST clients. When this extension is present, any +configured (that means NOT created programmatically via the builder, but via +configuration properties) GraphQL client will attempt to use the OIDC client +to obtain an access token and set it as an `Authorization` header value. +OIDC client will also refresh expired access tokens. + +To configure which OIDC client should be used by GraphQL client, select one of the configured OIDC clients with the `quarkus.oidc-client-graphql.client-name` property, for example: + +---- +quarkus.oidc-client-graphql.client-name=oidc-client-for-graphql + +# example declaration of the OIDC client itself +quarkus.oidc-client.oidc-client-for-graphql.auth-server-url=${keycloak.url} +quarkus.oidc-client.oidc-client-for-graphql.grant.type=password +quarkus.oidc-client.oidc-client-for-graphql.grant-options.password.username=${username} +quarkus.oidc-client.oidc-client-for-graphql.grant-options.password.password=${password} +quarkus.oidc-client.oidc-client-for-graphql.client-id=${quarkus.oidc.client-id} +quarkus.oidc-client.oidc-client-for-graphql.credentials.client-secret.value=${keycloak.credentials.secret} +quarkus.oidc-client.oidc-client-for-graphql.credentials.client-secret.method=POST +---- + +NOTE: If you don't specify the `quarkus.oidc-client-graphql.client-name` property, +GraphQL clients will use the default OIDC client (without an explicit name). + +Specifically for typesafe GraphQL clients, you can override this on a +per-client basis by annotating the `GraphQLClientApi` interface with +`@io.quarkus.oidc.client.filter.OidcClientFilter`. For example: + +[source,java] +---- +@GraphQLClientApi(configKey = "order-client") +@OidcClientFilter("oidc-client-for-graphql") +public interface OrdersGraphQLClient { + // queries, mutations and subscriptions go here... +} +---- + +To be able to use this with a programmatically created GraphQL client, both +builders (`VertxDynamicGraphQLClientBuilder` and +`VertxTypesafeGraphQLClientBuilder`) contain a method `dynamicHeader(String, +Uni`) that allows you to plug in a header that might change for +every request. To plug an OIDC client into it, use + +[source,java] +---- +@Inject +OidcClients oidcClients; + +VertxTypesafeGraphQLClientBuilder builder = ....; +Uni tokenUni = oidcClients.getClient("OIDC_CLIENT_NAME") + .getTokens().map(t -> "Bearer " + t.getAccessToken()); +builder.dynamicHeader("Authorization", tokenUni); +VertxDynamicGraphQLClient client = builder.build(); +---- + == References * xref:security-openid-connect-client.adoc[OpenID Connect Client and Token Propagation Quickstart] diff --git a/_versions/main/guides/security-openid-connect-client.adoc b/_versions/main/guides/security-openid-connect-client.adoc index 014662ed92..18af4adea3 100644 --- a/_versions/main/guides/security-openid-connect-client.adoc +++ b/_versions/main/guides/security-openid-connect-client.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: security :summary: This guide explains how to use OpenID Connect and OAuth2 Client and Filters to acquire, refresh and propagate access tokens. +:topics: security,oidc,client +:extensions: io.quarkus:quarkus-oidc-client This quickstart demonstrates how to use `OpenID Connect Client Reactive Filter` to acquire and propagate access tokens as `HTTP Authorization Bearer` access tokens, alongside `OpenID Token Propagation Reactive Filter` which propagates the incoming `HTTP Authorization Bearer` access tokens. diff --git a/_versions/main/guides/security-openid-connect-dev-services.adoc b/_versions/main/guides/security-openid-connect-dev-services.adoc index 02f30617e7..49722325e1 100644 --- a/_versions/main/guides/security-openid-connect-dev-services.adoc +++ b/_versions/main/guides/security-openid-connect-dev-services.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: security :keywords: sso oidc security keycloak :summary: Start Keycloak or other providers automatically in dev and test modes. +:topics: security,oidc,keycloak,devservices,tooling,testing,devmode +:extensions: io.quarkus:quarkus-oidc This guide covers the Dev Services and UI for OpenID Connect (OIDC) Keycloak provider and explains how to support Dev Services and UI for other OpenID Connect providers. It also describes Dev UI for all OpenID Connect providers which have already been started before Quarkus is launched in a dev mode. diff --git a/_versions/main/guides/security-openid-connect-multitenancy.adoc b/_versions/main/guides/security-openid-connect-multitenancy.adoc index bd444ef9f9..0e48f72369 100644 --- a/_versions/main/guides/security-openid-connect-multitenancy.adoc +++ b/_versions/main/guides/security-openid-connect-multitenancy.adoc @@ -8,6 +8,8 @@ include::_attributes.adoc[] :categories: security :keywords: sso oidc oauth2 security :summary: This guide demonstrates how your OpenID Connect application can support multi-tenancy so that you can serve multiple tenants from a single application. +:topics: security,oidc,multitenancy +:extensions: io.quarkus:quarkus-oidc This guide demonstrates how your OpenID Connect (OIDC) application can support multi-tenancy so that you can serve multiple tenants from a single application. Tenants can be distinct realms or security domains within the same OpenID Provider or even distinct OpenID Providers. diff --git a/_versions/main/guides/security-openid-connect-providers.adoc b/_versions/main/guides/security-openid-connect-providers.adoc index 93ce7de56b..6148ecbc6c 100644 --- a/_versions/main/guides/security-openid-connect-providers.adoc +++ b/_versions/main/guides/security-openid-connect-providers.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :categories: security,web :keywords: oidc github twitter google facebook mastodon microsoft apple spotify twitch :toclevels: 3 +:topics: security,oidc,github,twitter,google,facebook,mastodon,microsoft,apple,spotify,twitch +:extensions: io.quarkus:quarkus-oidc This document explains how to configure well-known social OIDC and OAuth2 providers. diff --git a/_versions/main/guides/security-overview.adoc b/_versions/main/guides/security-overview.adoc index 1b59fc285c..6593d5fb97 100644 --- a/_versions/main/guides/security-overview.adoc +++ b/_versions/main/guides/security-overview.adoc @@ -8,6 +8,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: concept :categories: security +:topics: security Quarkus Security is a framework that provides the architecture, multiple authentication and authorization mechanisms, and other tools for you to build secure and production-quality Java applications. diff --git a/_versions/main/guides/security-proactive-authentication.adoc b/_versions/main/guides/security-proactive-authentication.adoc index 5d9b35e7dc..446de6d018 100644 --- a/_versions/main/guides/security-proactive-authentication.adoc +++ b/_versions/main/guides/security-proactive-authentication.adoc @@ -8,6 +8,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: concept :categories: security,web +:topics: security,authentication +:extensions: io.quarkus:quarkus-vertx-http Proactive authentication is enabled in Quarkus by default. This means that if an incoming request has a credential then that request will always be authenticated, even if the target page does not require authentication. diff --git a/_versions/main/guides/security-properties.adoc b/_versions/main/guides/security-properties.adoc index 3765647b0b..7b5cb37c30 100644 --- a/_versions/main/guides/security-properties.adoc +++ b/_versions/main/guides/security-properties.adoc @@ -7,6 +7,8 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :categories: security :summary: This guide demonstrates how your Quarkus application can use a .properties file to store your user identities. +:topics: security,identity-providers +:extensions: io.quarkus:quarkus-elytron-security-properties-file Quarkus provides support for properties file-based authentication intended for development and testing purposes. It is not recommended to use this authentication in production as, at present, only plain-text and MD5 hashed passwords are used, and properties files are generally too limited. diff --git a/_versions/main/guides/security-testing.adoc b/_versions/main/guides/security-testing.adoc index 629f9f3cd8..234bc9d736 100644 --- a/_versions/main/guides/security-testing.adoc +++ b/_versions/main/guides/security-testing.adoc @@ -5,6 +5,9 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// = Security Testing include::_attributes.adoc[] +:categories: security +:topics: security,testing +:extensions: io.quarkus:quarkus-test-security This document describes how to test Quarkus Security. diff --git a/_versions/main/guides/security-vulnerability-detection.adoc b/_versions/main/guides/security-vulnerability-detection.adoc index 303348de85..4d11529ac6 100644 --- a/_versions/main/guides/security-vulnerability-detection.adoc +++ b/_versions/main/guides/security-vulnerability-detection.adoc @@ -8,6 +8,7 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::_attributes.adoc[] :diataxis-type: concept :categories: security,contributing +:topics: security,vulnerability Most of the Quarkus tags are registered in the US link:https://nvd.nist.gov[National Vulnerability Database (NVD)] in Common Platform Enumeration (CPE) name format. diff --git a/_versions/main/guides/security-webauthn.adoc b/_versions/main/guides/security-webauthn.adoc index 88231393c1..878b239806 100644 --- a/_versions/main/guides/security-webauthn.adoc +++ b/_versions/main/guides/security-webauthn.adoc @@ -5,11 +5,13 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// [id="security-webauthn"] = Using Security with WebAuthn -:extension-status: preview - include::_attributes.adoc[] +:extension-status: preview +:categories: security +:topics: security,webauthn,authorization +:extensions: io.quarkus:quarkus-security-webauthn -This guide demonstrates how your Quarkus application can use WebAuthn authentication instead of +This guide demonstrates how your Quarkus application can use WebAuthn authentication instead of passwords. include::{includes}/extension-status.adoc[] @@ -235,7 +237,7 @@ import io.vertx.ext.auth.webauthn.PublicKeyCredential; @Table(uniqueConstraints = @UniqueConstraint(columnNames = {"userName", "credID"})) @Entity public class WebAuthnCredential extends PanacheEntity { - + /** * The username linked to this authenticator */ @@ -284,16 +286,16 @@ public class WebAuthnCredential extends PanacheEntity { */ @OneToMany(mappedBy = "webAuthnCredential") public List x5c = new ArrayList<>(); - + public String fmt; - + // owning side @OneToOne public User user; public WebAuthnCredential() { } - + public WebAuthnCredential(Authenticator authenticator, User user) { aaguid = authenticator.getAaguid(); if(authenticator.getAttestationCertificates() != null) @@ -320,7 +322,7 @@ public class WebAuthnCredential extends PanacheEntity { public static Uni> findByUserName(String userName) { return list("userName", userName); } - + public static Uni> findByCredID(String credID) { return list("credID", credID); } @@ -345,10 +347,10 @@ import io.quarkus.hibernate.reactive.panache.PanacheEntity; @Entity public class WebAuthnCertificate extends PanacheEntity { - + @ManyToOne public WebAuthnCredential webAuthnCredential; - + /** * The list of X509 certificates encoded as base64url. */ @@ -494,7 +496,7 @@ public class MyWebAuthnSetup implements WebAuthnUserProvider { return ret; }); } - + @Override public Set getRoles(String userId) { if(userId.equals("admin")) { @@ -539,11 +541,11 @@ in `src/main/resources/META-INF/resources/index.html`: overflow: hidden; background-color: #333; } - + nav > ul > li { float: left; } - + nav > ul > li > a { display: block; color: white; @@ -551,13 +553,13 @@ in `src/main/resources/META-INF/resources/index.html`: padding: 14px 16px; text-decoration: none; } - + nav > ul > li > a:hover { background-color: #111; } - +