Quarkus Cheat-Sheet
What is Quarkus? Or in Kotlin: Command mode
Quarkus is a Kubernetes Native Java stack tailored for GraalVM & plugins { You can de ne the main CLI method to start Quarkus. There are two OpenJDK HotSpot, crafted from the best of breed Java libraries and java ways, implementing io.quarkus.runtime.QuarkusApplication standards. Also focused on developer experience, making things } interface or use the Java main method to launch Quarkus. just work with little to no con guration and allowing to do live apply(plugin = "io.quarkus") coding. @io.quarkus.runtime.annotations.QuarkusMain repositories { public class HelloWorldMain implements QuarkusApplication { Cheat-sheet tested with Quarkus 1.13.0.Final. mavenCentral() @Override } public int run(String... args) throws Exception { Getting Started System.out.println("Hello World"); dependencies { return 10; Quarkus comes with a Maven archetype to scaffold a very simple implementation(enforcedPlatform("io.quarkus:quarkus-bo } starting project. m:0.26.1")) } implementation("io.quarkus:quarkus-resteasy") } mvn io.quarkus:quarkus-maven-plugin:1.13.0.Final:create \ -DprojectGroupId=org.acme \ run method called when Quarkus starts, and stops when it nishes. -DprojectArtifactId=getting-started \ -DclassName="org.acme.quickstart.GreetingResource" \ Packaging As Java main : -Dpath="/hello"
mvn clean package @QuarkusMain public class JavaMain { This creates a simple JAX-RS resource called GreetingResource . public static void main(String... args) { Quarkus.run(HelloWorldMain.class, args); You need to distribute the -runner.jar le together with quarkus- @Path("/hello") } app directory. public class GreetingResource { } If quarkus.package.uber-jar property is set to true, then a uber-jar is @GET created with all dependencies bundled inside the JAR. @Produces(MediaType.TEXT_PLAIN) public String hello() { By default, Quarkus uses fast jar packaging, if quarkus.package.type Use @QuarkusMain in only one place. return "hello"; property is set to legacy-jar then Quarkus creates the old standard } jar le. Use Quarkus.waitForExit() from the main thread if you want to run } application.properties some logic on startup, and then run like a normal application (i.e. not exit). quarkus.package.uber-jar=true Gradle quarkus.package.type=legacy-jar You can inject command line arguments by using @CommandLineArguments annotation: There is no way to scaffold a project in Gradle but you only need to do: To compile to native, you need to set GRAALVM_HOME environment @CommandLineArguments variable and run the native pro le. String[] args; plugins { id 'java' mvn clean package -Pnative id 'io.quarkus' version '0.26.1' Picocli } ./gradlew build -Dquarkus.package.type=native You can use Picocli to implement CLI applications: repositories { mavenCentral() ./mvnw quarkus:add-extension Possible quarkus.package.type are: jar , legacy-jar , uber-jar and } -Dextensions="picocli" native .
dependencies { AppCDS implementation enforcedPlatform('io.quarkus:quarkus-bo m:0.26.1') Automatically generate AppCDS as part of the build process set the implementation 'io.quarkus:quarkus-resteasy' next property: quarkus.package.create-appcds=true . } To make use of it, just run java -jar -XX:SharedArchiveFile=app- cds.jsa myapp.jar . @CommandLine.Command @CommandLine.Command Dev Mode public class HelloCommand implements Runnable { public class EntryCommand implements Runnable { @CommandLine.Option(names = "-c", description = "JDBC c ./mvnw compile quarkus:dev @CommandLine.Option(names = {"-n", "--name"}, descripti onnection string")
on = "Who will we greet?", defaultValue = "World") String connectionString; ./gradlew quarkusDev String name; @Inject private final GreetingService greetingService; DataSource dataSource; } Endpoints are registered automatically to provide some basic public HelloCommand(GreetingService greetingService) { debug info in dev mode: this.greetingService = greetingService; @ApplicationScoped HTTP GET /quarkus/arc/beans } class DatasourceConfiguration {
Query Parameters: scope , beanClass , kind . @Override @Produces
public void run() { @ApplicationScoped HTTP GET /quarkus/arc/observers greetingService.sayHello(name); DataSource dataSource(CommandLine.ParseResult parseResu } lt) { Dev UI } System.out.println(parseResult.matchedOption("c").g etValue().toString()); Quarkus adds a Dev UI console to expose extension features. } } All classes annotated with picocli.CommandLine.Command are The Dev UI is available in dev mode only and accessible at the registered as CDI beans. /q/dev endpoint by default. If only one class annotated with picocli.CommandLine.Command it will Extensions Adding Con guration Parameters be used as entry point. If you want to provide your own @QuarkusMain : Quarkus comes with extensions to integrate with some libraries To add con guration to your application, Quarkus relies on such as JSON-B, Camel or MicroPro le spec. To list all available MicroPro le Con g spec. @QuarkusMain extensions just run: @CommandLine.Command(name = "demo", mixinStandardHelpOption @ConfigProperty(name = "greetings.message") s = true) ./mvnw quarkus:list-extensions String message; public class ExampleApp implements Runnable, QuarkusApplica
tion { @ConfigProperty(name = "greetings.message",
defaultValue = "Hello") @Inject You can use -DsearchPattern=panache to lter out all String messageWithDefault; CommandLine.IFactory factory; extensions except the ones matching the expression.
@ConfigProperty(name = "greetings.message") @Override And to register the extensions into build tool: Optional
@Override Properties can be set (in decreasing priority) as: ./mvnw quarkus:remove-extension -Dextensions="" public int run(String... args) throws Exception { return new CommandLine(this, factory).execute(arg System properties ( -Dgreetings.message ). s); } extensions property supports CSV format to register more Environment variables ( GREETINGS_MESSAGE ). } than one extension at once. Environment le named .env placed in the current working directory ( GREETING_MESSAGE= ). Application Lifecycle Use quarkus.picocli.native-image.processing.enable to false to use External con g directory under the current working directory: the picocli-codegen annotation processor instead of build steps. You can be noti ed when the application starts/stops by observing config/application.properties . StartupEvent and ShutdownEvent events. You can also con gure CDI beans with PicoCLI arguments: Resources src/main/resources/application.properties . @ApplicationScoped public class ApplicationLifecycle { greetings.message = Hello World void onStart(@Observes StartupEvent event) {} void onStop(@Observes ShutdownEvent event) {} } Array , List and Set are supported. The delimiter is comma ( , ) char and \ is the escape char.
Quarkus supports graceful shutdown. By default there is no timeout Con guration Pro les but can be set by using the quarkus.shutdown.timeout con g Quarkus allow you to have multiple con guration in the same le @ConfigProperty(name = "quarkus.application.name") @ConfigProperties(prefix = "greeting", namingStrategy=Namin ( application.properties ). String applicationName; gStrategy.KEBAB_CASE) public class GreetingConfiguration { The syntax for this is %{profile}.config.key=value . public String message; Additional locations public HiddenConfig hidden; quarkus.http.port=9090 %dev.quarkus.http.port=8181 You can use smallrye.config.locations property to set additional public static class HiddenConfig { con guration les. public List
And an application.properties mapping previous class: dev : Activated when in development mode ( quarkus:dev ). or
test : Activated when running tests. greeting.message = hello java -jar -Dsmallrye.config.locations=config.properties greeting.hidden.recipients=Jane,John prod : The default pro le when not running in development or test mode You can embed con guration les inside a dependency by adding Bean Validation is also supported so properties are validated at You can create custom pro le names by enabling the pro le either META-INF/microprofile.properties inside the JAR. When dependency startup time, for example @Size(min = 20) public String message; . setting quarkus.profile system property or QUARKUS_PROFILE is added to the application, con guration properties are merged environment variable. with current con guration. prefix attribute is not mandatory. If not provided, attribute is determined by class name (ie GreeetingConfiguration is quarkus.http.port=9090 @Con gProperties translated to greeting or GreetingExtraConfiguration to %staging.quarkus.http.port=9999 As an alternative to injecting multiple related con guration values, greeting-extra ). The su x of the class is always removed. you can also use the @io.quarkus.arc.config.ConfigProperties annotation to group properties. Naming strategy can be changed with property namingStrategy . And enable it quarkus.profile=staging . KEBAB_CASE (whatever.foo-bar) or VERBATIM (whatever.fooBar).
@ConfigProperties(prefix = "greeting", namingStrategy=Namin To get the active pro le programmatically use @io.quarkus.arc.config.ConfigIgnore annotation can be used to gStrategy.KEBAB_CASE) io.quarkus.runtime.configuration.ProfileManager.getActiveProfile() . ignore the injection of con guration elements. public class GreetingConfiguration { private String message; @ConfigIgnore You can also set it in the build tool: // getter/setter public Integer ignored; }
@ConfigProperty(name = "message") String message(); test { quarkus: String getSuffix(); useJUnitPlatform() datasource: systemProperty "quarkus.test.profile", "foo" url: jdbc:postgresql://localhost:5432/some-database } driver: org.postgresql.Driver If property does not follow getter/setter naming convention you need to use org.eclipse.microprofile.config.inject.ConfigProperty to set it. Special properties are set in prod mode: Or with pro les: quarkus.application.version and quarkus.application.name to get Nested objects are also supporte: them available at runtime. Then you need to register the ConfigSource as Java service. Create "%dev": @ApplicationScoped a le with the following content: quarkus: public class GreetingService { datasource: /META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource url: jdbc:postgresql://localhost:5432/some-database public String message(String message) { driver: org.postgresql.Driver com.acme.config.InMemoryConfig return message.toUpperCase(); } }
In case of subkeys ~ is used to refer to the unpre xed part. Custom Converters
You can implement your own conversion types from String. quarkus: Scope annotation is mandatory to make the bean discoverable. Implement org.eclipse.microprofile.config.spi.Converter http: interface: cors: @Inject ~: true GreetingService greetingService; methods: GET,PUT,POST @Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY + 100) public class CustomInstantConverter implements Converter
package com.acme.config; /META-INF/services/org.eclipse.microprofile.config.spi.Converter @Inject public class InMemoryConfig implements ConfigSource { Message msg; com.acme.config.CustomInstantConverter private Map
public InMemoryConfig() { Quali ers // Init properties Undertow Properties } You can use quali ers to return different implementations of the Possible parameters with pre x quarkus.servlet : same interface or to customize the con guration of the bean. @Override public int getOrdinal() { context-path // The highest ordinal takes precedence The context path to serve all Servlet context from. (default: / ) return 900; } default-charset
The default charset to use for reading and writing requests. @Override (default: UTF-8 ) public Map
@Override Quarkus is based on CDI 2.0 to implement injection of code. It is public String getValue(String propertyName) { not fully supported and only a subset of the speci cation is return prop.get(propertyName); implemented. }
@Override public String getName() { return "MemoryConfigSource"; } } To work with JSON-B you need to add a dependency: @Qualifier @Dependent @Retention(RUNTIME) public class TracerConfiguration { @Target({TYPE, METHOD, FIELD, PARAMETER}) @Produces ./mvnw quarkus:add-extension public @interface Quote { @IfBuildProfile("prod") -Dextensions="io.quarkus:quarkus-resteasy-jsonb" @Nonbinding String value(); public Tracer realTracer(Reporter reporter, Configurati } on configuration) { return new RealTracer(reporter, configuration); Any POJO is marshaled/unmarshalled automatically. @Produces } @Quote("") @Produces public class Sauce { Message message(InjectionPoint msg) { @DefaultBean private String name; Message m = new Message(); public Tracer noopTracer() { private long scovilleHeatUnits; m.setMsn( return new NoopTracer();
msg.getAnnotated() } // getter/setters .getAnnotation(Quote.class) } } .value() );
Using @io.quarkus.arc.profile.IfBuildProperty annotation, you can return m; JSON equivalent: conditionally enable a bean. @io.quarkus.arc.DefaultBean sets the } default bean. { @Inject "name":"Blair's Ultra Death", @Dependent @Quote("Aloha Beach") "scovilleHeatUnits": 1100000 public class TracerConfiguration { Message message; } @Produces @IfBuildProperty(name = "some.tracer.enabled", stringVa lue = "true") Quarkus breaks the CDI spec by allowing you to inject public Tracer realTracer(Reporter reporter, Configurati In a POST endpoint example: quali ed beans without using @Inject annotation. on configuration) {} @POST @Quote("Aloha Beach") @Produces @Consumes(MediaType.APPLICATION_JSON) Message message; @DefaultBean public Response create(Sauce sauce) { public Tracer noopTracer() {} // Create Sauce } return Response.created(URI.create(sauce.getId())) .build(); Quarkus breaks the CDI spec by skipping the @Produces annotation completely if the producer method is annotated } with a scope annotation, a stereotype or a quali er. Properties set at runtime have absolutely no effect on the bean resolution using @IfBuildProperty . @Quote("") To provide custom JsonBCon g object: Message message(InjectionPoint msg) { Container-managed Concurrency } @Dependent Quarkus provides @io.quarkus.arc.Lock and a built-in interceptor for JsonbConfig jsonConfig(Instance
} @NotBlank(message = "Name may not be blank") return objectMapper; private String name; } @Min(0) And use it normally: } private long scovilleHeatUnits; @NotExpired // getter/setters @JsonbDateFormat(value = "yyyy-MM-dd") } private LocalDate expired; Default media type in Quarkus RestEasy is JSON.
XML Marshalling/Unmarshalling To validate an object use @Valid annotation: Manual Validation
To work with JAX-B you need to add a dependency: public Response create(@Valid Sauce sauce) {} You can call the validation process manually instead of relaying to @Valid by injecting Validator class.
./mvnw quarkus:add-extension @Inject -Dextensions="quarkus-resteasy-jaxb" If a validation error is triggered, a violation report is Validator validator; generated and serialized as JSON. If you want to manipulate the output, you need to catch in the code the Then annotated POJOs are converted to XML. ConstraintViolationException exception. And use it: Create Your Custom Constraints @XmlRootElement Set
@GET @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, @Produces(MediaType.APPLICATION_XML) PARAMETER, TYPE_USE }) Localization public Message hello() { @Retention(RUNTIME) return message; @Documented You can con gure the based locale for validation messages. } @Constraint(validatedBy = { NotExpiredValidator.class}) public @interface NotExpired { quarkus.default-locale=ca-ES
# Supported locales resolved by Accept-Language String message() default "Sauce must not be expired"; quarkus.locales=en-US,es-ES,fr-FR, ca_ES JAXP Class[] groups() default { }; Class[] payload() default { }; To work with JAX-P you need to add a dependency: } ValidationMessages_ca_ES.properties
./mvnw quarkus:add-extension pattern.message=No conforme al patro -Dextensions="jaxp" You need to implement the validator logic in a class that implements ConstraintValidator . @Pattern(regexp = "A.*", message = "{pattern.message}") final DocumentBuilder dBuilder = DocumentBuilderFactory.new private String name; Instance().newDocumentBuilder(); final Document doc = dBuilder.parse(in); return doc.getDocumentElement().getTextContent(); Bean Validation can be con gured . The pre x is: quarkus.hibernate-validator .
Validator fail-fast When fail fast is enabled the validation will stop on the rst The path to log le (default: quarkus.log ) syslog.truncate constraint violation detected. (default: false ) Message should be truncated (default: true ) file.rotation.max-file-size method-validation.allow-overriding-parameter-constraints The maximum le size of the log le syslog.block-on-reconnect De ne whether overriding methods that override constraints Block when attempting to reconnect (default: true ) should throw an exception. (default: false ). file.rotation.max-backup-index The maximum number of backups to keep (default: 1 ) syslog.async method-validation.allow-parameter-constraints-on-parallel-methods Log asynchronously (default: false ) De ne whether parallel methods that de ne constraints should file.rotation.file-suffix throw an exception. (default: false ). Rotating log le su x. syslog.async.queue-length The queue length to use before ushing writing (default: 512 ) method-validation.allow-multiple-cascaded-validation-on-return- file.rotation.rotate-on-boot values Indicates rotate logs at bootup (default: true ) syslog.async.overflow De ne whether more than one constraint on a return value may Action when queue is full (default: BLOCK ) be marked for cascading validation are allowed. (default: false ). file.async Logging Log asynchronously (default: false ) You can inject logger instance:
file.async.queue-length import org.jboss.logging.Logger; You can con gure how Quarkus logs: The queue length to use before ushing writing (default: 512 ) import io.quarkus.arc.log.LoggerName;
quarkus.log.console.enable=true file.async.overflow @Inject quarkus.log.console.level=DEBUG Logger log; Action when queue is full (default: BLOCK ) quarkus.log.console.color=false quarkus.log.category."com.lordofthejars".level=DEBUG @LoggerName("foo") syslog.enable Logger fooLog; syslog logging is enabled (default: false ) Pre x is quarkus.log . public void ping() { syslog.format log.info("Simple!"); category."
level syslog.level Gelf ouput Default minimum level (default: INFO ) The minimum log level to write to syslog (default: ALL ) You can con gure the output to be in GELF format instead of plain text. console.enabled syslog.endpoint Console logging enabled (default: true ) The IP address and port of the syslog server (default: localhost:514 ) ./mvnw quarkus:add-extension -Dextensions="quarkus-logging-gelf" console.format Format pattern to use for logging. Default value: syslog.app-name %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{3.}] (%t) %s%e%n The app name used when formatting the message in RFC5424 format (default: current process name) handler.gelf.enabled console.level Enable GELF logging handler (default: false ) syslog.hostname Minimum log level (default: INFO ) The name of the host the messages are being sent from (default: handler.gelf.host console.color current hostname) Hostname/IP of Logstash/Graylof. Prepend tcp: for using TCP protocol. (default: udp:localhost ) Allow color rendering (default: true ) syslog.facility handler.gelf.port file.enable Priority of the message as de ned by RFC-5424 and RFC-3164 (default: USER_LEVEL ) The port. (default: 12201 ) File logging enabled (default: false )
syslog.syslog-type handler.gelf.version file.format The syslog type of format message (default: RFC5424 ) Format pattern to use for logging. Default value: GELF version. (default: 1.1 ) %d{yyyy-MM-dd HH:mm:ss,SSS} %h %N[%i] %-5p [%c{3.}] (%t) %s%e%n syslog.protocol handler.gelf.extract-stack-trace
file.level Protocol used (default: TCP ) Post Stack-Trace to StackTrace eld. (default: true ) Minimum log level (default: ALL ) syslog.use-counting-framing handler.gelf.stack-trace-throwable-reference
file.path Message pre xed with the size of the message (default false ) Gets the cause level to stack trace. 0 is fulls tack trace. (default: ) handler.gelf.filter-stack-trace json.print-details You can still use the JAX-RS client without any problem Stack-Trace ltering. (default: false ) Detailed caller information should be logged (default: false) ClientBuilder.newClient().target(… ) handler.gelf.timestamp-pattern Rest Client Adding headers Java Date pattern. (default: yyyy-MM-dd HH:mm:ss,SSS ) You can customize the headers passed by implementing Quarkus implements MicroPro le Rest Client spec: MicroPro le ClientHeadersFactory annotation: handler.gelf.level
Log level java.util.logging.Level . (default: ALL ) ./mvnw quarkus:add-extension @RegisterForReflection -Dextensions="quarkus-rest-client" public class BaggageHeadersFactory handler.gelf.facility implements ClientHeadersFactory { Name of the facility. (default: jboss-logmanage ) @Override To get content from http://worldclockapi.com/api/json/cet/now public MultivaluedMap
Include source code location. (default: true ) } @GET JSON output @ClientHeaderParam(name="X-Log-Level", value="ERROR") Response getNow(); You can con gure the output to be in JSON format instead of plain text. public class WorldClockOptions { @HeaderParam("Authorization") Asynchronous String auth; ./mvnw quarkus:add-extension -Dextensions="quarkus-logging-json" A method on client interface can return a CompletionStage class to @PathParam("where") be executed asynchronously. String where; } @GET @Path("/json/cet/now") And the con guration values are pre x with quarkus.log : @Produces(MediaType.APPLICATION_JSON) json CompletionStage
org.acme.quickstart.WorldClockService/mp-rest/url= json.pretty-print Reactive http://worldclockapi.com JSON output is "pretty-printed" (default: false) Rest Client also integrates with reactive library named Mutiny. To start using it you need to add the quarkus-rest-client-mutiny . json.date-format Injecting the client: Specify the date format to use (default: the default format) After that, a methodon a client interface can return a io.smallrye.mutiny.Uni instance. @RestClient json.record-delimiter WorldClockService worldClockService; Record delimiter to add (default: no delimiter) @GET @Path("/json/cet/now") @Produces(MediaType.APPLICATION_JSON) json.zone-id Uni
%s/mp-rest/keyStorePassword public class MultipartBody { @TestHTTPResource("index.html") Key store password. URL url; @FormParam("file") @PartType(MediaType.APPLICATION_OCTET_STREAM) %s/mp-rest/keyStoreType private InputStream file; Key store type (default: JKS ) @TestHTTPEndpoint(GreetingResource.class) @FormParam("fileName") Timeout @TestHTTPResource @PartType(MediaType.TEXT_PLAIN) URL url; private String name; You can de ne the timeout of the Rest Client:
// getter/setters org.acme.quickstart.WorldClockService/mp-rest/connectTimeou } @QuarkusTest t= @TestHTTPEndpoint(GreetingResource.class) 1000 public class GreetingResourceTest { org.acme.quickstart.WorldClockService/mp-rest/readTimeout= @Test And the Rest client interface: 2000 public void testHelloEndpoint() { given() import .when().get() org.jboss.resteasy.annotations.providers.multipart.Mult Instantiate client programmatically .then() ipartForm; .statusCode(200) .body(is("hello")); MovieReviewService reviewSvc = RestClientBuilder.newBuilder @Path("/echo") } () @RegisterRestClient } .baseUri(apiUri) public interface MultipartService { .build(WorldClockService.class);
@POST Root path is calculated automatically, not necessary to explicitly @Consumes(MediaType.MULTIPART_FORM_DATA) set. @Produces(MediaType.TEXT_PLAIN) Testing String sendMultipartData(@MultipartForm If you want any changes made to be rolled back at the end ofthe MultipartBody data); Quarkus archetype adds test dependencies with JUnit 5 and Rest- test you can use the io.quarkus.test.TestTransaction annotation. Assured library to test REST endpoints. } QuarkusTestPro le
You can de ne for each Test class a different con guration options. SSL This implies that the Quarkus service is restarted. You can con gure Rest Client key stores.
org.acme.quickstart.WorldClockService/mp-rest/trustStore= classpath:/store.jks org.acme.quickstart.WorldClockService/mp-rest/trustStorePas sword= supersecret And needs to be registered as Java SPI: public class MyProfile implements io.quarkus.test.junit.Qua public class MyCustomTestResource rkusTestProfile { implements QuarkusTestResourceLifecycleManager { META- INF/services/io.quarkus.test.junit.callback.QuarkusTestBeforeClassCallback @Override @Override io.quarkus.it.main.SimpleAnnotationCheckerBeforeClassCallba public Map
@Override // optional @Alternative public Set
Quarkus Test Resource @QuarkusTestResource(MyCustomTestResource.class) @InjectMock public class MyTest { GreetingService greetingService; You can execute some logic before the rst test run ( start ) and } execute some logic at the end of the test suite ( stop ). @BeforeEach public void setup() { You need to create a class implementing Mockito.when(greetingService.greet()).thenReturn("Hi"); When using multiple QuarkusTestResource you can set parallel QuarkusTestResourceLifecycleManager interface and register it in the } attribute to true to start them concurrently. test via @QuarkusTestResource annotation. Testing Callbacks @Path("/hello") public class ExampleResource { You can enrich all your @QuarkusTest classes by implementing the following callback interfaces: @Inject GreetingService greetingService; io.quarkus.test.junit.callback.QuarkusTestBeforeClassCallback }
io.quarkus.test.junit.callback.QuarkusTestAfterConstructCall back Mock is automatically injected and only valid for the de ned test class. io.quarkus.test.junit.callback.QuarkusTestBeforeEachCallback
Also spy is supported: io.quarkus.test.junit.callback.QuarkusTestAfterEachCallback
@InjectSpy public class SimpleAnnotationCheckerBeforeClassCallback imp GreetingService greetingService; lements QuarkusTestBeforeClassCallback {
@Override Mockito.verify(greetingService, Mockito.times(1)).greet(); public void beforeClass(Class testClass) { } } REST Client To Mock REST Client, you need to de ne the interface with includes Persistence @ApplicationScope : A list of class les to include in the report. (default: ** ) Quarkus works with JPA(Hibernate) as persistence solution. But @ApplicationScoped excludes also provides an Active Record pattern implementation under @RegisterRestClient A list of class les to exclude from the report. Panache project. public interface GreetingService { } To use database access you need to add Quarkus JDBC drivers report-location instead of the original ones. At this time Apache Derby , H2 , MariaDB , @InjectMock The location of the report les. (default: jacoco-report ) MySQL , MSSQL and PostgreSQL drivers are supported. @RestClient Native Testing GreetingService greetingService; ./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-hibernate-orm-panache, To test native executables annotate the test with @NativeImageTest . Mockito.when(greetingService.hello()).thenReturn("hello fro io.quarkus:quarkus-jdbc-mariadb" m mockito"); Quarkus Integration Tests
@QuarkusIntegrationTest should be used to launch and test the Interceptors artifact produced by the Quarkus build. If the result of a Quarkus @Entity build is a JAR then the app is launched as java -jar , if native is public class Developer extends PanacheEntity { Tests are actually full CDI beans, so you can apply CDI interceptors: launched as ./application , if container image is created (JiB, Docker extensions) is launched as docker run . // id field is implicit
@QuarkusTest public String name; @Stereotype } @Transactional @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface TransactionalQuarkusTest { And con guration in src/main/resources/application.properties : } quarkus.datasource.jdbc.url=jdbc:mariadb://localhost:3306/m @TransactionalQuarkusTest ydb public class TestStereotypeTestCase {} quarkus.datasource.db-kind=mariadb quarkus.datasource.username=developer quarkus.datasource.password=developer Test Coverage quarkus.hibernate-orm.database.generation=update
Due the nature of Quarkus to calculate correctly the coverage information with JaCoCo, you might need o ine instrumentation. List of datasource parameters.
./mvnw quarkus:add-extension quarkus.datasource as pre x is skipped in the next table. -Dextensions="quarkus-jacoco " db-kind Built-in datasource kinds so the JDBC driver is resolved automatically. Possible values: derby , h2 , mariadb , mssql , mysql , Possible con guration parameters pre xed quarkus.jacoco : postgresql , db2 . data-file username The jacoco data le. (default: jacoco-quarkus.exec ) Username to access. report password If Quarkus should generate the Jacoco report. (default: true ) Password to access. output-encoding driver Encoding of the generated reports. (default: UTF-8 ) JDBC Driver class. It is not necessary to set if db-kind used. title Name of the root node HTML report pages. credentials-provider Sets a custom credential provider name. footer Footer text used in HTML report pages. credentials-provider-name It is the @Named value of the credentials provider bean. Not source-encoding necessary if only one implementation. Encoding of the source les (default: UTF-8 ) jdbc.url dialect Number of rows fetched at a time. The datasource URL. Class name of the Hibernate ORM dialect. jdbc.statement-batch-size jdbc.min-size dialect.storage-engine Number of updates sent at a time. The datasource pool minimum size. (default: 0 ) The storage engine when the dialect supports multiple storage engines. log.sql jdbc.max-size Show SQL logs (default: false ) The datasource pool maximum size. (default: 20 ) sql-load-script Name of the le containing the SQL statements to execute when log.jdbc-warnings jdbc.initial-size starts. no-file force Hibernate to skip SQL import. (default: statistics import.sql ) The initial size of the pool. Enable statiscs collection. (default: false )
batch-fetch-size jdbc.background-validation-interval physical-naming-strategy The interval at which we validate idle connections in the The size of the batches. (default: -1 disabled) Class name of the Hibernate PhysicalNamingStrategy background. (default: 2M ) implementation. maxFetchDepth
jdbc.acquisition-timeout The maximum depth of outer join fetch tree for single-ended globally-quoted-identifiers associations. The timeout before cancelling the acquisition of a new Should quote all identi ers. (default: false ) connection. (default: 5 ) multitenant metrics-enabled jdbc.leak-detection-interval De nes the method for multi-tenancy. Possible values: DATABASE , Metrics published with smallrye-metrics extension (default: NONE , SCHEMA . (default: NONE ) The interval at which we check for connection leaks. false )
multitenant-schema-datasource jdbc.idle-removal-interval second-level-caching-enabled De nes the name of the data source to use in case of SCHEMA The interval at which we try to remove idle connections. (default: Enable/Disable 2nd level cache. (default: true ) approach. 5M ) Database operations: query.query-plan-cache-max-size jdbc.max-lifetime The max lifetime of a connection. The maximum size of the query plan cache. // Insert Developer developer = new Developer(); query.default-null-ordering jdbc.transaction-isolation-level developer.name = "Alex"; Default precedence of null values in ORDER BY . Possible values: developer.persist(); The transaction isolation level. Possible values: UNDEFINED , NONE , none , first , last . (default: none ) READ_UNCOMMITTED , READ_COMMITTED , REPEATABLE_READ , SERIALIZABLE . // Find All database.generation Developer.findAll().list(); jdbc.detect-statement-leaks
Database schema is generation. Possible values: none , create , Warn when a connection is returned to the pool without the // Hibernate Filters drop-and-create , drop , update . (default: none ) application having closed all open statements. (default: true ) Person.findAll().filter("Person.hasName", Parameters.with( "name", "Alex")); database.generation.halt-on-error jdbc.new-connection-sql Query executed when rst using a connection. Stop on the rst error when applying the schema. (default: false ) // Find By Query Developer.find("name", "Alex").firstResult(); database.generation.create-schemas jdbc.validation-query-sql Query executed to validate a connection. Hibernate ORM should create the schemas automatically (for // Delete databases supporting them). Developer developer = new Developer(); developer.id = 1; jdbc.pooling-enabled database.default-catalog developer.delete(); Disable pooling to prevent reuse of Connections. (default: true ) Default catalog. Person.deleteById(id); jdbc.enable-metrics // Delete By Query database.default-schema Enable datasource metrics collection when using quarkus- long numberOfDeleted = Developer.delete("name", "Alex"); Default Schema. smallrye-metrics extension.
database.charset jdbc.additional-jdbc-properties.
EntityManager You can inject EntityManager in your classes: Transactions
@Inject The easiest way to de ne your transaction boundaries is to use the EntityManager em; @Transactional annotation.
@Inject Transactions are mandatory in case of none idempotent org.hibernate.Session session; operations.
@Inject @Transactional org.hibernate.SessionFactory sessionFactory; public void createDeveloper() {}
em.persist(car); You can control the transaction scope:
Multiple datasources @Transactional(REQUIRED) (default): starts a transaction if none was started, stays with the existing one otherwise. You can register more than one datasource. get(@PathParam("id")) , list , add(Developer) , @ApplicationScoped quarkus.hibernate-orm.database.generation=none update(@PathParam("id"), Developer) , delete(@PathParam("id")) @Unremovable @Named("my-credentials-provider") quarkus.hibernate-orm.multitenant=DATABASE You can customize these defaults by using @ResourceProperties and public class CustomCredentialsProvider implements Credentia @MethodProperties annotations. lsProvider { # default tenant @Inject quarkus.datasource.base.db-kind=postgresql Config config; quarkus.datasource.base.username=quarkus_test @ResourceProperties(hal = true, path = "my-developer", halC ... ollectionName = "dev-collections") @Override # Tenant 'mycompany' public interface DeveloperResource extends PanacheEntityRes public Properties getCredentials(String credentials quarkus.datasource.mycompany.db-kind=postgresql ource
If you need more dynamic approach implement: @ApplicationScoped } io.quarkus.hibernate.orm.runtime.tenant.TenantConnectionResolver If hal is true , you need to send the Accept: application/hal+json } HTTP header to get the response. Hibernate Envers Hibernate Reactive
quarkus.datasource.credentials-provider= Quarkus supports Hibernate Envers. custom ./mvnw quarkus:add-extension quarkus.datasource.credentials-provider-name= ./mvnw quarkus:add-extension -Dextensions="quarkus-hibernate-reactive, quarkus-resteas my-credentials-provider -Dextensions="hibernate-envers" y-mutiny, "
Hibernate Multitenancy REST Data Panache Also you need to add the reactive driver (ie quarkus-reactive-pg- client ). Multitenancy is supported using Schema or Database approach. REST Data with Panache extension can generate the basic CRUD First you need to de ne how tenant is identi ed: You can use: org.hibernate.reactive.mutiny.Mutiny or endpoints for your entities and repositories. org.hibernate.reactive.stage.Stage . @RequestScoped @Unremovable ./mvnw quarkus:add-extension @Entity public class CustomTenantResolver implements TenantResolver -Dextensions="hibernate-orm-rest-data-panache" @Table(name = "dev") { public class Developer { } @Inject You also need to add the JDBC driver extension and a JSON RoutingContext context; Marshaller (ie resteasy-jackson ). @Inject CompletionStage
public interface DeveloperResource extends PanacheRepositor Schema approach public CompletionStage
Database approach Default path is a hyphenated lowercase resource name without a su x of or In nispan Quarkus integrates with In nispan: @Produces Con guration in infinispan.xml : FileDescriptorSource bookProtoDefinition() { ./mvnw quarkus:add-extension return FileDescriptorSource -Dextensions="infinispan-client" .fromString("library.proto",
@ProtoFactory public Author(String name, String surname) { Set con guration le location in application.properties : this.name = name; Marshaller this.surname = surname; quarkus.infinispan-embedded.xml-config=infinispan.xml } Using org.infinispan.protostream.MessageMarshaller interface.
@ProtoField(number = 1) public class AuthorMarshaller And you can inject the main entry point for the cache: public String getName() { implements MessageMarshaller
-Dextensions="redis-client" @Override @AutoProtoSchemaBuilder(includeClasses = public void writeTo(ProtoStreamWriter writer, { Book.class, Author.class }, Author author) throws IOException { schemaPackageName = "book_sample") writer.writeString("name", author.getName()); Con gure Redis location: interface BookContextInitializer writer.writeString("surname", author.getSurname()); extends SerializationContextInitializer { } } quarkus.redis.hosts=localhost:6379
@Override public Author readFrom(ProtoStreamReader reader) User written based throws IOException { You can use synchronous or reactive clients: String name = reader.readString("name"); There are three ways to create your schema: String surname = reader.readString("surname"); @Inject return new Author(name, surname); RedisClient redisClient; Proto le } } @Inject Creates a .proto le in the META-INF directory. ReactiveRedisClient reactiveRedisClient;
package book_sample; And producing the marshaller:
message Author { required string name = 1; @Produces required string surname = 2; MessageMarshaller authorMarshaller() { } return new AuthorMarshaller(); }
In case of having a Collection eld you need to use the repeated key (ie repeated Author authors = 4 ). In nispan Embedded
In code ./mvnw quarkus:add-extension -Dextensions="infinispan-embeddedy" Setting proto schema directly in a produced bean. sql-migration-prefix void increment(String key, Integer incrementBy) { Flyway redisClient.incrby(key, incrementBy.toString()); Pre x for versioned SQL migrations (default: V ) } Quarkus integrates with Flyway to help you on database schema migrations. repeatable-sql-migration-prefix:: Pre x for repeatable SQL Uni> keys() { migrations (default: R ) return reactiveRedisClient ./mvnw quarkus:add-extension baseline-on-migrate .keys("*") -Dextensions="quarkus-flyway" .map(response -> { Only migrations above baseline-version will then be applied List
Or can be automatically executed by setting migrate-at-start placeholder-prefix property to true . Pre x of every placeholder (default: ${ ) @Inject RedisClient defaultRedisClient; quarkus.flyway.migrate-at-start=true placeholder-suffix Su x of every placeholder (default: } ) @Inject @RedisClientName("second") List of Flyway parameters. callbacks RedisClient redisClient2; Comma-separated list of fully quali ed class names of Callback quarkus.flyway as pre x is skipped in the next table. implementations.
clean-at-start List of Redis parameters. ignore-future-migrations Execute Flyway clean command (default: false ) Ignore future migrations when reading the history table. quarkus.redis as pre x is skipped in the next table. migrate-at-start health.enabled Multiple Datasources Flyway migration automatically (default: false ) Health check is published in case the smallrye-health extension To use multiple datasource in Flyway you just need to add the is present. (default: true ) locations datasource name just after the flyway property: CSV locations to scan recursively for migrations. Supported password pre xes classpath and filesystem (default: quarkus.datasource.users.jdbc.url=jdbc:h2:tcp://localhost/m The Redis password. classpath:db/migration ). em:users quarkus.datasource.inventory.jdbc.url=jdbc:h2:tcp://localho hosts connect-retries st/mem:inventory The Redis hosts. (default: localhost:6379 ) The maximum number of retries when attempting to connect # ... (default: 0) database quarkus.flyway.users.schemas=USERS_TEST_SCHEMA quarkus.flyway.inventory.schemas=INVENTORY_TEST_SCHEMA The Redis database. schemas # ... CSV case-sensitive list of schemas managed (default: none) timeout The maximum delay to wait before a blocking command to redis table server times out. (default: 10s ) The name of Flyway’s schema history table (default: Liquibase flyway_schema_history ) ssl Quarkus integrates with Liquibase to help you on database schema Enables or disables the SSL on connect. out-of-order migrations. Allows migrations to be run "out of order". clinet-type ./mvnw quarkus:add-extension The Redis client type. Possible values: standalone , cluster , ignore-missing-migrations -Dextensions="quarkus-liquibase" sentinel (default: standalone ) Ignore missing migrations when reading the history table. Then place changelog les to the ( src/main/resources/db ) folder. liquibase-catalog-name You need to de ne the analyzers and normalizers de ned in The liquibase tables catalog name. annotations. You only need to implement You can inject org.quarkus.liquibase.LiquibaseFactory to ElasticsearchAnalysisConfigurer interface and con gure it. programmatically execute the migration. liquibase-schema-name The liquibase tables schema name. public class MyQuarkusAnalysisConfigurer @Inject implements ElasticsearchAnalysisConfigurer { LiquibaseFactory liquibaseFactory; liquibase-tablespace-name @Override try (Liquibase liquibase = liquibaseFactory.createLiquibase The liquibase tables tablespace name. public void configure( ()) { ElasticsearchAnalysisDefinitionContainerContext ct ... Multiple Datasources x) } { To use multiple datasource in Liquibase you just need to add the ctx.analyzer("english").custom() datasource name just after the liquibase property: .withTokenizer("standard") Or can be automatically executed by setting migrate-at-start .withTokenFilters("asciifolding", quarkus.datasource.users.jdbc.url=jdbc:h2:tcp://localhost/m property to true . "lowercase", "porter_stem"); em:users quarkus.datasource.inventory.jdbc.url=jdbc:h2:tcp://localho ctx.normalizer("sort").custom() quarkus.liquibase.migrate-at-start=true st/mem:inventory .withTokenFilters("asciifolding", "lowercase"); # ... } } List of Liquibase parameters. quarkus.liquibase.users.schemas=USERS_TEST_SCHEMA quarkus.liquibase.inventory.schemas=INVENTORY_TEST_SCHEMA quarkus.liquibase as pre x is skipped in the next table. # ... Use Hibernate Search in REST service: change-log The change log le. XML , YAML , JSON , SQL formats supported. public class LibraryResource { (default: db/changeLog.xml ) Hibernate Search @Inject change-log-parameters."
index-defaults.lifecycle.required-status-wait-timeout List of Hibernate-Elasticsearch properties pre xed with Waiting time before failing the bootstrap. @Inject quarkus.hibernate-search.elasticsearch : DynamoDbAsyncClient dynamoDB; index-defaults.refresh-after-write backends Set if index should be refreshed after writes. Uni.createFrom().completionStage(() -> dynamoDB.scan(scanRe Map of con guration of additional backends. quest())).... Possible annotations: version Version of Elasticsearch @Indexed To use it as a local DynamoDB instance: Register entity as full text index analysis-configurer quarkus.dynamodb.region= Class or name of the neab used to con gure. @FullTextField eu-central-1 Full text search. Need to set an analyzer to split tokens. quarkus.dynamodb.endpoint-override= hosts http://localhost:8000 quarkus.dynamodb.credentials.type=STATIC List of Elasticsearch servers hosts. @KeywordField quarkus.dynamodb.credentials.static-provider The string is kept as one single token but can be normalized. .access-key-id=test-key username quarkus.dynamodb.credentials.static-provider Username for auth. IndexedEmbedded .secret-access-key=test-secret Include the Book elds into the Author index. password Password for auth. @ContainerExtraction If you want to work with an AWS account, you’d need to set it with: Sets how to extract a value from container, e.g from a Map . connection-timeout quarkus.dynamodb.region=
TLS manager: none , DEFAULT Parameter Default Description tls-managers- system-property system-property , provider.type connection- Connection file-store 10S default- acquisition-timeout acquisation timeout. provider.async- Should fetch false credential-update- credentials async. tls-managers- enabled Max time to provider.file- Path to key store. connection-max-idle- 60S connection to be store.path time opened. default- Should reuse the last provider.reuse-last- true successful tls-managers- provider-enabled credentials. connection-timeout Connection timeout. provider.file- Key store type. store.type
STATIC connection-time-to- Max time connection 0 live to be open. tls-managers- provider.file- Key store password. static- store.password provider.access-key- AWS access key id. socket-timeout 30S Time to wait for data. id In case of asynchronous client, the next parameters can be max-connections 50 Max connections. con gured pre xed by quarkus.dynamodb.async-client : static- AWS secret access Parameter Default Description provider.secret- key. access-key Client send an HTTP expect-continue- true expect-continue connection- Connection enabled 10S handsake. acquisition-timeout acquisation timeout. Parameter Default Description Parameter Default Description quarkus.s3.endpoint-override=http://localhost:8008 quarkus.s3.interceptors=io.quarkus.it.amazon.s3.S3ModifyRes Max time to Sets the HTTP connection-max-idle- protocol HTTP_1_1 ponse 60S connection to be protocol. time quarkus.s3.aws.region=us-east-1 opened. quarkus.s3.aws.credentials.type=static quarkus.s3.aws.credentials.static-provider.access-key-id=te Max number of max-http2-streams st-key connection-timeout Connection timeout. concurrent streams. quarkus.s3.aws.credentials.static-provider.secret-access-ke y=test-secret
connection-time-to- Max time connection Enable custom event 0 event-loop.override false live to be open. loop conf. You can inject asynchronous client too:
Max number of event-loop.number-of- Number of threads to @Inject max-concurrency 50 concurrent threads use in event loop. S3AsyncClient s3AsyncClient; connections.
event-loop.thread- aws-java-sdk- Pre x of thread And you need to add the asynchronous Netty client: Connections in pool name-prefix NettyEventLoop names. use-idle-connection- true should be closed reaper asynchronously.
Quarkus integrates with Neo4j: proxy.enabled false Enables HTTP proxy. You need to set a HTTP client either URL Connection : ./mvnw quarkus:add-extension -Dextensions="quarkus-neo4j" proxy.non-proxy- List of non proxy
uri tls-managers- provider.file- Key store type. URI of Neo4j. (default: localhost:7687 ) quarkus.s3.sync-client.type=apache store.type authentication.username Username. (default: neo4j ) tls-managers- And con gure it: provider.file- Key store password. authentication.password store.password Password. (default: neo4j )
SSL Provider ( jdk , authentication.disabled ssl-provider openssl , openssl- Disable authentication. (default: false ) refcnt ). Enable metrics. (default: false ) @GET quarkus.mongodb as pre x is skipped in the following table. public Publisher
And Quarkus Maven Plugin with next con guration: @Inject max-connection-life- Life time of pooled Duration com.mongodb.client.MongoClient client; time connection.
If you are using Neo4j 4.0, you can use fully reactive. Add the next extension: quarkus-resteasy-mutiny . Inject the instance using socket-timeout Duration @io.quarkus.mongodb.runtime.MongoClientName annotation:
tls-insecure boolean [false] Insecure TLS. @Inject @MongoClientName("users") MongoClient mongoClient1; tls boolean [false] Enable TLS Parameter Type Description Parameter Type Description person.persist(); person.update(); Implies hosts given Source of the replica-set-name String credentials.auth- person.delete(); are a seed list. String authentication source credentials. List
local-threshold Duration to make a server long updated = Person.update("name", "Mortal").where("statu eligible. MongoDB Panache s", Status.Alive);
You can also use the Panache framework to write persistence part Frequency to long countAll = Person.count(); when using MongoDB. heartbeat-frequency Duration determine the state of servers. Person.deleteById(id); ./mvnw quarkus:add-extension Person.delete("status", Status.Alive); -Dextensions="mongodb-panache" primary , primaryPreferred , All list methods have equivalent stream versions. read-preference secondary , Read preferences. MongoDB con guration comes from MongoDB Client section. secondaryPreferred , Pagination nearest @MongoEntity(collection="ThePerson") You can also use pagination: public class Person extends PanacheMongoEntity { public String name; Max number of PanacheQuery
concurrent Person.find("status", Status.Alive); max-wait-queue-size Int @BsonProperty("birth") operations allowed to livingPersons.page(Page.ofSize(25)); public LocalDate birthDate; wait.
// get the first page public Status status; List
Possible annotations in elds: @BsonId (for custom ID), write- Journal writing boolean [true] @BsonProperty and @BsonIgnore . concern.journal aspect. Range
@MongoEntity is optional. PanacheQuery
write-concern.retry- Retry writes if @MongoEntity(collection = "TheBook", clientName = "client2" boolean [false] writes network fails. , database = "database2") You cannot mix pagination and range.
Queries write-concern.w- Timeout to all write Duration Methods provided are similar of the ones shown in Persistence timeout commands. section. Native MongoDB queries are supported (if they start with { or org.bson.Document instance) as well as Panache Queries. Panache Queries equivalence in MongoDB: credentials.username String Username.
firstname = ?1 and status = ?2 → {'firstname': ?1, 'status': ? 2} credentials.password String Password.
amount > ?1 and firstname != ?2 → {'amount': {'$gt': ?1}, 'firstname': {'$ne': ?2}} credentials.auth- MONGO-CR , GSSAPI , mechanism PLAIN , MONGODB-X509 lastname like ?1 → {'lastname': {'$regex': ?1}}
lastname is not null → {'lastname':{'$exists': true}} Then you can de ne interfaces for de ning endpoints: PanacheQL refers to the Object parameter name but native
t(); CompletionStage> allPersons = Reactive @ApplicationScoped Person.listAll(); FruitDao produceFruitDao() { Publisher
> persons = ReactivePersonEntity.find( @ApplicationScoped "lastname", name).project(PersonName.class).list(); public class PersonRepository Cassandra con guration: implements PanacheMongoRepository
@Produces(MediaType.TEXT_PLAIN) @Select ./mvnw quarkus:add-extension public CompletionStage
.run() @Mapper @ApplicationScoped .thenApply(list -> list.toString()); public interface FruitMapper { public static class ReactiveHello { }
@DaoFactory public Uni
Mutiny and JAX-RS RxJava 2
Apart from the CompletionStage support, there is also support for
From RxJava2 : Uni
To RxJava2 : CompletableFuture
io.quarkus:quarkus-smallrye-reactive-messaging" Completable completable = multi.convert().with(MultiRxConve RESTEasy Reactive is a new implementation of JAX-RS but fully rters.toCompletable()); reactive. Single
Reactor API @Outgoing("my-in-memory") public Flowable
or in Mutiny: From Reactor : @ApplicationScoped @Inject @Stream(“out”) mp.messaging.outgoing.generated-price.connector= public class ProducerData { Publisher
Patterns public BeerDeserializer() { REST API → Message Possible implementations are: super(Beer.class); } In-Memory @Inject @Stream(“in”) } Emitter
memory stream, if not then stream type is de ned by connector emitter.send(message); eld. AMQP
Kafka To integrate with AMQP you need to add next extensions: Message → Message To integrate with Kafka you need to add next extensions: ./mvnw quarkus:add-extension @Incoming(“in”) -Dextensions="reactive-messaging-amqp" @Outgoing(“out”) mvn quarkus:add-extension public String process(String in) { -Dextensions=" } io.quarkus:quarkus-smallrye-reactive-messaging-kafka" Then @Outgoing , @Incoming or @Stream can be used.
AMQP con guration schema: mp.messaging.[outgoing|incoming]. Message → SSE Then @Outgoing , @Incoming or @Stream can be used. {stream-name}.
The connector type is smallrye-kafka . Common Reeactive DataSource Client con guration properties amqp-username=quarkus Kafka Streams pre xed with quarkus.datasource : amqp-password=quarkus # write Create streaming queries with the Kafka Streams API. reactive.cache-prepared-statements mp.messaging.outgoing.generated-price.connector= Prepared statements should be cached on the client side. smallrye-amqp ./mvnw quarkus:add-extension (default: false ) mp.messaging.outgoing.generated-price.address= -Dextensions="kafka-streams" prices mp.messaging.outgoing.generated-price.durable= reactive.url true The datasource URL. All we need to do for that is to declare a CDI producer method # read which returns the Kafka Streams mp.messaging.incoming.prices.connector= reactive.max-size org.apache.kafka.streams.Topology : smallrye-amqp The datasource pool maximum size. mp.messaging.incoming.prices.durable= true @ApplicationScoped reactive.trust-all public class TopologyProducer { @Produces All server certi cates should be trusted. (default: false ) public Topology buildTopology() { A complete list of supported properties for AMQP. org.apache.kafka.streams.StreamsBuilder.StreamsBuil reactive.trust-certificate-pem MQTT der Trust con guration in the PEM format. builder = new StreamsBuilder(); To integrate with MQTT you need to add next extensions: // ... reactive.trust-certificate-jks builder.stream() Trust con guration in the JKS format. .join() ./mvnw quarkus:add-extension // ... -Dextensions="vertx, smallrye-reactive-streams-operator reactive.trust-certificate-pfx .toStream() s .to(); Trust con guration in the PFX format. smallrye-reactive-messaging" return builder.build(); } reactive.key-certificate-pem } Key/cert con guration in the PEM format. And add io.smallrye.reactive:smallrye-reactive-messaging-mqtt- 1.0:0.0.10 dependency in your build tool. reactive.key-certificate-jks Previous example produces content to another stream. If you want Then @Outgoing , @Incoming or @Stream can be used. Key/cert con guration in the JKS format. to write interactive queries, you can use Kafka streams. MQTT con guration schema: mp.messaging.[outgoing|incoming]. reactive.key-certificate-pfx {stream-name}.> fruits = public class ArtemisConsumerManager { client.preparedQuery("SELECT * FROM fruits") ActiveMQ Artemis .onItem().apply(rowSet -> { @Inject ConnectionFactory connectionFactory; JsonArray jsonArray = new JsonArray(); Quarkus uses Reactive Messaging to integrate with messaging
for (Row row : rowSet) { systems, but in case you need deeper control when using Apache private Connection connection; jsonArray.add(from(row)); ActiveMQ Artemis there is also an extension: } return jsonArray; @PostConstruct }) ./mvnw quarkus:add-extension public void init() throws JMSException { -Dextensions="quarkus-artemis-core" connection = connectionFactory.createConnection(); connection.start(); } Reactive MySQL Client And then you can inject } org.apache.activemq.artemis.api.core.client.ServerLocator You can use Reactive MySQL to execute queries to MySQL instance. database in a reactive way, instead of using JDBC. Con guration options are the same as Artemis core. @ApplicationScoped ./mvnw quarkus:add-extension public class ArtemisConsumerManager { -Dextensions="quarkus-reactive-mysql-client" Vert.X Reactive Clients @Inject ServerLocator serverLocator; Vert.X Reactive clients in Quarkus, the next clients are supported Database con guration is the same as shown in Persistence and you need to add the dependency to use them: section, but URL is different as it is not a jdbc. private ClientSessionFactory connection; Vert.X Mail Client @PostConstruct quarkus.datasource.db-kind=mysql io.smallrye.reactive:smallrye-mutiny-vertx-mail-client quarkus.datasource.reactive.url=mysql:///your_database public void init() throws Exception { connection = serverLocator.createSessionFactory(); Vert.X MongoDB Client } } io.smallrye.reactive:smallrye-mutiny-vertx-mongo-client Then you can inject io.vertx.mutiny.mysqlclient.MySQLPool class. Vert.X Redis Client Reactive DB2 Client io.smallrye.reactive:smallrye-mutiny-vertx-redis-client And con gure ServerLocator in application.properties : You can use Reactive DB2 to execute queries to DB2 database in a Vert.X Cassandra Client reactive way, instead of using JDBC. quarkus.artemis.url=tcp://localhost:61616 io.smallrye.reactive:smallrye-mutiny-vertx-cassandra-client
./mvnw quarkus:add-extension Vert.X Consul Client -Dextensions="quarkus-reactive-db2-client" You can con gure ActiveMQ Artemis in application.properties le io.smallrye.reactive:smallrye-mutiny-vertx-consul-client by using next properties pre xed with quarkus :
artemis.url Vert.X Kafka Client Database con guration is the same as shown in Persistence Connection URL. io.smallrye.reactive:smallrye-mutiny-vertx-kafka-client section, but URL is different as it is not a jdbc.
artemis.username Vert.X AMQP Client quarkus.datasource.db-kind=db2 Username for authentication. io.smallrye.reactive:smallrye-mutiny-vertx-amqp-client quarkus.datasource.reactive.url=vertx-reactive:db2://localh ost:50005/hreact artemis.password Vert.X RabbitMQ Client Password for authentication. io.smallrye.reactive:smallrye-mutiny-vertx-rabbitmq-client
Then you can inject i i db2 li 2 l class Example of Vert.X Web Client: quarkus.sqs.sync-client.type=apache TLS
@Inject You can trust all certi cates globally by using quarkus.tls.trust- Vertx vertx; You can go async by using Mutiny: all=true
private WebClient client; RBAC @Inject @PostConstruct software.amazon.awssdk.services.sqs.SqsAsyncClient sqs; You can set RBAC using annotations or in application.properties . void initialize() { this.client = WebClient.create(vertx, ...); Uni.createFrom() Annotations } .completionStage( sqs.sendMessage(m -> m.queueUrl(queueUrl).messageBo You can de ne roles by using dy(message)) javax.annotation.security.RolesAllowed annotation. ) Amazon SQS Client .onItem()... @RolesAllowed("Subscriber")
return Uni.createFrom() ./mvnw quarkus:add-extension .completionStage( -Dextensions="amazon-sqs" sqs.receiveMessage(m -> m.maxNumberOfMessages(10).q You can use io.quarkus.security.Authenticated as a shortcut of ueueUrl(queueUrl)) @RolesAllowed("*") . ) Injecting the client: .onItem() To alter RBAC behaviour there are two con guration properties:
@Inject quarkus.security.deny-unannotated=true software.amazon.awssdk.services.sqs.SqsClient sqs; And you need to add the asynchronous Netty client:
SendMessageResponse response = sqs.sendMessage(m -> m.queue
quarkus.security.deny-unannotated If true denies by default all CDI methods and JAX-RS endpoints. And con gure it: Con guration properties are the same as Amazon DynamoDB but changing the pre x from dynamodb to sqs . (default: false )
quarkus.sqs.endpoint-override=http://localhost:8010 By default in Quarkus, if an incoming request has a credential the quarkus.sqs.aws.region=us-east-1 request will always be authenticated (even if the target page does quarkus.sqs.aws.credentials.type=static not require authentication). quarkus.sqs.aws.credentials.static-provider.access-key-id=t est-key You can change this behaviour by setting quarkus.sqs.aws.credentials.static-provider.secret-access-k quarkus.http.auth.proactive property to false . ey=test-secret File Con guration
De ning RBAC in application.properties instead of using You need to set a HTTP client either URL Connection : annotations.
or Apache HTTP:
permit smallrye.jwt.require.named-principal quarkus.http.auth.permission.permit1.methods= mvn quarkus:add-extension A token must have a upn or preferred_username or sub claim set GET -Dextensions="io.quarkus:quarkus-smallrye-jwt" if using java.security.Principal . True makes throw an exception
if not set. (default: false ). quarkus.http.auth.permission.deny1.paths= /forbidden Minimum JWT required claims: typ , alg , kid , iss , sub , exp , iat , quarkus.http.auth.permission.deny1.policy= smallrye.jwt.path.sub jti , upn , groups . deny Path to the claim with subject name.
You can inject token by using JsonWebToken or a claim individually by smallrye.jwt.claims.sub using @Claim . You need to provide permissions set by using the roles-allowed Default sub claim value. property or use the built-in ones deny , permit or authenticated . @Inject JsonWebToken jwt; smallrye.jwt.path.groups You can use enabled property (ie Path to the claim containing the groups. quarkus.http.auth.permission.permit1.enabled ) to enable the entire @Inject permission set. @Claim(standard = Claims.preferred_username) smallrye.jwt.groups-separator String name; Testing Separator for splitting a string which may contain multiple group values. (default. ` `). Quarkus provides explicit support for testing with different users, @Inject @Claim("groups") and with the security subsystem disabled. smallrye.jwt.claims.groups Set
mp.jwt.verify.publickey smallrye.jwt.time-to-live Public Key text itself to be supplied as a string. BouncyCastle The maximum number of seconds that a JWT may be issued for use. mp.jwt.verify.publickey.location Relative path or URL of a public Quarkus supports BouncyCastle, you only need to add the key. smallrye.jwt.sign.key-location BouncyCastle dependency and con gure the security provider: mp.jwt.verify.issuer Location of a private key which will be used to sign the claims iss accepted as valid. when either a no-argument sign() or innerSign() method is called. smallrye.jwt.token.header smallrye.jwt.encrypt.key-location Location of a public key which will be used to encrypt the claims tenant-enabled Jwt.claims() or inner JWT when a no-argument encrypt() method is called. .issuer("https://server.com") If the tenant con guration is enabled. (default: true ) .claim("customClaim", 3) Supported public key formats: .sign(createKey()); application-type
PKCS#8 PEM The application type. Possible values: web_app , service . (default: JwtSignatureBuilder jwtSignatureBuilder = Jwt.claims("/test service ) JWK JsonToken.json").jws(); jwtSignatureBuilder connection-delay .signatureKeyId("some-key-id") JWKS The maximum amount of time the adapter will try connecting. .signatureAlgorithm(SignatureAlgorithm.ES256) JWK Base64 URL .header("custom-header", "custom-value"); auth-server-url .sign(createKey()); JWKS Base64 URL The base URL of the OpenID Connect (OIDC) server. Jwt.claims("/testJsonToken.json") To send a token to server-side you should use Authorization .encrypt(createKey()); introspection-path header: curl -H "Authorization: Bearer eyJraWQiOi… " . Relative path of the RFC7662 introspection service. JwtEncryptionBuilder jwtEncryptionBuilder = Jwt.claims("/te To inject claim values, the bean must be @RequestScoped CDI stJsonToken.json").jwe(); jwks-path scoped. If you need to inject claim values in scope with a lifetime jwtEncryptionBuilder Relative path of the OIDC service returning a JWK set. greater than @RequestScoped then you need to use .keyEncryptionKeyId("some-key-id") javax.enterprise.inject.Instance interface. .keyEncryptionAlgorithm(KeyEncryptionAlgorithm.ECDH_E public-key S_A256KW) @Inject .header("custom-header", "custom-value"); Public key for the local JWT token veri cation @Claim(standard = Claims.iat) .encrypt(createKey()); private Instance
You can also protect resources with security annotations. token.expiration-grace Expiration grace period in seconds. @GET @RolesAllowed("admin") token.principal-claim Name of the claim which contains a principal name.
Con gure application to Keycloak service in application.properties token.refresh-expired le. If property is enabled then a refresh token request is performed.
quarkus.oidc.realm=quarkus credentials.secret quarkus.oidc.auth-server-url=http://localhost:8180/auth The client secret quarkus.oidc.resource=backend-service quarkus.oidc.bearer-only=true authentication.redirect-path quarkus.oidc.credentials.secret=secret Relative path for calculating a redirect_uri query parameter.
authentication.restore-path-after-redirect Con guration options with quarkus.oidc pre x: The original request URI used before the authentication will be enabled restored after the user has been redirected back to the application. (default: true ) The OIDC is enabled. (default: true ) authentication.scopes quarkus.oidc.auth-server-url=http://localhost:8180/auth/rea Authenticating via HTTP List of scopes. lms/quarkus quarkus.oidc.client-id=multi-tenant-client HTTP basic auth is enabled by the quarkus.http.auth.basic=true authentication.extra-params quarkus.oidc.application-type=web-app property. Additional properties which will be added as the query parameters . quarkus.oidc.tenant-b.auth-server-url=https://accounts.goog HTTP form auth is enabled by the le.com quarkus.http.auth.form.enabled=true property. authentication.cookie-path quarkus.oidc.tenant-b.application-type=web-app quarkus.oidc.tenant-b.client-id=xxxx Then you need to add elytron-security-properties-file or elytron- Cookie path parameter. quarkus.oidc.tenant-b.credentials.secret=yyyy security-jdbc . quarkus.oidc.tenant-b.token.issuer=https://accounts.google. proxy.host com Security with Properties File The host (name or IP address) of the Proxy. quarkus.oidc.tenant-b.authentication.scopes=email,profile,o penid You can also protect endpoints and store identities (user, roles) in proxy.port the le system. The port number of the Proxy. (default: 80 ) OAuth2 mvn quarkus:add-extension proxy.username -Dextensions="elytron-security-properties-file" The username to authenticate. Quarkus integrates with OAuth2 to be used in case of opaque tokens (none JWT) and its validation against an introspection proxy.password endpoint. You need to con gure the extension with users and roles les: The password to authenticate. And con guration in src/main/resources/application.properties : mvn quarkus:add-extension end-session-path -Dextensions="security-oauth2" quarkus.security.users.file.enabled=true Relative path of the OIDC end_session_endpoint . quarkus.security.users.file.users=test-users.properties quarkus.security.users.file.roles=test-roles.properties logout.path And con guration in src/main/resources/application.properties : quarkus.security.users.file.auth-mechanism=BASIC The relative path of the logout endpoint at the application. quarkus.security.users.file.realm-name=MyRealm quarkus.oauth2.client-id=client_id quarkus.security.users.file.plain-text=true logout.post-logout-path quarkus.oauth2.client-secret=secret Relative path of the application endpoint where the user should quarkus.oauth2.introspection-url=http://oauth-server/intros pect be redirected to after logging out. Then users.properties and roles.properties : tls.verification scott=jb0ss Sets the TLs veri cation. Possible values: REQUIRED , NONE . And you can map roles to be used in security annotations. jdoe=p4ssw0rd (default: REQUIRED ). @RolesAllowed("Subscriber") With Keycloak OIDC server https://host:port/auth/realms/{realm} where {realm} has scott=Admin,admin,Tester,user to be replaced by the name of the Keycloak realm. jdoe=NoRolesUser Con guration options: You can use quarkus.http.cors property to enable consuming form different domain. quarkus.oauth2.enabled Determine if the OAuth2 extension is enabled. (default: true ) IMPORTANT: If plain-text is set to false (or omitted) then Multi-tenancy passwords must be stored in the form MD5 username quarkus.oauth2.client-id ( :`realm`:`password`). Multi-tenancy is supported by adding a sub-category to OIDC con guration properties (ie quarkus.oidc.{tenent_id}.property ). The OAuth2 client id used to validate the token. Elytron File Properties con guration properties. Pre x quarkus.security.users is skipped. quarkus.oauth2.client-secret The OAuth2 client secret used to validate the token. file.enabled The le realm is enabled. (default: false ) quarkus.oauth2.introspection-url URL used to validate the token and gather the authentication file.auth-mechanism claims. The authentication mechanism. ( default: BASIC )
quarkus.oauth2.role-claim file.realm-name The claim that is used in the endpoint response to load the roles The authentication realm name. (default: Quarkus ) ((default: scope ) file.plain-text If passwords are in plain or in MD5. (default: false ) You still need to add the database driver (ie jdbc-h2 ). principal-query.bcrypt-password-mapper.salt-index file.users You need to con gure JDBC and Elytron JDBC Realm: The index column containing the Bcrypt salt. (default: 0 ) Classpath resource of user/password. (default: users.properties ) quarkus.datasource.url= principal-query.bcrypt-password-mapper.salt-encoding quarkus.datasource.driver=org.h2.Driver A string referencing the salt encoding ( BASE64 or HEX ). (default: quarkus.datasource.username=sa file.roles BASE64 ) quarkus.datasource.password=sa Classpath resource of user/role. (default: roles.properties )
principal-query.bcrypt-password-mapper.iteration-count-index quarkus.security.jdbc.enabled=true Embedded Realm quarkus.security.jdbc.principal-query.sql= The index column containing the Bcrypt iteration count. (default: 0 ) You can embed user/password/role in the same SELECT u.password, u.role FROM test_user u WHERE u.user =? application.properties : quarkus.security.jdbc.principal-query For multiple datasources you can use the datasource name in the .clear-password-mapper.enabled=true properties: quarkus.security.users.embedded.enabled=true quarkus.security.jdbc.principal-query quarkus.security.users.embedded.plain-text=true .clear-password-mapper.password-index=1 quarkus.datasource.url= quarkus.security.users.embedded.users.scott=jb0ss quarkus.security.jdbc.principal-query quarkus.security.jdbc.principal-query.sql= quarkus.security.users.embedded.roles.scott=admin,tester,us .attribute-mappings.0.index=2 er quarkus.security.jdbc.principal-query quarkus.datasource.permissions.url= quarkus.security.users.embedded.auth-mechanism=BASIC .attribute-mappings.0.to=groups quarkus.security.jdbc.principal-query.permissions.sql=
IMPORTANT: If plain-text is set to false (or omitted) then You need to set the index (1-based) of password and role. passwords must be stored in the form MD5 Security with JPA ( username :`realm`:`password`). Elytron JDBC Realm con guration properties. Pre x You can also protect endpoints and store identities in a database quarkus.security.jdbc is skipped. Pre x quarkus.security.users.embedded is skipped. using JPA. auth-mechanism algorithm The authentication mechanism. (default: BASIC ) mvn quarkus:add-extension Determine which algorithm to use. Possible values: DIGEST_MD5 , -Dextensions="security-jpa" DIGEST_SHA DIGEST_SHA_256 DIGEST_SHA_384 DIGEST_SHA_512 , , , , realm-name DIGEST_SHA_512_256 . (default: DIGEST_MD5 ) The authentication realm name. (default: Quarkus ) Also you might require jdbc-postgresql , resteasy , file.enabled enabled hibernate-orm-panache . The le realm is enabled. (default: false ) If the properties store is enabled. (default: false ) file.auth-mechanism principal-query.sql The authentication mechanism. (default: BASIC ) The sql query to nd the password. file.realm-name principal-query.datasource The authentication realm name. (default: Quarkus ) The data source to use. file.plain-text principal-query.clear-password-mapper.enabled If passwords are in plain or in MD5. (default: false ) If the clear-password-mapper is enabled. (default: false ) file.users.* principal-query.clear-password-mapper.password-index * is user and value is password. The index of column containing clear password. (default: 1 ) file.roles.* principal-query.bcrypt-password-mapper.enabled * is user and value is role. If the bcrypt-password-mapper is enabled. (default: false )
Security with a JDBC Realm principal-query.bcrypt-password-mapper.password-index The index of column containing password hash. (default: 0 ) You can also protect endpoints and store identities in a database.
principal-query.bcrypt-password-mapper.hash-encoding mvn quarkus:add-extension A string referencing the password hash encoding ( BASE64 or HEX ). -Dextensions="elytron-security-jdbc" (default: BASE64 ) The identi er ( baseFilter ) which correlates to the provided user @io.quarkus.security.jpa.UserDefinition quarkus.security.ldap.enabled=true (default: uid ) @Table(name = "test_user") quarkus.security.ldap.dir-context.principal=uid=tool,ou=acc @Entity ounts,o=YourCompany,c=DE public class User extends PanacheEntity { quarkus.security.ldap.dir-context.url=ldaps://ldap.server.l identity-mapping.search-base-dn @io.quarkus.security.Username ocal The dn where we look for users. public String name; quarkus.security.ldap.dir-context.password=PASSWORD quarkus.security.ldap.identity-mapping.rdn-identifier=uid identity-mapping.attribute-mappings.
quarkus.security.ldap.identity-mapping.attribute-mapping identity-mapping.attribute-mappings.
@io.quarkus.security.RolesValue And annotate the test: And con guring Vault in application.properties : public String role; } @QuarkusTestResource(io.quarkus.test.ldap.LdapServerTestRes # vault url ource.class) quarkus.vault.url=http://localhost:8200 public class ElytronLdapExtensionTestResources {
} You need to con gure JDBC: quarkus.vault.authentication.userpass.username= bob quarkus.datasource.url=jdbc:postgresql:security_jpa quarkus.vault.authentication.userpass.password= quarkus.datasource.driver=org.postgresql.Driver Elytron LDAP Realm con guration properties. Pre x sinclair quarkus.datasource.username=quarkus quarkus.security.ldap is skipped. quarkus.datasource.password=quarkus # path within the kv secret engine enabled quarkus.vault.secret-config-kv-path= quarkus.hibernate-orm.database.generation=drop-and-create Enable the LDAP elytron module (default: false ) myapps/vault-quickstart/config quarkus.vault.secret-config-kv-prefix.singer.paths= realm-name multi/singer1, multi/singer2 Security with LDAP The elytron realm name (default: Quarkus )
You can also protect endpoints and store identities in a database direct-verification vault kv put secret/myapps/vault-quickstart/config a-private- key=123456 using LDAP. Provided credentials are veri ed against LDAP (default: true )
vault kv put secret/multi/singer1 firstname=paul mvn quarkus:add-extension dir-context.url -Dextensions="elytron-security-ldap" The url of the LDAP server. @ConfigProperty(name = "a-private-key") String privateKey; dir-context.principal User ( bindDn ) which is used to connect to LDAP server. @ConfigProperty(name = "singer.firstname") String firstName; dir-context.password The password ( bindCredential ) which belongs to the principal. You can access the KV engine programmatically: identity-mapping.rdn-identifier @Inject @Inject @Inject VaultKVSecretEngine kvSecretEngine; VaultTransitSecretEngine transit; VaultSystemBackendEngine vaultSystemBackendEngine;
kvSecretEngine.readSecret("myapps/vault-quickstart/" + vaul transit.encrypt("my_encryption", text); @Inject tPath).toString(); transit.decrypt("my_encryption", text).asString(); VaultKubernetesAuthService vaultKubernetesAuthService; transit.sign("my-sign-key", text); Map
No password is set as it is fetched from Vault. CreateKeyParameters createKeyParameters = new CreateKeyPara authentication.app-role.role-id meters("Google", "[email protected]"); Role Id for AppRole auth Dynamic credentials are also supported: createKeyParameters.setPeriod("30m"); Running the following dynamic database con g in Vault: authentication.app-role.secret-id /** Generate Key (QR code) */ Secret Id for AppRole auth vault write database/config/mydb plugin_name=postgresql-database- final Optional
/** Login logic */ quarkus.datasource.db-kind= boolean valid = vaultTOTPSecretEngine.validateCode("my_key_ authentication.userpass.password postgresql 2", keyCode); quarkus.datasource.credentials-provider= Password for userpass auth mydatabase quarkus.datasource.jdbc.url= authentication.userpass.password-wrapping-token jdbc:postgresql://localhost:5432/mydatabase Vault Provisioning Wrapping token containing a password. password and password- wrapping-token are exclusive. Vault extension offers façade classes to Vault provisioning functions: Username and password are fetched from Vault authentication.kubernetes.role Kubernetes authentication role Transit
authentication.kubernetes.jwt-token-path Location of the le containing the Kubernetes JWT token
renew-grace-period Renew grace period duration (default: 1H ) quarkus.kms.endpoint-override=http://localhost:8011
TLS will be active (default: true ) quarkus.sqs.sync-client.type=apache @Inject IamAsyncClient async; connect-timeout Tiemout to establish a connection (default: 5S ) You can go async by using Mutiny: read-timeout quarkus.iam.endpoint-override=${iam.url} @Inject quarkus.iam.aws.region=us-east-1 Request timeout (default: 1S ) software.amazon.awssdk.services.kms.KmsAsyncClient kms; quarkus.iam.aws.credentials.type=static quarkus.iam.aws.credentials.static-provider.access-key-id=t credentials-provider."credentials-provider".database-credentials- Uni.createFrom().completionStage( est-key role kms.encrypt(req -> req.keyId(keyArn).plaintext(SdkByte quarkus.iam.aws.credentials.static-provider.secret-access-k Database credentials role s.fromUtf8String(data)) ey=test-secret )) credentials-provider."credentials-provider".kv-path A path in vault kv store, where we will nd the kv-key Con guration properties are the same as Amazon DynamoDB but And you need to add the asynchronous Netty client: changing the pre x from dynamodb to iam . credentials-provider."credentials-provider".kv-key
Key name to search in vault path kv-path (default: password )
mvn quarkus:add-extension -Dextensions="amazon-kms" Con guration properties are the same as Amazon DynamoDB but changing the pre x from dynamodb to kms .
@Inject Amazon IAM KmsClient kms;
mvn quarkus:add-extension kms.encrypt(req -> req.keyId(keyArn).plaintext( -Dextensions="quarkus-amazon-iam" SdkBytes.fromUtf8String(data))).ciphertextBlob();
You need to set a HTTP client either URL Connection : HTTP Con guration The le path to a service certi cate or certi cate chain in PEM enable-compression format. Relative to src/main/resources . If responses should be compressed. You can con gure HTTP parameters. Using quarkus.http pre x: ssl.certificate.key-file read-timeout cors The le path to the corresponding certi cate private key in PEM Http connection read timeout for blocking IO. (default: 60s ) Enable CORS. (default: false ) format. Relative to src/main/resources . body.handle-file-uploads cors.origins ssl.certificate.key-store-file If the les sent using multipart/form-data will be stored locally. CSV of origins allowed. (dedault: Any request valid.) The key store contains the certi cate information. Relative to (default: true ) src/main/resources .
cors.methods body.uploads-directory ssl.certificate.key-store-file-type CSV of methods valid. (default: Any method valid.) The directory where the les sent using multipart/form-data The key store type. It is automatically detected based on the le should be stored. (default: file-uploads ) cors.headers name or can be set manually. Supported values are: JKS , JCEKS , P12 , PKCS12 or PFX . CSV of valid allowed headers. (default: Any requested header body.merge-from-attributes valid.) If the form attributes should be added to the request parameters. ssl.certificate.key-store-password (default: true ) cors.exposed-headers The password to open the key store le. CSV of valid exposed headers. body.delete-uploaded-files-on-end ssl.certificate.trust-store-file The trust store location which If the uploaded les should be removed after serving the request. contains the certi cate information of the certi cates to trust. port Relative to src/main/resources . The HTTP port. (default: 8080 ) body.preallocate-body-buffer ssl.certificate.trust-store-file-type If the body buffer should pre-allocated based on the Content- test-port The trust store type. It is automatically detected based on the le Length header value. (default: 1K ) The HTTP test port. (default: 8081 ) name or can be set manually. auth.session.encryption-key host ssl.certificate.trust-store-password The encryption key that is used to store persistent logins. The HTTP host. (default: 0.0.0.0 ) The password to open the trust store le. so-reuse-port host-enabled ssl.cipher-suites Enable socket reuse port. Enable listening to host:port. (default: true ) A list of strings of cipher suites to use. If not provided, a reasonable default is selected. tcp-quick-ack ssl-port Enable tcp quick ack. The HTTPS port. (default 8443 ) ssl.protocols The list of protocols to explicitly enable. (default: TLSv1.3 and tcp-cork test-ssl-port TLSv1.2 ). Enable tcp cork. The HTTPS port used to run tests. (default 8444 ) ssl.client-auth tcp-fast-open proxy-address-forwarding Con gures the engine to require/request client authentication. Enable tcp fast open. The address, scheme etc will be set from headers forwarded by Possible values are: none , request and required . (default: none ). the proxy server. domain-socket io-threads Path to a unix domain socket. (default: allow-forwarded The number if IO threads used to perform IO. /var/run/io.quarkus.app.socket ) Proxy address forwarding is enabled then the standard Forwarded header will be used, rather than the more common but not limits.max-header-size domain-socket-enabled standard X-Forwarded-For . The maximum length of all headers. (default: 20k ) Enables domain socket.
insecure-requests limits.max-body-size record-request-start-time If insecure requests are allowed. Possible values: enabled , The maximum size of a request body. (default: 10M ) If enabled then start time will be recorded to enable logging of redirect , disable . (default: enabled ) total request time. (default: false ) limits.max-chunk-size http2 The max HTTP chunk size. access-log.enabled Enables HTTP/2. (default: true ) If access logging is enabled. (default: false ) limits.max-initial-line-length ssl.port The maximum length of the initial line. (default: 4096 ) access-log.pattern The HTTPS port. (default: 8443 ) The access log pattern. (default: common ) idle-timeout ssl certificate file Htt ti idl ti t (d f lt ) l l t fil If logging should be done to a separate le. (default: false ) @Path("/book") @Target({ElementType.METHOD}) public class BookResource { @Retention(RetentionPolicy.RUNTIME) access-log.base-file-name @HttpMethod("LOCK") The access log le base name. (default: quarkus ) @GET public @interface LOCK { @Produces(MediaType.APPLICATION_JSON) } access-log.log-directory public List
@DELETE Injecting access-log.log-suffix @Path("{isbn}") The log le su x. (default: .log ) @Produces(MediaType.APPLICATION_JSON) Using @Context annotation to inject JAX-RS and Servlet information. public Response deleteBook( access-log.category @PathParam("isbn") String isbn) {} @GET
The log category to use if logging is being done via the standard public String getBase(@Context UriInfo uriInfo) {
log mechanism. (default: io.quarkus.http.access-log ) return uriInfo.getBaseUri(); @GET } access-log.rotate @Produces(MediaType.APPLICATION_JSON) @Path("search") If the log should be rotated daily. (default: true ) public Response searchBook( @QueryParam("description") String description) {} Possible injectable objects: SecurityContext , Request , Application , same-site-cookie.
JAX-RS Get URI matrix parameter. (example: @Context /book;author=mkyong;country=malaysia ) Quarkus uses JAX-RS to de ne REST-ful web APIs. Under the HttpServletRequest request; covers, Rest-EASY is working with Vert.X directly without using any @CookieParam Servlet. @Override Gets cookie param by name. public void filter(ContainerRequestContext context) { It is important to know that if you want to use any feature that final String method = context.getMethod(); implies a Servlet (ie Servlet Filters) then you need to add the @HeaderParam final String path = info.getPath(); quarkus-undertow extension to switch back to the Servlet Gets header parameter by name. final String address = request.getRemoteAddr(); ecosystem but generally speaking, you don’t need to add it as System.out.println("Request %s %s from IP %s", method, path, address); everything else is well-supported. Valid HTTP method annotations provided by the spec are: @GET , } @POST , @PUT , @DELETE , @PATCH , @HEAD and @OPTIONS .
You can create new annotations that bind to HTTP methods not } de ned by the spec.
Exception Mapper
You can map exceptions to produce a custom output by implementing ExceptionMapper interface: @Provider import io.quarkus.vertx.http.runtime.filters.Filters; @ApplicationScoped public class ErrorMapper import io.vertx.ext.web.Router; public class MyDeclarativeRoutes { implements ExceptionMapper
@Produces(MediaType.APPLICATION_JSON) } @org.jboss.resteasy.annotations.cache.NoCache public User me() {} Declarative
@Produces(MediaType.APPLICATION_JSON) You can use @Route annotation to use reactive routes and GraphQL @org.jboss.resteasy.annotations.cache.Cache( @RouteFilter to sue reactive lters in a declarative way: maxAge = 2000, Quarkus integrates with GraphQL using MicroPro le GraphQL noStore = false ./mvnw quarkus:add-extension integration. ) -Dextensions="quarkus-vertx-web" public User you() {} ./mvnw quarkus:add-extension -Dextensions="graphql" Vert.X Filters and Routes
Programmatically @GraphQLApi public class FilmResource { You can also register Vert.X Filters and Router programmatically inside a CDI bean: @Query("allFilms") public List
@Query public String getFilm(@Name("filmId") int id)) {}
@Query public List
@Mutation public Greetings load(Greetings greetings) { }
} If name not provided, then query name is resolved from method extendig io.smallrye.mutiny.vertx.core.AbstractVerticle . ssl.key name. The le path to the corresponding certi cate private key le in GZip Support PEM format. You can see the full schema at /graphql/schema.graphql . Also GraphiQL UI is enabled at dev and test mode at /graphql-ui/ . You can con gure Quarkus to use GZip in the ssl.key-store Extension can be con gured with the follwoing paramters pre xed application.properties le using the next properties with An optional key store which holds the certi cate information with quarkus.smallrye-graphql . quarkus.resteasy su x: instead of specifying separate les.
gzip.enabled root-path ssl.key-store-type The rootPath under which queries will be served. (default: EnableGZip. (default: false ) An optional parameter to specify the type of the key store le. /graphql ) gzip.max-input ssl.key-store-password root-path-ui Con gure the upper limit on de ated request body. (default: 10M ) A parameter to specify the password of the key store le. The path where GraphQL UI is available. (default: /graphql-ui ) (default: password ) GRPC always-include-ui ssl.trust-store The path where GraphQL UI is available. (default: /graphql-ui ) Quarkus integrates with gRPC: Trust store which holds the certi cate information of the certi cates to trust root-path-ui ./mvnw quarkus:add-extension Always include the UI. By default this will only be included in dev -Dextensions="quarkus-grpc" ssl.trust-store-type and test. (default: false ) Parameter to specify type of the trust store le.
enable-ui Then you need to con gure build tool with gRPC plugins. In the ssl.trust-store-password If GraphQL UI should be enabled. (default: false ) case of Maven, the kr.motd.maven:os-maven-plugin extension and A parameter to specify the password of the trust store le. org.xolstice.maven.plugins:protobuf-maven-plugin
metrics.enabled ssl.cipher-suites Protos les are stored at src/main/proto . Enable metrics. (default: false ) A list of the cipher suites to use. When java les are created two service implementations are Vert.X Verticle provided: one with default gRPC API and other with Mutiny support. ssl.protocols The list of protocols to explicitly enable. (default: With quarkus.grpc.server pre x, the next con guration properties Vert.X Verticles are also supported: TLSv1.3,TLSv1.2 ) can be set:
transport-security.certificate @ApplicationScoped port public class VerticleDeployer { The path to the certi cate le. The gRPC Server port. (default: 9000 )
@Inject transport-security.key host Vertx vertx; The path to the private key le. The gRPC server host. (default: 0.0.0.0 ) public void init(@Observes StartupEvent ev) { To consume the service: CountDownLatch latch = new CountDownLatch(1); handshake-timeout vertx.deployVerticle(BareVerticle::new, The gRPC handshake timeout. new DeploymentOptions() @GrpcService("hello") GreeterGrpc.GreeterBlockingStub client; .setConfig( max-inbound-message-size new JsonObject() The max inbound message size in bytes. .put("id", "bare") @GrpcService("hello") ) io.grpc.Channel channel; plain-text ) .thenAccept(x -> latch.countDown()); Use plain text. (default: true ) Some con guration example to set the host and the SSL latch.countDown(); alpn parameters: } TWhether ALPN should be used. (default: true ) } quarkus.grpc.clients.hello.host=localhost enable-reflection-service quarkus.grpc.clients.hello.plain-text=false Enables the gRPC Re ection Service. (default: false ) quarkus.grpc.clients.hello.ssl.certificate=src/main/resourc Verticles can be: es/tls/client.pem ssl.certificate quarkus.grpc.clients.hello.ssl.key=src/main/resources/tls/c bare The le path to a server certi cate or certi cate chain in PEM lient.key extending io.vertx.core.AbstractVerticle . format. quarkus.grpc.clients.hello.ssl.trust-store=src/main/resourc es/tls/ca.pem mutiny If 3 (4 x 0.75) failures occur among the rolling window of 4 Fault Tolerance org.acme.quickstart.WorldClock/getNow/Retry/enabled=false consecutive invocations then the circuit is opened for 1000 ms and # Disable everything except fallback then be back to half open. If the invocation succeeds then the Quarkus uses MicroPro le Fault Tolerance spec: MP_Fault_Tolerance_NonFallback_Enabled=false circuit is back to closed again.
./mvnw quarkus:add-extension You can use bulkahead pattern to limit the number of concurrent -Dextensions="io.quarkus:quarkus-smallrye-fault-toleranc access to the same resource. If the operation is synchronous it MicroPro le Fault Tolerance integrates with MicroPro le e" uses a semaphore approach, if it is asynchronous a thread-pool Metrics spec. You can disable it by setting one. When a request cannot be processed BulkheadException is MP_Fault_Tolerance_Metrics_Enabled to false. thrown. It can be used together with any other fault tolerance MicroPro le Fault Tolerance spec uses CDI interceptor and it can annotation. Observability be used in several elements such as CDI bean, JAX-RS resource or MicroPro le Rest Client. @Bulkhead(5) Health Checks @Retry(maxRetries = 4, To do automatic retries on a method: delay = 1000, Quarkus relies on MicroPro le Health spec to provide health retryOn = BulkheadException.class) checks. @Path("/api") WorldClock getNow(){} @RegisterRestClient ./mvnw quarkus:add-extension public interface WorldClockService { -Dextensions="io.quarkus:quarkus-smallrye-health" @GET @Path("/json/cet/now") Fault tolerance annotations: @Produces(MediaType.APPLICATION_JSON) @Retry(maxRetries = 2) Annotation Properties WorldClock getNow(); By just adding this extension, an endpoint is registered to /q/health } providing a default health check. @Timeout unit
{ "status": "UP", You can set fallback code in case of an error by using @Fallback maxRetries , delay , delayUnit , annotation: maxDuration , durationUnit , "checks": [ @Retry jitter , jitterDelayUnit , retryOn , ] abortOn } @Retry(maxRetries = 1) @Fallback(fallbackMethod = "fallbackMethod") WorldClock getNow(){} @Fallback fallbackMethod To create a custom health check you need to implement the public WorldClock fallbackMethod() { HealthCheck interface and annotate either with @Readiness (ready to return new WorldClock(); process requests) or @Liveness (is running) annotations. waitingTaskQueue (only valid in @Bulkhead } asynchronous) @Readiness public class DatabaseHealthCheck implements HealthCheck { @Override fallbackMethod must have the same parameters and return type as failOn , delay , delayUnit , public HealthCheckResponse call() { the annotated method. @CircuitBreaker requestVolumeThreshold , HealthCheckResponseBuilder responseBuilder = failureRatio , successThreshold You can also set logic into a class that implements FallbackHandler HealthCheckResponse.named("Database conn"); interface: @Asynchronous try { checkDatabaseConnection(); public class RecoverFallback responseBuilder.withData("connection", true); implements FallbackHandler
In case you want to use circuit breaker pattern: You can also enable/disable policies using special parameter Builds the next output: @CircuitBreaker(requestVolumeThreshold = 4, enabled . failureRatio=0.75, delay = 1000) WorldClock getNow(){} Health groups are supported to provide custom health checks { quarkus.smallrye-health.root-path=/hello groups: "status": "UP", quarkus.smallrye-health.liveness-path=/customlive "checks": [ quarkus.smallrye-health.readiness-path=/customready { @io.smallrye.health.HealthGroup("mygroup1") "name": "Database conn", public class SimpleHealthGroupCheck implements HealthCheck { "status": "UP", Automatic readiness probes "data": { } "connection": true Some default readiness probes are provided by default if any of the } next features are added: } You can ping grouped health checks by querying /group/mygroup1 . ] datasource } A probe to check database connection status. Group root path can be con gured:
kafka quarkus.smallrye-health.group-path=/customgroup Since health checks are CDI beans, you can do: A probe to check kafka connection status. In this case you need to enable manually by setting quarkus.kafka.health.enabled to @ApplicationScoped true . Metrics public class DatabaseHealthCheck { mongoDB Quarkus can utilize the MicroPro le Metrics spec to provide metrics @Liveness A probe to check MongoDB connection status. support. HealthCheck check1() { return io.smallrye.health.HealthStatus neo4j ./mvnw quarkus:add-extension .up("successful-live"); -Dextensions="io.quarkus:quarkus-smallrye-metrics" } A probe to check Neo4J connection status.
@Readiness artemis HealthCheck check2() { A probe to check Artemis JMS connection status. The metrics can be read with JSON or the OpenMetrics format. An return HealthStatus endpoint is registered automatically at /q/metrics providing default metrics. .state("successful-read", this::isReady) kafka-streams } Liveness (for stream state) and Readiness (topics created) MicroPro le Metrics annotations: probes. private boolean isReady() {} @Timed } vault Tracks the duration. A probe to check Vault conection status. @SimplyTimed You can ping liveness or readiness health checks individually by gRPC Tracks the duration without mean and distribution calculations. querying /q/health/live or /q/health/ready . A readiness probe for the gRPC services. Quarkus comes with some HealthCheck implementations for @Metered checking service status. Cassandra Tracks the frequency of invocations. A readiness probe to check Cassandra connection status. SocketHealthCheck: checks if host is reachable using a @Counted socket. Redis Counts number of invocations. UrlHealthCheck: checks if host is reachable using a Http URL A readiness probe to check Redis connection status. connection. @Gauge You can disable the automatic generation by setting Samples the value of the annotated object. InetAddressHealthCheck: checks if host is reachable using
If you want to override or set manually readiness/liveness probes, quarkus.vault.health.enabled=true you can do it by setting health properties: quarkus.vault.health.stand-by-ok=true quarkus.vault.health.performance-stand-by-ok=true export.prometheus.path @GET @Stereotype //... @Retention(RetentionPolicy.RUNTIME) The path for the prometheus metrics endpoint (produces @Timed(name = "checksTimer", @Target({ ElementType.TYPE, ElementType.METHOD, ElementTyp text/plain). (default: /q/metrics ) description = "A measure of how long it takes e.FIELD }) to perform a hello.", @Timed(name = "checksTimer", export.azuremonitor.enabled unit = MetricUnits.MILLISECONDS) description = "A measure of how long it takes Support for export to Azure Monitor. public String hello() {} to perform a hello.", unit = MetricUnits.MILLISECONDS) export.azuremonitor.instrumentation-key @Counted(name = "countWelcome", public @interface TimedMilliseconds { The path for the azure monitor instrumentationKey. description = "How many welcome have been performed.") } public String hello() {} export.statsd.enabled Support for export to StatsD. There is a tight integration with Micrometer in the form of an @Gauge annotation returning a measure as a gauge. extension: export.stackdriver.enabled Micrometer metrics support. (default: true ) @Gauge(name = "hottestSauce", unit = MetricUnits.NONE, ./mvnw quarkus:add-extension description = "Hottest Sauce so far.") -Dextensions="micrometer" export.signalfx.enabled public Long hottestSauce() {} Micrometer metrics support. (default: true ) Add a micrometer dependency for the registry of your choosing: export.signalfx.uri Injecting a histogram using @Metric . Signalfx URI.
binder.vertx.match-patterns
You can con gure Metrics: You can con gure Micrometer. Pre x is quarkus.micrometer : Comma-separated case-sensitive list of regular expressions de ning Paths that should be matched and used as tags enabled quarkus.smallrye-metrics.path=/mymetrics Micrometer metrics support. (default: true ) binder.vertx.ignore-patterns Comma-separated case-sensitive list of regular expressions registry-enabled-default de ning Paths that should be ignored / not measured. Pre x is quarkus.smallrye-metrics . Micrometer MeterRegistry discovery. (default: true ) export.datadog path Datadog MeterRegistry con guration in Map
export.jmx.enabled ./mvnw quarkus:add-extension Support for export to JMX Support for JMX. -Dextensions="io.quarkus:quarkus-smallrye-opentracing"
export.prometheus.enabled Support for export to Prometheus. Requests sent to any endpoint are traced automatically. This extension includes OpenTracing support and Jaeger tracer. Kafka Tracer Native Executable Jaeger tracer con guration: Adds a span for each message sent to or received from a Kafka You can build a native image by using GraalVM. The common use topic. case is creating a Docker image so you can execute the next quarkus.jaeger.service-name=myservice commands: quarkus.jaeger.sampler-type=const
docker build -f src/main/docker/Dockerfile.native -t quarkus/getting-started . @Traced annotation can be set to disable tracing at class or method And con gure it: docker run -i --rm -p 8080:8080 quarkus/getting-started level. ... Tracer class can be injected into the class. mp.messaging.outgoing.generated-price.topic=prices You can use quarkus.native.container-runtime to select the container runtime to use. Now docker (default) and podman are the @Inject # For Produces valid options. Tracer tracer; mp.messaging.outgoing.generated-price.interceptor.classes=i o.opentracing.contrib.kafka.TracingProducerInterceptor ./mvnw package -Pnative -Dquarkus.native.container-runtime= tracer.activeSpan().setBaggageItem("key", "value"); ... podman # For consumers mp.messaging.incoming.prices.interceptor.classes=io.opentra You can disable Jaeger extension by using quarkus.jaeger.enabled cing.contrib.kafka.TracingConsumerInterceptor property. To con gure native application, you can create a config directory at the same place as the native le and place an application.properties le inside. config/application.properties . You can log the traceId , spanId and sampled in normal log: AWS XRay SSL quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{tra If you are building native images, and want to use AWS X-Ray ceId}, Tracing with your lambda you will need to include quarkus-amazon- To create a native image with SSL you need to copy SunEC library spanId=%X{spanId}, sampled lambda-xray as a dependency in your pom. and certi cates: =%X{sampled} [%c{2.}] (%t) %s%e%n Java 8:
Additional tracers FROM quay.io/quarkus/ubi-quarkus-native-image:{graalvm-vers ion}-java8 as nativebuilder JDBC Tracer RUN mkdir -p /tmp/ssl-libs/lib \ && cp /opt/graalvm/jre/lib/security/cacerts /tmp/ssl-libs Adds a span for each JDBC queries. \ && cp /opt/graalvm/jre/lib/amd64/libsunec.so /tmp/ssl-lib
OpenTelemetry
Quarkus integrates with the OpenTelemetry project. For exporting traces to a Jaeger collector, use the quarkus-opentelemetry- exporter-jaeger extension If all character sets should be added to the native image. full-stack-traces FROM quay.io/quarkus/ubi-quarkus-native-image:{graalvm-vers ion}-java11 as nativebuilder If full stack traces are enabled in the resulting image. RUN mkdir -p /tmp/ssl-libs/lib \ graalvm-home && cp /opt/graalvm/lib/security/cacerts /tmp/ssl-libs \ The location of the Graal distribution. enable-reports && cp /opt/graalvm/lib/libsunec.so /tmp/ssl-libs/lib/ If the reports on call paths and included java-home packages/classes/methods should be generated. FROM registry.access.redhat.com/ubi8/ubi-minimal The location of the JDK. WORKDIR /work/ report-exception-stack-traces COPY --from=nativebuilder /tmp/ssl-libs/ /work/ native-image-xmx If exceptions should be reported with a full stack trace. COPY target/*-runner /work/application The maximum Java heap to be used during the native image RUN chmod 775 /work /work/application generation. report-errors-at-runtime EXPOSE 8080 CMD ["./application", "-Dquarkus.http.host=0.0.0.0", "-Djav If errors should be reported at runtime. a.library.path=/work/lib", "-Djavax.net.ssl.trustStore=/wor debug-build-process k/cacerts"] If the native image build should wait for a debugger to be enable-dashboard-dump attached before running. Generate the report les for GraalVM Dashboard.
Inclusion of resources publish-debug-build-process-port resources.includes If the debug port should be published when building with docker A comma separated list of globs to match resource paths that By default, no resources are included in native executable. and debug-build-process. (default: true ) should be added to the native image. quarkus.native.resources.includes allows to set glob expressions to src/main/resources include resources based on path. cleanup-server resources.excludes If the native image server should be restarted. Given src/main/resources/foo/selected.png : A comma separated list of globs to match resource paths that should exclude to the native image. enable-isolates quarkus.native.resources.includes=foo/** If isolates should be enabled. (default: true ) debug.enabled If debug is enabled and debug symbols are generated. enable-fallback-images Exclusion of resources If a JVM based 'fallback image' should be created if native image Container Images Creation By default, no resources are excluded. fails. You can levarage to Quarkus to generation and release of Docker enable-server quarkus.native.resources.excludes = foo/** containers. It provides several extensions to make it so. If the native image server should be used. mvn clean package auto-service-loader-registration -Dquarkus.container-image.build=true Native con guration properties pre xed with quarkus.native : If all META-INF/services entries should be automatically -Dquarkus.container-image.push=true additional-build-args registered. -Dquarkus.container-image.registry=quay.io Additional arguments to pass to the build process. dump-proxies
enable-http-url-handler If the bytecode of all proxies should be dumped for inspection. Pre x is quarkus.container-image : If the HTTP url handler should be enabled. (default: true ) container-build group The group/repository of the image. (default: the ${user.name} ) enable-https-url-handler If this build should be done using a container runtime. If the HTTPS url handler should be enabled. remote-container-build name The name of the image. (default: the application name) enable-all-security-services If this build is done using a remote docker daemon. If all security services should be added to the native image. builder-image tag The tag of the image. (default: the application version) user-language The docker image to use to do the image build. De nes the user language used for building the native additional-tags executable. container-runtime The container runtime that is used to do an image based build. Additional tags of the container image. user-country ( docker , podman ) registry De nes the user country used for building the native executable. container-runtime-options The registry to use for pushing. (default: docker.io )
file-encoding Options to pass to the container runtime. username De nes the le encoding. enable-vm-inspection The registry username. If the resulting image should allow VM introspection password ports Running ./mvnw package the Kubernetes resources are created at The registry password. The ports to expose. target/kubernetes/ directory. insecure user Container Images Creation integrates with Kubernetes extension, so no need of extra Kubernetes properties. Flag to allow insecure registries. (default: false ) The user to use in generated image. Generated resource is integrated with MicroPro le Health build always-cache-base-image annotations. Boolean to set if image should be built. (default: false ) Controls the optimization which skips downloading base image layers that exist in a target registry (default: false ). Also, you can customize the generated resource by setting the new push values in application.properties : Boolean to set if image should be pushed. (default: false ) appcds-builder-image When AppCDS generation is enabled, if this property is set, then quarkus.kubernetes.namespace=mynamespace Jib the JVM used to generate the AppCDS le will be the JVM present in the container image. quarkus.kubernetes.replicas=3
./mvnw quarkus:add-extensions quarkus.kubernetes.labels.foo=bar -Dextensions="quarkus-container-image-jib" platforms
List of target platforms. (ie linux/amd64 ). quarkus.kubernetes.readiness-probe.period-seconds=45
Docker Quarkus copies any le under src/main/jib into the built container quarkus.kubernetes.mounts.github-token.path=/deployment/git image. hub ./mvnw quarkus:add-extensions quarkus.kubernetes.mounts.github-token.read-only=true Pre x is quarkus.container-image-jib : -Dextensions="quarkus-container-image-docker" quarkus.kubernetes.secret-volumes.github-token.volume-name= base-jvm-image github-token The base image to use for the jib build. (default: fabric8/java- Pre x is quarkus.container-image-s2i : quarkus.kubernetes.secret-volumes.github-token.secret-name= alpine-openjdk8-jre ) greeting-security dockerfile-jvm-path quarkus.kubernetes.secret-volumes.github-token.default-mode base-native-image Path to the JVM Docker le. (default: =420
The base image to use for the native build. (default: ${project.root}/src/main/docker/Dockerfile.jvm ) registry.access.redhat.com/ubi8/ubi-minimal ) quarkus.kubernetes.config-map-volumes.github-token.config-m ap-name=my-secret dockerfile-native-path jvm-arguments Path to the native Docker le. (default: quarkus.kubernetes.expose=true The arguments to pass to java. (default: - ${project.root}/src/main/docker/Dockerfile.native ) quarkus.kubernetes.ingress.expose=true Dquarkus.http.host=0.0.0.0,- quarkus.kubernetes.ingress.host=example.com Djava.util.logging.manager=org.jboss.logmanager.LogManager ) S2I quarkus.kubernetes.env.vars.my-env-var=foobar native-arguments ./mvnw quarkus:add-extensions quarkus.kubernetes.env.configmaps=my-config-map,another-con The arguments to pass to the native application. (default: - -Dextensions="quarkus-container-image-s2i" fig-map Dquarkus.http.host=0.0.0.0 ) quarkus.kubernetes.env.secrets=my-secret,my-other-secret environment-variables quarkus.kubernetes.resources.requests.memory=64Mi Pre x is quarkus.container-image-docker : Map of environment variables. quarkus.kubernetes.resources.requests.cpu=250m base-jvm-image quarkus.kubernetes.resources.limits.memory=512Mi quarkus.kubernetes.resources.limits.cpu=1000m jvm-entrypoint The base image to use for the s2i build. (default: fabric8/java- A custom entry point of the container image in JVM mode. alpine-openjdk8-jre ) native-entrypoint base-native-image All possible values are explained at https://quarkus.io/guides/kubernetes#con guration-options. A custom entry point of the container image in native mode. The base image to use for the native build. (default: registry.access.redhat.com/ubi8/ubi-minimal ) Labels and Annotations labels Custom labels to add to the generated image. Kubernetes The generated manifest use the Kubernetes recommended labels and annotations. base-registry-username Quarkus can use Dekorate to generate Kubernetes resources. The username to use to authenticate with the registry used to pull the base JVM image. ./mvnw quarkus:add-extensions -Dextensions="quarkus-kubernetes" base-registry-password The password to use to authenticate with the registry used to pull openshift Datasource con guration part is absent as it is aut-discovered by "labels" : { Quarkus. "app.kubernetes.io/part-of" : "todo-app", https://quarkus.io/guides/kubernetes#openshift "app.kubernetes.io/name" : "todo-rest", "app.kubernetes.io/version" : "1.0-rc.1" Knative Minikube } https://quarkus.io/guides/kubernetes#knative Quarkus has a Minikube extension which creates Kubernetes "annotations": { Using Existing Resources manifests that are tailored for Minikube. "app.quarkus.io/vcs-url" : "
Resources are added in src/main/kubernetes directory with the You can override the labels by using the next properties: target name ( kubernetes.json , openshift.json , knative.json , or the Remember to execute eval $(minikube -p minikube docker- yml equivalents) with one orm ore Kubernetes resources. Any env) to build images directly inside Minkube cluster. quarkus.kubernetes.part-of=todo-app resource found will be added in the generated manifests. If one of quarkus.kubernetes.name=todo-rest the provided resources has the same name as one of the generated OpenShift quarkus.kubernetes.version=1.0-rc.1 ones, then the generated resource will be created on top of the provided resource, respecting existing content. Instead of adding Kubernetes extension, set container image s2i and the target to openshift for working with OpenShift, an Or add new labels and/or annotations: To override the name of the generated resource you can use: extension grouping all of the is created: quarkus.kubernetes.name , quarkus.openshift.name and quarkus.knative.name . quarkus.kubernetes.labels.foo=bar ./mvnw quarkus:add-extension quarkus.kubernetes.annotations.foo=bar Deployment -Dextensions="openshift"
To deploy automatically the generated resources, you need to set metrics quarkus.container.deploy ag to true . Kubernetes Con guration Extension When using metrics extension, Prometheus annotations are mvn clean package -Dquarkus.kubernetes.deploy=true Integration between MicroPro le Con g spec and Con gMaps & generated: Secrets:
prometheus.io/scrape: "true" If you set this ag to true , the build and push ags from ./mvnw quarkus:add-extensions prometheus.io/path: /metrics container-image are set to true too. -Dextensions="quarkus-kubernetes-config" prometheus.io/port: "8080" To deploy the application, the extension uses the https://github.com/fabric8io/kubernetes-client. All options Kubernetes Deployment Targets described at Kubernetes Client are valid here. quarkus.kubernetes-config.enabled=true quarkus.kubernetes-config.config-maps=cmap1,cmap2 You can generate different resources setting the property Kubernetes Service Binding quarkus.kubernetes.deployment-target . Quarkus supports binding services to applications via the Service Possible values are kubernetes , openshift and knative . The default Binding Speci cation for Kubernetes. @ConfigProperty(name = "some.prop1") value is kubernetes . String someProp1; The following Quarkus extensions support this feature: Knative Properties @ConfigProperty(name = "some.prop2") quarkus-jdbc-mariadb String someProp2; Most of the Kubernetes properties are valid in Knative output by just changing the kubernetes pre x to knative pre x (ie quarkus-jdbc-mssql quarkus.kubernetes.readiness-probe.period-seconds to quarkus.knative.readiness-probe.period-seconds ). quarkus-jdbc-mysql If the con g key is a Quarkus con guration le application.properties / application.yaml , the content is parsed and There are also speci c properties for Knative: quarkus-jdbc-postgresql each key of the con guration le is used as con g property.
quarkus-kafka-client List of Kubernetes Con g parameters. quarkus.kubernetes.deployment-target=knative quarkus.knative.revision-name=my-revision quarkus-smallrye-reactive-messaging-kafka quarkus.kubernetes-config as pre x is skipped in the next table. quarkus.knative.traffic.my-revision.percentage=80
./mvnw quarkus:add-extensions enabled -Dextensions="quarkus-kubernetes-service-binding" The application will attempt to look up the con guration from the List of con guration options: API server. (default: false ) kubernetes fail-on-missing-config https://quarkus io/guides/kubernetes#con guration options The application will not start if any of the con gured con g watch-reconnect-interval @Inject sources cannot be located. (default: true ) Watch reconnect interval. (default: PT1S ) KubernetesClient client; config-maps watch-reconnect-limit ServiceList myServices = client.services().list(); Con gMaps to look for in the namespace that the Kubernetes Maximum reconnect attempts. (default: -1 ) Client has been con gured for. Supports CSV. Service myservice = client.services() connection-timeout .inNamespace("default") namespace .withName("myservice") Maximum amount of time to wait for a connection. (default: .get(); Access to Con gMaps from a speci c namespace. PT10S )
CustomResourceDefinitionList crds = client secrets.enabled request-timeout .customResourceDefinitions() Whether or not con guration can be read from secrets. (default: Maximum amount of time to wait for a request. (default: PT10S ) .list(); false )
rolling-timeout dummyCRD = new CustomResourceDefinitionBuilder() Kubernetes Client Maximum amount of time to wait for a rollout. (default: PT15M ) ... .build() Quarkus integrates with Fabric8 Kubernetes Client. http-proxy client.customResourceDefinitions() .create(dummyCRD); HTTP proxy used to access the Kubernetes. ./mvnw quarkus:add-extension -Dextensions="quarkus-kubernetes-client" https-proxy Testing HTTPS proxy used to access the Kubernetes. Quarkus provides a Kubernetes Mock test resource that starts a List of Kubernetes client parameters. proxy-username mock of Kubernetes API server and sets the proper environment Proxy username. quarkus.kubernetes-client as pre x is skipped in the next table. variables needed by Kubernetes Client. trust-certs proxy-password Register next dependency: io.quarkus:quarkus-test-kubernetes- client:test . Trust self-signed certi cates. (default: false ) Proxy password.
@QuarkusTestResource(KubernetesMockServerTestResource.clas master-url no-proxy s) IP addresses or hosts to exclude from proxying URL of Kubernetes API server. @QuarkusTest public class KubernetesClientTest { Or programmatically: namesapce Default namespace. @MockServer @Dependent private KubernetesMockServer mockServer; ca-cert-file public class KubernetesClientProducer { CA certi cate data. @Test @Produces public void test() { public KubernetesClient kubernetesClient() { final Pod pod1 = ... client-cert-file Config config = new ConfigBuilder() mockServer Client certi cate le. .withMasterUrl("https://mymaster.com") .expect() .build(); .get() client-cert-data return new DefaultKubernetesClient(config); .withPath("/api/v1/namespaces/test/pods") Client certi cate data. } .andReturn(200, } new PodListBuilder() client-key-data .withNewMetadata() Client key data. .withResourceVersion("1") And inject it on code: .endMetadata() .withItems(pod1, pod2) client-key-algorithm .build()) Client key algorithm. .always(); } client-key-passphrase } Client key passphrase. username AWS Lambda Username. Quarkus integrates with Amazon Lambda. password Password The Cloud Event type that triggers the function is defaultChain . It ./mvnw quarkus:add-extension mvn archetype:generate \ generates a response that triggers a new Cloud Event whose type is -Dextensions="io.quarkus:quarkus-amazon-lambda" -DarchetypeGroupId=io.quarkus \ defaultChain.output and the event source is defaultChain . -DarchetypeArtifactId=quarkus-azure-functions-http-archet ype \ It can be changed by using the next properties: And then implement -DarchetypeVersion={version} com.amazonaws.services.lambda.runtime.RequestHandler interface. quarkus.funqy.knative-events.mapping.defaultChain.trigger=c onfigChain.output public class TestLambda Funqy quarkus.funqy.knative-events.mapping.defaultChain.response- implements RequestHandler
The interface @Inject Also can be overriden with com.amazonaws.services.lambda.runtime.RequestStreamHandler is also GreetingService service; @io.quarkus.funqy.knative.events.CloudEventMapping annotation. supported. @io.quarkus.funqy.Funq @Funq The interface com.amazon.ask.SkillStreamHandler is also supported. public String greet(String name) {} @CloudEventMapping(trigger = "annotated", responseSource = "annotated", responseType = "lastChainLink") You can set the handler name by using quarkus.lambda.handler @io.quarkus.funqy.Funq("HelloCustomer") public String annotatedChain(String input) {} property or by annotating the Lambda with the CDI @Named public String greet(Customer name) {} annotation. @Funq Test responseType chains annotatedChain response to lastChainLink public Greeting greet(Friend friend, function. You can write tests for Amazon lambdas: @io.quarkus.funqy.Context AwsContext ctx) {} } @Funq
Quarkus can make a microservice be deployable to the Azure Functions. @Funq To scaffold a deployable microservice to the Azure Functions run: public String defaultChain(String input) {} Possible Swagger UI options with quarkus.swagger-ui pre x: curl -v "http://default-broker.knativetutorial.svc.cluster. Apache Camel local" \ urls -X POST \ Apache Camel Quarkus has its own site: -H "Ce-Id: 1234" \ https://github.com/apache/camel-quarkus The urls that will be included as options. (ie quarkus.swagger- -H "Ce-Specversion: 1.0" \ ui.urls.petstore=https://petstore.swagger.io/v2/swagger.json ) -H "Ce-Type: defaultChain" \ WebSockets -H "Ce-Source: curl" \ urls-primary-name -H "Content-Type: application/json" \ Quarkus can be used to handling web sockets. If urls option is used, this will be the name of the default -d '"Start"' selection.
./mvnw quarkus:add-extension title -Dextensions="quarkus-websockets" The html title for the page.
And web sockets classes can be used: theme Swagger UI theme to be used.
@ServerEndpoint("/chat/{username}") footer @ApplicationScoped public class ChatSocket { A footer for the html page. Nothing by default.
@OnOpen deep-linking public void onOpen(Session session, Enables deep linking for tags and operations. @PathParam("username") String username) {} display-operation-id @OnClose Controls the display of operationId in operations list. public void onClose(..) {}
default-models-expand-depth @OnError public void onError(..., Throwable throwable) {} The default expansion depth for models.
@OnMessage default-model-expand-depth public void onMessage(...) {} The default expansion depth for the model on the model-example section. } default-model-rendering Controls how the model is shown when the API is rst rendered. OpenAPI display-request-duration Quarkus can expose its API description as OpenAPI spec and test it Controls the display of the request duration (in milliseconds) for using Swagger UI. "Try it out" requests.
./mvnw quarkus:add-extension doc-expansion -Dextensions="io.quarkus:quarkus-smallrye-openapi" Controls the default expansion setting for the operations and tags.
Then you only need to access to /openapi to get OpenAPI v3 spec filter of services. Enables ltering.
quarkus.smallrye- You can update the OpenApi path by setting max-displayed-tags openapi.path property. Limits the number of tagged operations displayed to at most this Also, in case of starting Quarkus application in dev or test mode, many. Swagger UI is accessible at /swagger-ui . If you want to use it in production mode you need to set quarkus.swagger-ui.always- operations-sorter include property to true . Apply a sort to the operation list of each API. ( alpha , method , function ) You can update the Swagger UI path by setting quarkus.swagger- ui.path property. show-extensions Controls the display of vendor extension. quarkus.swagger-ui.path=/my-custom-path
show-common-extensions Controls the display of extensions. presets Add a Security Scheme name to the generated OpenAPI A list of presets to use in Swagger UI. document. (default: SecurityScheme ) tag-sorter Apply a sort to the tag list of each API. You can customize the output by using Open API v3 annotations. security-scheme-description Add a description to the Security Scheme. (default: on-complete @Schema(name="Developers", Authentication ) Provides a mechanism to be noti ed when Swagger UI has description="POJO that represents a developer.") nished rendering a newly provided de nition. public class Developer { basic-security-scheme-value @Schema(required = true, example = "Alex") Add a scheme value to the Basic HTTP Security Scheme. syntax-highlight private String name; (default: basic ) Set to false to deactivate syntax highlighting of payloads and } cURL command. jwt-security-scheme-value @POST Add a scheme value to the JWT Security Scheme. (default: @Path("/developer") oauth2-redirect-url bearer ) @Operation(summary = "Create deeloper", OAuth redirect URL. description = "Only be done by admin.") jwt-bearer-format public Response createDeveloper( request-interceptor @RequestBody(description = "Developer object", Add a bearer format to the JWT Security Scheme. (default: JWT ) Function to intercept remote de nition, "Try it out", and OAuth 2.0 required = true, requests. content = @Content(schema = oidc-open-id-connect-url @Schema(implementation = Developer.class))) Add a openIdConnectUrl value to the OIDC Security Scheme request-curl-options Developer developer) Array of command line options available to the curl command. oauth2-implicit-refresh-url Add a implicit ow refreshUrl value to the OAuth2 Security response-interceptor All possible annotations can be seen at Scheme Function to intercept remote de nition, "Try it out", and OAuth 2.0 org.eclipse.micropro le.openapi.annotations package. responses. oauth2-implicit-authorization-url You can also serve OpenAPI Schema from static les instead of Add an implicit ow authorizationUrl value to the OAuth2 Security dynamically generated from annotation scanning. show-mutated-request Scheme
Uses the mutated request returned from a requestInterceptor to You need to put OpenAPIdocumentation under META-INF directory oauth2-implicit-token-url produce the curl command in the UI. (ie: META-INF/openapi.yaml ). Add an implicit ow tokenUrl value to the OAuth2 Security supported-submit-methods A request to /openapi will serve the combined OpenAPI document Scheme from the static le and the generated from annotations. You can List of HTTP methods that have the "Try it out" feature enabled. disable the scanning documents by adding the next con guration Mail Sender property: mp.openapi.scan.disable=true . validator-url You can send emails by using Quarkus Mailer extension: Swagger UI attempts to validate specs against swagger.io’s Other valid document paths are: META-INF/openapi.yml , META- online validator. INF/openapi.json , WEB-INF/classes/META-INF/openapi.yml , WEB- INF/classes/META-INF/openapi.yaml , WEB-INF/classes/META- ./mvnw quarkus:add-extension with-credentials INF/openapi.json . -Dextensions="io.quarkus:quarkus-mailer" Enables passing credentials, as de ned in the Fetch standard, in CORS requests that are sent by the browser. You can store generated OpenAPI schema if quarkus.swagger- ui.store-schema-directory is set. You can inject two possible classes io.quarkus.mailer.Mailer for model-property-macro synchronous API or io.quarkus.mailer.reactive.ReactiveMailer for Possible OpenAPI options with quarkus.smallrye-openapi pre x: Function to set default values to each property in model. asynchronous/reactive API. path parameter-macro The path at which to register the OpenAPI Servlet. (default: @Inject Function to set default value to parameters. openapi ) Mailer mailer; persist-authorization store-schema-directory It persists authorization data and it would not be lost on browser The generated OpenAPI schema documents will be stored here And then you can use them to send an email: close/refresh. on build. mailer.send( layout security-scheme Mail.withText("[email protected]", "Subject", "Body") The name of a component available via the plugin system to use Add a certain SecurityScheme with con g. ( basic , jwt , oidc , ); as the top-level layout for Swagger UI. oauth2Implicit ) plugins security-scheme-name Reactive Mail client A list of plugin functions to use in Swagger UI. @Inject Parameter Default Description @Inject ReactiveMailer reactiveMailer; MockMailbox mailbox; mailer.password The password. CompletionStage
Mail class contains methods to add cc , bcc , headers , bounce Hostname for You can schedule periodic tasks with Quarkus. address , reply to , attachments , inline attachments and html body . mailer.own-host-name HELO/EHLO and Message-ID @ApplicationScoped mailer.send(Mail.withHtml("[email protected]", "Subject", body) public class CounterBean { .addInlineAttachment("quarkus.png", Connection pool new File("quarkus.png"), mailer.keep-alive true enabled. @Scheduled(every="10s", delayed="1s") "image/png", "
mailer.disable-esmtp false Disable ESMTP. @Scheduled(cron="0 15 10 * * ?") If you need deep control you can inject Vert.x mail client void morningTask() {} @Inject MailClient client; } TLS security mode. You need to con gure SMTP properties to be able to send an email: mailer.start-tls OPTIONAL DISABLED , OPTIONAL , REQUIRED . every and cron parameters can be surrounded with {} and the [email protected] value is used as con g property to get the value. quarkus.mailer.host=smtp.sendgrid.net Login mode. NONE , quarkus.mailer.port=465 mailer.login NONE @Scheduled(cron = "{morning.check.cron.expr}") OPTIONAL , REQUIRED . quarkus.mailer.ssl=true void morningTask() {} quarkus.mailer.username=.... quarkus.mailer.password=.... mailer.auth-methods All methods. Space-separated list. And con gure the property into application.properties :
morning.check.cron.expr=0 15 10 * * ? List of Mailer parameters. quarkus. as a pre x is skipped in the next mailer.key-store Path of the key store. table.
Parameter Default Description mailer.key-store- Key store password. By default Quarkus expresion is used, but you can change that by password setting quarkus.scheduler.cron-type property. mailer.from Default address. if you enable SSL for the mailer and you want to build a native executable, you will need to enable the SSL support quarkus.scheduler.cron-type=unix Emails not sent, just quarkus.ssl.native=true . false in prod , true in mailer.mock printed and stored in dev and test . a MockMailbox . Testing org.quartz.Scheduler can be injected as any other bean and scehdule jobs programmatically. If quarkus.mailer.mock is set to true , which is the default value in dev and test mode, you can inject MockMailbox to get the sent mailer.bounce- @Inject Default address. messages. address org.quartz.Scheduler quartz;
quartz.scheduleJob(job, trigger); mailer.host mandatory SMTP host.
mailer.port 25 SMTP port. Kogito
Quarkus integrates with Kogito, a next-generation business mailer.username The username. automation toolkit from Drools and jBPM projects for adding business automation capabilities. To start using it you only need to add the next extension: try (Git git = Git.cloneRepository() import org.jboss.stm.annotations.ReadLock; .setDirectory(tmpDir) import org.jboss.stm.annotations.State; ./mvnw quarkus:add-extension .setURI(url) import org.jboss.stm.annotations.WriteLock; -Dextensions="kogito" .call()) { return tmpDir.toString(); public class FlightServiceImpl } implements FlightService { @State Apache Tika private int numberOfBookings;
Quarkus integrates with Apache Tika to detect and extract When running in native mode, make sure to con gure SSL @ReadLock metadata/text from different le types: access correctly quarkus.ssl.native=true (Native and SSL). public int getNumberOfBookings() { return numberOfBookings; ./mvnw quarkus:add-extension Web Resources } -Dextensions="quarkus-tika" You can serve web resources with Quarkus. You need to place web @WriteLock resources at src/main/resources/META-INF/resources and then they public void makeBooking(String details) { are accessible (ie http://localhost:8080/index.html) numberOfBookings += 1; @Inject } io.quarkus.tika.TikaParser parser; By default static resources as served under the root context. You } can change this by using quarkus.http.root-path property. @POST @Path("/text") Transactional Memory @Consumes({ "text/plain", "application/pdf", Any member is saved/restored automatically ( @State is not "application/vnd.oasis.opendocument.text" }) mandatory). You can use @NotState to avoid behaviour. Quarkus integrates with the Software Transactional Memory (STM) @Produces(MediaType.TEXT_PLAIN) implementation provided by the Narayana project. Transaction boundaries public String extractText(InputStream stream) { return parser.parse(stream).getText(); Declarative } ./mvnw quarkus:add-extension -Dextensions="narayana-stm" @NestedTopLevel : De nes that the container will create a new top-level transaction for each method invocation. You can con gure Apache Tika in application.properties le by @Nested : De nes that the container will create a new top-level using next properties pre xed with quarkus : Transactional objects must be interfaces and annotated with org.jboss.stm.annotations.Transactional . or nested transaction for each method invocation. Parameter Default Description Programmatically @Transactional Path to the Tika @NestedTopLevel tika.tika-config- AtomicAction aa = new AtomicAction(); tika-config.xml con guration public interface FlightService { path resource. int getNumberOfBookings(); aa.begin(); void makeBooking(String details); { } CSV of the try { abbreviated or full flightService.makeBooking("BA123 ..."); quarkus.tika.parsers parser class to be taxiService.makeBooking("East Coast Taxis ..."); The pessimistic strategy is the default one, you can change to loaded by the optimistic by using @Optimistic . extension. aa.commit(); } catch (Exception e) { Then you need to create the object inside org.jboss.stm.Container . aa.abort(); The document may } tika.append-embedded- have other embedded Container
./mvnw quarkus:add-extension ./mvnw quarkus:add-extension -Dextensions="quartz" -Dextensions="quarkus-jgit"
And then you can start using JGit: instance-name @ApplicationScoped public class TaskBean { The name of the Quartz instance. (default:
QuarkusQuartzScheduler ) @Transactionalforce-start To render the template: The scheduler will be started even if no scheduled business To con gure in clustered mode vida DataSource: methods are found. public class Item { quarkus.datasource.url=jdbc:postgresql://localhost/quarkus_ start-mode public String name; test public BigDecimal price; Scheduler can be started in different modes: normal , forced or quarkus.datasource.driver=org.postgresql.Driver } halted . (default: normal ) # ... @Inject quarkus.quartz.clustered=true Qute io.quarkus.qute.Template item; quarkus.quartz.store-type=db Qute is a templating engine designed speci cally to meet the @GET Quarkus needs. Templates should be placed by default at @Path("{id}") src/main/resources/templates aand subdirectories. @Produces(MediaType.TEXT_HTML) You need to de ne the datasource used by clustered mode public TemplateInstance get(@PathParam("id") Integer id) { and also import the database tables following the Quartz return item.data("item", service.findItem(id)); schema. ./mvnw quarkus:add-extension -Dextensions="quarkus-resteasy-qute" }
Quartz can be con gured usinf the following properties with @TemplateExtension quarkus.quartz pre x: static BigDecimal discountedPrice(Item item) { Templates can be de ned in any format, in case of HTML: return item.price.multiply(new BigDecimal("0.9")); clustered item.html } Enable cluster mode or not. {@org.acme.Item item} @TemplateExtension(namespace = "str") store-type public static class StringExtensions { The type of store to use. Possible values: ram , db (default: ram ) static String reverse(String val) {
return new StringBuilder(val).reverse().toString(); datasource } The name of the datasource to use.{item.name ?: 'Unknown'}
The pre x for quartz job store tables. (default: QRTZ_ ) If @ResourcePath is not used in Template then the name of the eld is{str:reverse('Hello')}
used as le name. In this case the le should be@io.quarkus.qute.i18n.MessageBundle void configureEngine(@Observes EngineBuilder builder) { public interface AppMessages { builder.addValueResolver(ValueResolver.builder() static BigDecimal discountedPrice(Item item, int scale) { @io.quarkus.qute.i18n.Message("Hello {name}!") .appliesTo(ctx -> ctx.getBase() instanceof Long && ct return item.price.multiply(scale); String hello_name(String name); x.getName().equals("tenTimes")) } } .resolveSync(ctx -> (Long) ctx.getBase() * 10) .build()); }
Qute for syntax supports any instance of Iterable , Map.EntrySet , There are 3 methods to inject the message: Stream or Integer . MessageBundles.get(AppMessages.class).hello_name("Lucie"); Content Filters {#for i in total} Content lters can be used to modify the template contents before {i}: parsing. {/for} or
void configureEngine(@Observes EngineBuilder builder) { @Inject AppMessages app; builder.addParserHook(new ParserHook() { The next map methods are supported: @Override app.hello_name("Lucie"); public void beforeParsing(ParserHelper parserHelper) {#for key in map.keySet} { {#for value in map.values} parserHelper.addContentFilter(contents -> content {map.size} or s.replace("${", "$\\{")); {#if map.isEmpty} } {map['foo'] });
{msg:hello_name('Lucie')}
}The next list methods are supported: Localization Reactive and Async {list[0]} There are two ways to set localized message: CompletionStage
The next number methods are supported: public interface GermanAppMessages { Uni
.completionStage(() -> report.r {#if counter.mod(5) == 0} @Override enderAsync()); @io.quarkus.qute.i18n.Message("Hallo {name}!") String hello_name(String name); } Switch/When Qute Mail Integration
{#switch person.name} or @Inject {#case 'John'} MailTemplate hello; Hey John! msg_de.properties {#case 'Mary'} CompletionStage
{#when items.size} {#is 1} (1) // file located at src/main/resources/templates/reports/v1/ INFO: Template located at src/main/resources/templates/hello. There is exactly one item! report_01.{} [html|txt] . {#is > 10} (2) @ResourcePath("reports/v1/report_01") There are more than 10 items! Template report; Sentry {#else} (3) String output = report There are 2 -10 items! Quarkus integrates with Sentry for logging errors into an error .data("samples", service.get()) {/when} monitoring system. .render();
./mvnw quarkus:add-extension Following operators can be used either in when and switch : not, ne, -Dextensions="quarkus-logging-sentry" != , gt, > , ge, >= , lt, < , le, <= , in , ni, !in . Value Resolvers And the con guration to send all errors occuring in the package quarkus.banner.enabled @ApplicationScoped org.example to Sentrty with DSN https://[email protected]/1234 : public class CachedBean { Enables banner. (default : true )
quarkus.log.sentry=true @CacheResult(cacheName = "foo") OptaPlanner quarkus.log.sentry.dsn=https://[email protected]/1234 public Object load(Object key) {} quarkus.log.sentry.level=ERROR Quarkus integrates with OptaPlanner. quarkus.log.sentry.in-app-packages=org.example @CacheInvalidate(cacheName = "foo") public void invalidate(Object key) {} ./mvnw quarkus:add-extension
-Dextensions="quarkus-optaplanner, quarkus-optaplanner-ja @CacheInvalidateAll(cacheName = "foo") Full list of con guration properties having quarkus.log as pre x: ckson" public void invalidateAll() {} sentry.enable } Enable the Sentry logging extension (default: false) @PlanningSolution sentry.dsn You can disable the caching system by setting public class TimeTable { Where to send events. quarkus.cache.enabled property to false . }
This extension uses Caffeine as its underlying caching provider. @Inject sentry.level private SolverManager
properties-value-keys ./mvnw quarkus:add-extension Keys whose value represents a properties-like le conttent. -Dextensions="webjars-locator" If using mutiny extension together you already get context propagation for ArC, RESTEasy and transactions. With fail-on-missing-key CompletionStage you need to: If the application will not start if any of the con gured con g Then the JavaScript location is changed from sources cannot be located. (default: true ) /webjars/jquery/3.1.1/jquery.min.js to @Inject ThreadContext threadContext; /webjars/jquery/jquery.min.js in your HTML les. @Inject ManagedExecutor managedExecutor; trust-store threadContext.withContextCapture(..) TrustStore to be used containing the SSL certi cate used by Amazon SES .thenApplyAsync(r -> {}, managedExecutor); Consul agent. mvn quarkus:add-extension trust-store-password -Dextensions="amazon-ses" If you are going to use security in a reactive environment you will Password of TrustStore to be used containing the SSL certi cate likely need Smallrye Content Propagation to propagate the identity used by Consul agent. throughout the reactive callback. key-password @Inject Con guration from HasiCorp Consul Password to recover key from KeyStore for SSL client software.amazon.awssdk.services.ses.SesClient sesClient; authentication with Consul agent. @Inject You can read runtime con guration from HashiCorp Consul. software.amazon.awssdk.services.ses.SesAsyncClient sesClien agent.host-port t; ./mvnw quarkus:add-extension Consul agent host. (default: localhost:8500 ) -Dextensions="consul-config" agent.use-https quarkus.ses.endpoint-override=http://localhost:8012 Use HTTPS when communicating with the agent. (default: false ) You need to con gure Consul: quarkus.ses.aws.region=us-east-1 quarkus.ses.aws.credentials.type=static agent.token quarkus.ses.aws.credentials.static-provider.access-key-id=t quarkus.consul-config.enabled=true Consul token to be provided when authentication is enabled. est-key quarkus.consul-config.agent.host-port=localhost:8500 quarkus.ses.aws.credentials.static-provider.secret-access-k quarkus.consul-config.properties-value-keys=config/consul-t agent.key-store ey=test-secret est KeyStore (classpath or lesystem) to be used containing the SSL certi cate used by Consul agent.
You need to set a HTTP client either URL Connection : agent.key-store-password @ConfigProperty(name = "greeting.message") Password of KeyStore. String message;
agent.connection-timeout "Key": "config/consul-test", "Value": "greeting.message=Hello from Consul" Connection timeout. (default: 10S ) or Apache HTTP:
agent.read-timeout
./mvnw quarkus:add-extension ./mvnw quarkus:add-extension Con guration properties are the same as Amazon DynamoDB but -Dextensions="quarkus-spring-di" -Dextensions="quarkus-spring-boot-properties" changing the pre x from dynamodb to ses .
Jbang Some examples of what you can do. Notice that annotations are @ConfigurationProperties("example") the Spring original ones. public final class ClassProperties { Creating an initial script:
@Configuration private String value; public class AppConfiguration { jbang scripting/quarkusapp.java private AnotherClass anotherClass;
@Bean(name = "capitalizeFunction") // getters/setters public StringFunction capitalizer() { } Adding Quarkus dependencies in script: return String::toUpperCase; } //DEPS io.quarkus:quarkus-resteasy:{quarkus-version} } example.value=class-value example.anotherClass.value=true Put some Quarkus CLI code: Or as a component:
@Component("noopFunction") @Path("/hello") public class NoOpSingleStringFunction Spring Cloud Con g Client @ApplicationScoped implements StringFunction { public class quarkusapp { } Quarkus integrates Spring Cloud Con g Client and MicroPro le @GET Con g spec. public String sayHello() { return "hello"; ./mvnw quarkus:add-extension } Also as a service and injection properties from -Dextensions="quarkus-spring-cloud-config-client" public static void main(String[] args) { application.properties . Quarkus.run(args); } @Service } public class MessageProducer { You need to con gure the extension:
@Value("${greeting.message}") quarkus.spring-cloud-config.uri=http://localhost:8089 To run the script: String message; quarkus.spring-cloud-config.username=user quarkus.spring-cloud-config.password=pass } quarkus.spring-cloud-config.enabled=true jbang quarkusapp.java
And you can inject using Autowired or constructor in a component A Maven goal is provided to scaffold a project: @ConfigProperty(name = "greeting.message") and in a JAX-RS resource too. String greeting; mvn io.quarkus:quarkus-maven-plugin:
private final MessageProducer messageProducer; uri
@Autowired @Qualifier("noopFunction") Base URI where the Spring Cloud Con g Server is available. StringFunction noopStringFunction; (default: localhost:8888 )
public GreeterBean(MessageProducer messageProducer) { username this.messageProducer = messageProducer; Username to be used if the Con g Server has BASIC Auth } enabled. } password Password to be used if the Con g Server has BASIC Auth enabled. enabled The next return types are supported: @Query("select m from Movie m where m.rating = ?1") org.springframework.http.ResponseEntity and java.util.Map . Enables read con guration from Spring Cloud Con g Server. Iterator
Methods of Spring Web public interface FruitRepository org.springframework.data.repository.query.QueryByExampleExec extends CrudRepository
org.springframework.data.repository.Repository Spring Data Rest @RestController @RequestMapping("/greeting") org.springframework.data.repository.CrudRepository While users are encouraged to use REST Data with Panache for the public class GreetingController { REST data access endpoints generation, Quarkus provides a org.springframework.data.repository.PagingAndSortingReposito compatibility layer for Spring Data REST in the form of the spring- private final GreetingBean greetingBean; ry data-rest extension.
public GreetingController(GreetingBean greetingBean) { org.springframework.data.jpa.repository.JpaRepository . ./mvnw quarkus:add-extension this.greetingBean = greetingBean; INFO: Generated repositories are automatically annotated with -Dextensions="spring-data-rest" } @Transactional .
@GetMapping("/{name}") Repository fragments is also supported: public Greeting hello(@PathVariable(name = "name") import java.util.Optional; String name) { import org.springframework.data.repository.CrudRepository; return new Greeting(greetingBean.greet(name)); public interface PersonRepository import org.springframework.data.rest.core.annotation.Reposi } extends JpaRepository
Supported annotations are: RestController , RequestMapping , @RepositoryRestResource(exported = false, path = "/my-fruit GetMapping , PostMapping , PutMapping , DeleteMapping , PatchMapping , s") RequestParam , RequestHeader , MatrixVariable , PathVariable , User de ned queries: public interface FruitsRepository extends CrudRepository
org.springframework.data.jpa.repository.JpaRepository @PreAuthorize("@personChecker.check(#person, authenticatio n.principal.username)") Spring Security public void doSomething(Person person){}
Quarkus provides a compatibility layer for Spring Security. @Component public class PersonChecker { ./mvnw quarkus:add-extension public boolean check(Person person, String username) { -Dextensions="spring-security" return person.getName().equals(username); } } You need to choose a security extension to de ne user, roles, … such as openid-connect , oauth2 , properties-file or security-jdbc as seen at RBAC. Combining expressions:
Then you can use Spring Security annotations to protect the @PreAuthorize("hasAnyRole('user', 'admin') AND #user == pri methods: ncipal.username") public void allowedForUser(String user) {} @Secured("admin") @GetMapping public String hello() { return "hello"; Spring Cache } Quarkus provides a compatibility layer for Spring dependency injection. Quarkus provides support for some of the most used features of Spring Security’s @PreAuthorize annotation. ./mvnw quarkus:add-extension -Dextensions="spring-cache" Some examples: hasRole @org.springframework.cache.annotation.Cacheable("someCache" @PreAuthorize("hasRole('admin')") ) public Greeting greet(String name) {} @PreAuthorize("hasRole(@roles.USER)") where roles is a bean de ned with @Component annotation and USER is a public eld of the class. Quarkus provides compatibility with the following Spring Cache hasAnyRole annotations:
@PreAuthorize("hasAnyRole(@roles.USER, 'view')") @Cacheable
Permit and Deny All @CachePut
@PreAuthorize("permitAll()") @CacheEvict
@PreAuthorize("denyAll()") Spring Schedule
Anonymous and Authenticated Quarkus provides a compatibility layer for Spring Scheduled annotation. @PreAuthorize("isAnonymous()")
@PreAuthorize("isAuthenticated()") ./mvnw quarkus:add-extension -Dextensions="spring-scheduled" Resources Authors : 1.13.0.Final
https://quarkus.io/guides/ @alexsotob Java Champion and Director of DevExp at Red Hat https://www.youtube.com/user/lordofthejars