Quarkus Cheat-Sheet

62
Quarkus Cheat-Sheet What is Quarkus? Quarkus is a Kubernetes Native Java stack tailored for GraalVM & OpenJDK HotSpot, crafted from the best of breed Java libraries and standards. Also focused on developer experience, making things just work with little to no conguration and allowing to do live coding. Cheat-sheet tested with Quarkus 1.13.0.Final. Getting Started Quarkus comes with a Maven archetype to scaffold a very simple starting project. mvn io.quarkus:quarkus-maven-plugin:1.13.0.Final:create \ -DprojectGroupId=org.acme \ -DprojectArtifactId=getting-started \ -DclassName="org.acme.quickstart.GreetingResource" \ -Dpath="/hello" This creates a simple JAX-RS resource called GreetingResource . @Path("/hello") public class GreetingResource { @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return "hello"; } } Gradle There is no way to scaffold a project in Gradle but you only need to do: plugins { id 'java' id 'io.quarkus' version '0.26.1' } repositories { mavenCentral() } dependencies { implementation enforcedPlatform('io.quarkus:quarkus-bo m:0.26.1') implementation 'io.quarkus:quarkus-resteasy' } Or in Kotlin: plugins { java } apply(plugin = "io.quarkus") repositories { mavenCentral() } dependencies { implementation(enforcedPlatform("io.quarkus:quarkus-bo m:0.26.1")) implementation("io.quarkus:quarkus-resteasy") } Packaging mvn clean package You need to distribute the -runner.jar le together with quarkus- app directory. If quarkus.package.uber-jar property is set to true, then a uber-jar is created with all dependencies bundled inside the JAR. By default, Quarkus uses fast jar packaging, if quarkus.package.type property is set to legacy-jar then Quarkus creates the old standard jar le. application.properties quarkus.package.uber-jar=true quarkus.package.type=legacy-jar To compile to native, you need to set GRAALVM_HOME environment variable and run the native prole. mvn clean package -Pnative ./gradlew build -Dquarkus.package.type=native Possible quarkus.package.type are: jar , legacy-jar , uber-jar and native . AppCDS Automatically generate AppCDS as part of the build process set the next property: quarkus.package.create-appcds=true . To make use of it, just run java -jar -XX:SharedArchiveFile=app- cds.jsa myapp.jar . Command mode You can dene the main CLI method to start Quarkus. There are two ways, implementing io.quarkus.runtime.QuarkusApplication interface or use the Java main method to launch Quarkus. @io.quarkus.runtime.annotations.QuarkusMain public class HelloWorldMain implements QuarkusApplication { @Override public int run(String... args) throws Exception { System.out.println("Hello World"); return 10; } } run method called when Quarkus starts, and stops when it nishes. As Java main : @QuarkusMain public class JavaMain { public static void main(String... args) { Quarkus.run(HelloWorldMain.class, args); } } Use @QuarkusMain in only one place. Use Quarkus.waitForExit() from the main thread if you want to run some logic on startup, and then run like a normal application (i.e. not exit). You can inject command line arguments by using @CommandLineArguments annotation: @CommandLineArguments String[] args; Picocli You can use Picocli to implement CLI applications: ./mvnw quarkus:add-extension -Dextensions="picocli"

Transcript of Quarkus Cheat-Sheet

Page 1: Quarkus Cheat-Sheet

QuarkusCheat-Sheet

WhatisQuarkus?

Quarkus isaKubernetesNativeJavastacktailoredforGraalVM&OpenJDKHotSpot,craftedfromthebestofbreedJavalibrariesandstandards. Also focused on developer experience, making thingsjust work with little to no con�guration and allowing to do livecoding.

Cheat-sheettestedwithQuarkus1.13.0.Final.

GettingStarted

QuarkuscomeswithaMavenarchetype toscaffoldaverysimplestartingproject.

mvnio.quarkus:quarkus-maven-plugin:1.13.0.Final:create\

-DprojectGroupId=org.acme\

-DprojectArtifactId=getting-started\

-DclassName="org.acme.quickstart.GreetingResource"\

-Dpath="/hello"

ThiscreatesasimpleJAX-RSresourcecalledGreetingResource .

@Path("/hello")publicclassGreetingResource{

@GET@Produces(MediaType.TEXT_PLAIN)publicStringhello(){return"hello";}

}

Gradle

ThereisnowaytoscaffoldaprojectinGradlebutyouonlyneedtodo:

plugins{

id'java'

id'io.quarkus'version'0.26.1'

}

repositories{

mavenCentral()

}

dependencies{

implementation enforcedPlatform('io.quarkus:quarkus-bo

m:0.26.1')

implementation'io.quarkus:quarkus-resteasy'

}

OrinKotlin:

plugins{

java

}

apply(plugin="io.quarkus")

repositories{

mavenCentral()

}

dependencies{

implementation(enforcedPlatform("io.quarkus:quarkus-bo

m:0.26.1"))

implementation("io.quarkus:quarkus-resteasy")

}

Packaging

mvncleanpackage

You need to distribute the -runner.jar �le together with quarkus-app directory.

If quarkus.package.uber-jar propertyissettotrue,thenauber-jariscreatedwithalldependenciesbundledinsidetheJAR.

Bydefault,Quarkususesfastjarpackaging,if quarkus.package.typepropertyissetto legacy-jar thenQuarkuscreatestheoldstandardjar�le.

application.properties

quarkus.package.uber-jar=truequarkus.package.type=legacy-jar

To compile to native, you need to set GRAALVM_HOME environmentvariableandrunthenative pro�le.

mvncleanpackage-Pnative

./gradlewbuild-Dquarkus.package.type=native

Possible quarkus.package.type are: jar , legacy-jar , uber-jar andnative .

AppCDS

AutomaticallygenerateAppCDSaspartofthebuildprocesssetthenextproperty:quarkus.package.create-appcds=true .

To make use of it, just run java -jar -XX:SharedArchiveFile=app-cds.jsamyapp.jar .

Commandmode

Youcande�nethemain CLImethodtostartQuarkus.Therearetwoways, implementing io.quarkus.runtime.QuarkusApplication

interfaceorusetheJavamainmethodtolaunchQuarkus.

@io.quarkus.runtime.annotations.QuarkusMainpublicclassHelloWorldMainimplementsQuarkusApplication{@Overridepublicintrun(String...args)throwsException{System.out.println("HelloWorld");

return10;}

}

run methodcalledwhenQuarkusstarts,andstopswhenit�nishes.

AsJavamain :

@QuarkusMainpublicclassJavaMain{publicstaticvoidmain(String...args){Quarkus.run(HelloWorldMain.class,args);

}

}

Use@QuarkusMain inonlyoneplace.

Use Quarkus.waitForExit() fromthemainthreadifyouwanttorunsome logiconstartup,and then run likeanormalapplication (i.e.notexit).

You can inject command line arguments by using@CommandLineArguments annotation:

@CommandLineArgumentsString[]args;

Picocli

YoucanusePicoclitoimplementCLIapplications:

./mvnwquarkus:add-extension

-Dextensions="picocli"

Page 2: Quarkus Cheat-Sheet

@CommandLine.CommandpublicclassHelloCommandimplementsRunnable{

@CommandLine.Option(names={"-n","--name"},description="Whowillwegreet?",defaultValue="World")

Stringname;

privatefinalGreetingServicegreetingService;

publicHelloCommand(GreetingServicegreetingService){this.greetingService=greetingService;}

@Overridepublicvoidrun(){greetingService.sayHello(name);

}

}

All classes annotated with picocli.CommandLine.Command areregisteredasCDIbeans.

Ifonlyoneclassannotatedwith picocli.CommandLine.Command itwillbe used as entry point. If you want to provide your own@QuarkusMain :

@[email protected](name="demo",mixinStandardHelpOptions=true)publicclassExampleAppimplementsRunnable,QuarkusApplication{

@InjectCommandLine.IFactoryfactory;

@Overridepublicvoidrun(){}

@Overridepublicintrun(String...args)throwsException{returnnewCommandLine(this, factory).execute(args);

}

}

Use quarkus.picocli.native-image.processing.enable to false tousethepicocli-codegen annotationprocessorinsteadofbuildsteps.

Youcanalsocon�gureCDIbeanswithPicoCLIarguments:

@CommandLine.CommandpublicclassEntryCommandimplementsRunnable{@CommandLine.Option(names="-c",description="JDBCconnectionstring")

StringconnectionString;

@InjectDataSourcedataSource;

}

@ApplicationScopedclassDatasourceConfiguration{

@Produces@ApplicationScopedDataSourcedataSource(CommandLine.ParseResultparseResult){

System.out.println(parseResult.matchedOption("c").g

etValue().toString());

}

}

Extensions

Quarkus comes with extensions to integrate with some librariessuch as JSON-B, Camel orMicroPro�le spec. To list all availableextensionsjustrun:

./mvnwquarkus:list-extensions

You can use -DsearchPattern=panache to �lter out allextensionsexcepttheonesmatchingtheexpression.

Andtoregistertheextensionsintobuildtool:

./mvnwquarkus:add-extension-Dextensions=""

./mvnwquarkus:remove-extension-Dextensions=""

extensions propertysupportsCSV format to registermorethanoneextensionatonce.

ApplicationLifecycle

Youcanbenoti�edwhentheapplicationstarts/stopsbyobservingStartupEvent andShutdownEvent events.

@ApplicationScopedpublicclassApplicationLifecycle{voidonStart(@ObservesStartupEventevent){}voidonStop(@ObservesShutdownEventevent){}}

Quarkussupportsgracefulshutdown.Bydefaultthereisnotimeoutbut can be set by using the quarkus.shutdown.timeout con�g

DevMode

./mvnwcompilequarkus:dev

./gradlewquarkusDev

Endpoints are registered automatically to provide some basicdebuginfoindevmode:

HTTPGET/quarkus/arc/beans

QueryParameters:scope ,beanClass ,kind .

HTTPGET/quarkus/arc/observers

DevUI

QuarkusaddsaDevUIconsoletoexposeextensionfeatures.

The Dev UI is available in dev mode only and accessible at the/q/dev endpointbydefault.

AddingCon�gurationParameters

To add con�guration to your application, Quarkus relies onMicroPro�leCon�gspec.

@ConfigProperty(name="greetings.message")Stringmessage;

@ConfigProperty(name="greetings.message",defaultValue="Hello")

StringmessageWithDefault;

@ConfigProperty(name="greetings.message")Optional<String>optionalMessage;

Propertiescanbeset(indecreasingpriority)as:

Systemproperties(-Dgreetings.message ).

Environmentvariables(GREETINGS_MESSAGE ).

Environment �le named .env placed in the current workingdirectory(GREETING_MESSAGE= ).

External con�gdirectory under the currentworking directory:config/application.properties .

Resourcessrc/main/resources/application.properties .

greetings.message=HelloWorld

Array ,List and Set aresupported.Thedelimiteriscomma(, )charand\ istheescapechar.

Con�gurationPro�les

Page 3: Quarkus Cheat-Sheet

Quarkus allow you to havemultiple con�guration in the same�le(application.properties ).

Thesyntaxforthisis%{profile}.config.key=value .

quarkus.http.port=9090%dev.quarkus.http.port=8181

HTTPportwillbe9090,unlessthe'dev'pro�leisactive.

Defaultpro�lesare:

dev :Activatedwhenindevelopmentmode(quarkus:dev ).

test :Activatedwhenrunningtests.

prod :Thedefaultpro�lewhennot running indevelopmentortestmode

Youcancreatecustompro�lenamesbyenablingthepro�leeithersetting quarkus.profile system property or QUARKUS_PROFILE

environmentvariable.

quarkus.http.port=9090%staging.quarkus.http.port=9999

Andenableitquarkus.profile=staging .

To get the active pro�le programmatically useio.quarkus.runtime.configuration.ProfileManager.getActiveProfile() .

Youcanalsosetitinthebuildtool:

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-surefire-plugin</artifactId>

<version>${surefire-plugin.version}</version>

<configuration>

<systemPropertyVariables>

<quarkus.test.profile>foo</quarkus.test.profile>

<buildDirectory>${project.build.directory}

</buildDirectory>

</systemPropertyVariables>

</configuration>

Sameformaven-failsafe-plugin .

test{

useJUnitPlatform()

systemProperty"quarkus.test.profile","foo"

}

Special properties are set in prod mode:quarkus.application.version and quarkus.application.name to getthemavailableatruntime.

@ConfigProperty(name="quarkus.application.name")StringapplicationName;

Additionallocations

You can use smallrye.config.locations property to set additionalcon�guration�les.

smallrye.config.locations=config.properties

or

java-jar-Dsmallrye.config.locations=config.properties

Youcanembedcon�guration�les insideadependencybyaddingMETA-INF/microprofile.properties insidetheJAR.Whendependencyis added to the application, con�guration properties are mergedwithcurrentcon�guration.

@Con�gProperties

Asanalternative to injectingmultiple relatedcon�gurationvalues,you can also use the @io.quarkus.arc.config.ConfigProperties

annotationtogroupproperties.

@ConfigProperties(prefix="greeting",namingStrategy=NamingStrategy.KEBAB_CASE)

publicclassGreetingConfiguration{privateStringmessage;//getter/setter

}

This class maps greeting.message property de�ned inapplication.properties .

YoucaninjectthisclassbyusingCDI@InjectGreetingConfigurationgreeting; .

Alsoyoucanuseaninterfaceapproach:

@ConfigProperties(prefix="greeting",namingStrategy=NamingStrategy.KEBAB_CASE)

publicinterfaceGreetingConfiguration{

@ConfigProperty(name="message")Stringmessage();StringgetSuffix();

If property does not follow getter/setter naming convention youneed to use org.eclipse.microprofile.config.inject.ConfigPropertytosetit.

Nestedobjectsarealsosupporte:

@ConfigProperties(prefix="greeting",namingStrategy=NamingStrategy.KEBAB_CASE)

publicclassGreetingConfiguration{publicStringmessage;publicHiddenConfighidden;

publicstaticclassHiddenConfig{publicList<String>recipients;}

}

Andanapplication.properties mappingpreviousclass:

greeting.message=hellogreeting.hidden.recipients=Jane,John

Bean Validation is also supported so properties are validated atstartuptime,forexample@Size(min=20)publicStringmessage; .

prefix attribute isnotmandatory. Ifnotprovided,attributeis determined by class name (ie GreeetingConfiguration istranslated to greeting or GreetingExtraConfiguration togreeting-extra ).Thesu�xoftheclassisalwaysremoved.

Naming strategy can be changed with property namingStrategy .KEBAB_CASE (whatever.foo-bar)orVERBATIM (whatever.fooBar).

@io.quarkus.arc.config.ConfigIgnore annotation can be used toignoretheinjectionofcon�gurationelements.

@ConfigIgnorepublicIntegerignored;

YAMLCon�g

YAML con�guration is also supported. The con�guration �le iscalled application.yaml and youneed to register adependency toenableitssupport:

pom.xml

<dependency>

<groupId>io.quarkus</groupId>

<artifactId>quarkus-config-yaml</artifactId>

</dependency>

quarkus:

datasource:

url:jdbc:postgresql://localhost:5432/some-database

driver:org.postgresql.Driver

Orwithpro�les:

Page 4: Quarkus Cheat-Sheet

"%dev":

quarkus:

datasource:

url:jdbc:postgresql://localhost:5432/some-database

driver:org.postgresql.Driver

Incaseofsubkeys~ isusedtorefertotheunpre�xedpart.

quarkus:

http:

cors:

~:true

methods:GET,PUT,POST

Isequivalentto:

quarkus.http.cors=truequarkus.http.cors.methods=GET,PUT,POST

CustomLoader

You can implement your own ConfigSource to load con�gurationfrom different places than the default ones provided by Quarkus.Forexample,database,customXML,RESTEndpoints,…

You need to create a new class and implement ConfigSource

interface:

packagecom.acme.config;publicclassInMemoryConfigimplementsConfigSource{

privateMap<String,String>prop=newHashMap<>();

publicInMemoryConfig(){//Initproperties

}

@OverridepublicintgetOrdinal(){//Thehighestordinaltakesprecedence

return900;}

@OverridepublicMap<String,String>getProperties(){returnprop;}

@OverridepublicStringgetValue(StringpropertyName){returnprop.get(propertyName);}

@OverridepublicStringgetName(){return"MemoryConfigSource";}

}

Thenyouneedtoregisterthe ConfigSource asJavaservice.Createa�lewiththefollowingcontent:

/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource

com.acme.config.InMemoryConfig

CustomConverters

You can implement your own conversion types from String.Implement org.eclipse.microprofile.config.spi.Converter

interface:

@Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY+100)publicclassCustomInstantConverterimplementsConverter<Instant>{

@OverridepublicInstantconvert(Stringvalue){if("now".equals(value.trim())){returnInstant.now();}

returnInstant.parse(value);}

}

@Priority annotation is used to override the defaultInstantConverter .

Thenyouneed to register the Converter asJavaservice.Createa�lewiththefollowingcontent:

/META-INF/services/org.eclipse.microprofile.config.spi.Converter

com.acme.config.CustomInstantConverter

UndertowProperties

Possibleparameterswithpre�xquarkus.servlet :

context-path

ThecontextpathtoserveallServletcontextfrom.(default:/ )

default-charset

The default charset to use for reading and writing requests.(default:UTF-8 )

Injection

Quarkus is basedonCDI2.0 to implement injectionof code. It isnot fully supported and only a subset of the speci�cation isimplemented.

@ApplicationScopedpublicclassGreetingService{

publicStringmessage(Stringmessage){returnmessage.toUpperCase();}

}

Scopeannotationismandatorytomakethebeandiscoverable.

@InjectGreetingServicegreetingService;

Quarkus is designed with Substrate VM in mind. For thisreason, we encourage you to use package-private scopeinsteadofprivate.

Produces

You can also create a factory of an object by [email protected] annotation.

@Produces@ApplicationScopedMessagemessage(){Messagem=newMessage();m.setMsn("Hello");

returnm;}

@InjectMessagemsg;

Quali�ers

You can use quali�ers to return different implementations of thesameinterfaceortocustomizethecon�gurationofthebean.

Page 5: Quarkus Cheat-Sheet

@Qualifier@Retention(RUNTIME)@Target({TYPE,METHOD,FIELD,PARAMETER})public@interfaceQuote{@NonbindingStringvalue();}

@Produces@Quote("")Messagemessage(InjectionPointmsg){Messagem=newMessage();m.setMsn(

msg.getAnnotated()

.getAnnotation(Quote.class)

.value()

);

returnm;}

@Inject@Quote("AlohaBeach")Messagemessage;

Quarkus breaks the CDI spec by allowing you to injectquali�edbeanswithoutusing@Inject annotation.

@Quote("AlohaBeach")Messagemessage;

Quarkus breaks the CDI spec by skipping the @Producesannotationcompletelyiftheproducermethodisannotatedwithascopeannotation,astereotypeoraquali�er.

@Quote("")Messagemessage(InjectionPointmsg){}

@Quote("AlohaBeach")Messagemessage;

Alternatives

It is also possible to select alternatives for an application usingapplication.properties .

quarkus.arc.selected-alternatives=org.acme.Foo,org.acme.*,Bar

BeansbyQuarkusPro�le

Using @io.quarkus.arc.profile.IfBuildProfile [email protected] annotations, you canconditionallyenableabean.

@DependentpublicclassTracerConfiguration{@Produces@IfBuildProfile("prod")publicTracerrealTracer(Reporterreporter,Configurationconfiguration){

returnnewRealTracer(reporter,configuration);}

@Produces@DefaultBeanpublicTracernoopTracer(){returnnewNoopTracer();}

}

Using @io.quarkus.arc.profile.IfBuildProperty annotation, youcanconditionally enable a bean. @io.quarkus.arc.DefaultBean sets thedefaultbean.

@DependentpublicclassTracerConfiguration{@Produces@IfBuildProperty(name="some.tracer.enabled",stringValue="true")

publicTracerrealTracer(Reporterreporter,Configurationconfiguration){}

@Produces@DefaultBeanpublicTracernoopTracer(){}}

Propertiessetat runtimehaveabsolutelynoeffecton thebeanresolutionusing@IfBuildProperty .

Container-managedConcurrency

Quarkusprovides @io.quarkus.arc.Lock andabuilt-ininterceptorforconcurrencycontrol.

@Lock@ApplicationScopedclassSharedService{

voidaddAmount(BigDecimalamout){}

@Lock(value=Lock.Type.READ,time=1,unit=TimeUnit.SECONDS)

BigDecimalgetAmount(){}

}

By default the class is in write mode (so no concurrent callsallowed)exceptwhen lock type is READ where themethodcanbecalledconcurrentlyifnowriteoperationinprocess.

JSON Marshalling/Unmarshalling

ToworkwithJSON-B youneedtoaddadependency:

./mvnwquarkus:add-extension

-Dextensions="io.quarkus:quarkus-resteasy-jsonb"

AnyPOJOismarshaled/unmarshalledautomatically.

publicclassSauce{privateStringname;privatelongscovilleHeatUnits;

//getter/setters

}

JSONequivalent:

{

"name":"Blair'sUltraDeath",

"scovilleHeatUnits":1100000

}

InaPOST endpointexample:

@POST@Consumes(MediaType.APPLICATION_JSON)publicResponsecreate(Saucesauce){//CreateSauce

returnResponse.created(URI.create(sauce.getId())).build();

}

ToprovidecustomJsonBCon�gobject:

@DependentJsonbConfig jsonConfig(Instance<JsonbConfigCustomizer> customizers){

JsonbConfigconfig=myJsonbConfig();//Custom`JsonbC

onfig`

for(JsonbConfigCustomizercustomizer:customizers){customizer.customize(config);

}

returnconfig;}

ToworkwithJackson youneedtoadd:

./mvnwquarkus:add-extension

-Dextensions="quarkus-resteasy-jackson"

Ifyoudon’twanttousethedefaultObjectMapper youcancustomizeitby:

Page 6: Quarkus Cheat-Sheet

@ApplicationScopedpublicclassCustomObjectMapperConfig{@Singleton@ProducespublicObjectMapperobjectMapper(Instance<ObjectMapperCustomizer>customizers){

ObjectMapperobjectMapper=newObjectMapper();//performconfiguration

for(ObjectMapperCustomizercustomizer:customizers){

customizer.customize(mapper);

}

returnobjectMapper;}

}

DefaultmediatypeinQuarkusRestEasyisJSON.

XMLMarshalling/Unmarshalling

ToworkwithJAX-B youneedtoaddadependency:

./mvnwquarkus:add-extension

-Dextensions="quarkus-resteasy-jaxb"

ThenannotatedPOJOsareconvertedtoXML.

@XmlRootElementpublicclassMessage{}

@GET@Produces(MediaType.APPLICATION_XML)publicMessagehello(){returnmessage;}

JAXP

ToworkwithJAX-P youneedtoaddadependency:

./mvnwquarkus:add-extension

-Dextensions="jaxp"

finalDocumentBuilderdBuilder=DocumentBuilderFactory.newInstance().newDocumentBuilder();

finalDocumentdoc=dBuilder.parse(in);returndoc.getDocumentElement().getTextContent();

Validator

QuarkususesHibernateValidatortovalidateinput/outputofRESTservicesandbusinessservicesusingBeanvalidationspec.

./mvnwquarkus:add-extension

-Dextensions="io.quarkus:quarkus-hibernate-validator"

Annotate POJO objects with validator annotations such as:@NotNull ,@Digits ,@NotBlank ,@Min ,@Max ,…

publicclassSauce{

@NotBlank(message="Namemaynotbeblank")privateStringname;@Min(0)privatelongscovilleHeatUnits;

//getter/setters

}

Tovalidateanobjectuse@Valid annotation:

publicResponsecreate(@ValidSaucesauce){}

If a validation error is triggered, a violation report isgenerated and serialized as JSON. If you want tomanipulate the output, you need to catch in the code theConstraintViolationException exception.

CreateYourCustomConstraints

Firstyouneedtocreatethecustomannotation:

@Target({METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER,TYPE_USE})

@Retention(RUNTIME)@Documented@Constraint(validatedBy={NotExpiredValidator.class})public@interfaceNotExpired{

Stringmessage()default"Saucemustnotbeexpired";Class<?>[]groups()default{};Class<?extendsPayload>[]payload()default{};

}

You need to implement the validator logic in a class thatimplementsConstraintValidator .

publicclassNotExpiredValidatorimplementsConstraintValidator<NotExpired,LocalDate>{

@OverridepublicbooleanisValid(LocalDatevalue,ConstraintValidatorContextctx){

if(value==null)returntrue;LocalDatetoday=LocalDate.now();

returnChronoUnit.YEARS.between(today,value)>0;}

}

Anduseitnormally:

@NotExpired@JsonbDateFormat(value="yyyy-MM-dd")privateLocalDateexpired;

ManualValidation

Youcancallthevalidationprocessmanuallyinsteadofrelayingto@Valid byinjectingValidator class.

@InjectValidatorvalidator;

Anduseit:

Set<ConstraintViolation<Sauce>>violations=

validator.validate(sauce);

Localization

Youcancon�gurethebasedlocaleforvalidationmessages.

quarkus.default-locale=ca-ES#SupportedlocalesresolvedbyAccept-Language

quarkus.locales=en-US,es-ES,fr-FR,ca_ES

ValidationMessages_ca_ES.properties

pattern.message=Noconformealpatro

@Pattern(regexp="A.*",message="{pattern.message}")privateStringname;

Bean Validation can be con�gured . The pre�x is:quarkus.hibernate-validator .

fail-fast

Page 7: Quarkus Cheat-Sheet

When fail fast is enabled the validation will stop on the �rstconstraintviolationdetected.(default:false )

method-validation.allow-overriding-parameter-constraints

De�ne whether overriding methods that override constraintsshouldthrowanexception.(default:false ).

method-validation.allow-parameter-constraints-on-parallel-methods

De�ne whether parallelmethods that de�ne constraints shouldthrowanexception.(default:false ).

method-validation.allow-multiple-cascaded-validation-on-return-

values

De�newhethermore thanoneconstraintona returnvaluemaybemarkedforcascadingvalidationareallowed.(default:false ).

Logging

Youcancon�gurehowQuarkuslogs:

quarkus.log.console.enable=truequarkus.log.console.level=DEBUGquarkus.log.console.color=falsequarkus.log.category."com.lordofthejars".level=DEBUG

Pre�xisquarkus.log .

category."<category-name>".level

Minimumlevelcategory(default:INFO )

level

Defaultminimumlevel(default:INFO )

console.enabled

Consoleloggingenabled(default:true )

console.format

Formatpatterntouseforlogging.Defaultvalue:%d{yyyy-MM-ddHH:mm:ss,SSS}%-5p[%c{3.}](%t)%s%e%n

console.level

Minimumloglevel(default:INFO )

console.color

Allowcolorrendering(default:true )

file.enable

Fileloggingenabled(default:false )

file.format

Formatpatterntouseforlogging.Defaultvalue:%d{yyyy-MM-ddHH:mm:ss,SSS}%h%N[%i]%-5p[%c{3.}](%t)%s%e%n

file.level

Minimumloglevel(default:ALL )

file.path

Thepathtolog�le(default:quarkus.log )

file.rotation.max-file-size

Themaximum�lesizeofthelog�le

file.rotation.max-backup-index

Themaximumnumberofbackupstokeep(default:1 )

file.rotation.file-suffix

Rotatinglog�lesu�x.

file.rotation.rotate-on-boot

Indicatesrotatelogsatbootup(default:true )

file.async

Logasynchronously(default:false )

file.async.queue-length

Thequeuelengthtousebefore�ushingwriting(default:512 )

file.async.overflow

Actionwhenqueueisfull(default:BLOCK )

syslog.enable

syslogloggingisenabled(default:false )

syslog.format

Theformatpatterntouseforloggingtosyslog.Defaultvalue:%d{yyyy-MM-ddHH:mm:ss,SSS}%h%N[%i]%-5p[%c{3.}](%t)%s%e%n

syslog.level

Theminimumlogleveltowritetosyslog(default:ALL )

syslog.endpoint

The IP address and port of the syslog server (default:localhost:514 )

syslog.app-name

The app name usedwhen formatting themessage in RFC5424format(default:currentprocessname)

syslog.hostname

Thenameofthehostthemessagesarebeingsentfrom(default:currenthostname)

syslog.facility

Priority of themessage as de�ned by RFC-5424 and RFC-3164(default:USER_LEVEL )

syslog.syslog-type

Thesyslogtypeofformatmessage(default:RFC5424 )

syslog.protocol

Protocolused(default:TCP )

syslog.use-counting-framing

Messagepre�xedwiththesizeofthemessage(defaultfalse )

syslog.truncate

Messageshouldbetruncated(default:true )

syslog.block-on-reconnect

Blockwhenattemptingtoreconnect(default:true )

syslog.async

Logasynchronously(default:false )

syslog.async.queue-length

Thequeuelengthtousebefore�ushingwriting(default:512 )

syslog.async.overflow

Actionwhenqueueisfull(default:BLOCK )

Youcaninjectloggerinstance:

importorg.jboss.logging.Logger;importio.quarkus.arc.log.LoggerName;

@InjectLoggerlog;

@LoggerName("foo")LoggerfooLog;

publicvoidping(){log.info("Simple!");

}

Gelfouput

Youcancon�guretheoutputtobeinGELFformatinsteadofplaintext.

./mvnwquarkus:add-extension

-Dextensions="quarkus-logging-gelf"

handler.gelf.enabled

EnableGELFlogginghandler(default:false )

handler.gelf.host

Hostname/IP of Logstash/Graylof. Prepend tcp: for using TCPprotocol.(default:udp:localhost )

handler.gelf.port

Theport.(default:12201 )

handler.gelf.version

GELFversion.(default:1.1 )

handler.gelf.extract-stack-trace

PostStack-TracetoStackTrace�eld.(default:true )

handler.gelf.stack-trace-throwable-reference

Getsthecauseleveltostacktrace. 0 isfullstacktrace.(default:)

Page 8: Quarkus Cheat-Sheet

handler.gelf.filter-stack-trace

Stack-Trace�ltering.(default:false )

handler.gelf.timestamp-pattern

JavaDatepattern.(default:yyyy-MM-ddHH:mm:ss,SSS )

handler.gelf.level

Logleveljava.util.logging.Level .(default:ALL )

handler.gelf.facility

Nameofthefacility.(default:jboss-logmanage )

handler.gelf.additional-field.<field>.<subfield>

Post additional �elds. quarkus.log.handler.gelf.additional-

field.field1.type=String

handler.gelf.include-full-mdc

Includeall�eldsfromtheMDC.

handler.gelf.maximum-message-size

Maximummessagesize(inbytes).(default:8192 )

handler.gelf.include-log-message-parameters

Includemessageparametersfromthelogevent.(default:true )

handler.gelf.include-location

Includesourcecodelocation.(default:true )

JSONoutput

Youcancon�guretheoutputtobeinJSONformatinsteadofplaintext.

./mvnwquarkus:add-extension

-Dextensions="quarkus-logging-json"

Andthecon�gurationvaluesarepre�xwithquarkus.log :

json

JSONloggingisenabled(default:true).

json.pretty-print

JSONoutputis"pretty-printed"(default:false)

json.date-format

Specifythedateformattouse(default:thedefaultformat)

json.record-delimiter

Recorddelimitertoadd(default:nodelimiter)

json.zone-id

ThetimezoneID

json.exception-output-type

The exception output type: detailed , formatted , detailed-and-

formatted (default:detailed )

json.print-details

Detailedcallerinformationshouldbelogged(default:false)

RestClient

QuarkusimplementsMicroPro�leRestClientspec:

./mvnwquarkus:add-extension

-Dextensions="quarkus-rest-client"

To get content from http://worldclockapi.com/api/json/cet/nowyouneedtocreateaserviceinterface:

@Path("/api")@RegisterRestClientpublicinterfaceWorldClockService{

@GET@Path("/json/cet/now")@Produces(MediaType.APPLICATION_JSON)WorldClockgetNow();

@GET@Path("/json/{where}/now")@Produces(MediaType.APPLICATION_JSON)WorldClockgetSauce(@BeanParamWorldClockOptionsworldClockOptions);

}

publicclassWorldClockOptions{@HeaderParam("Authorization")Stringauth;

@PathParam("where")Stringwhere;

}

Andcon�gurethehostnameatapplication.properties :

org.acme.quickstart.WorldClockService/mp-rest/url=http://worldclockapi.com

Injectingtheclient:

@RestClientWorldClockServiceworldClockService;

If invokation happens within JAX-RS, you can propagate headersfromincomingtooutgoingbyusingnextproperty.

org.eclipse.microprofile.rest.client.propagateHeaders=Authorization,MyCustomHeader

You can still use the JAX-RS client without any problemClientBuilder.newClient().target(…)

Addingheaders

You can customize the headers passed by implementingMicroPro�leClientHeadersFactory annotation:

@RegisterForReflectionpublicclassBaggageHeadersFactoryimplementsClientHeadersFactory{@OverridepublicMultivaluedMap<String,String>update(MultivaluedMap<String,String>incomingHeaders,

MultivaluedMap<String,String>outgoingHeaders){}

}

And registering it in the client using RegisterClientHeaders

annotation.

@RegisterClientHeaders(BaggageHeadersFactory.class)@RegisterRestClientpublicinterfaceWorldClockService{}

Orstaticallyset:

@GET@ClientHeaderParam(name="X-Log-Level",value="ERROR")ResponsegetNow();

Asynchronous

Amethodonclient interfacecanreturna CompletionStage classtobeexecutedasynchronously.

@GET@Path("/json/cet/now")@Produces(MediaType.APPLICATION_JSON)CompletionStage<WorldClock>getNow();

Reactive

Rest Client also integrateswith reactive library namedMutiny.Tostartusingityouneedtoaddthequarkus-rest-client-mutiny .

After that, a methodon a client interface can return aio.smallrye.mutiny.Uni instance.

@GET@Path("/json/cet/now")@Produces(MediaType.APPLICATION_JSON)Uni<WorldClock>getNow();

ARESTEasyReactive-basedRESTClientextension.Youonlyneedtoreplacethequarkus-rest-client toquarkus-rest-client-reactive .

Multipart

Page 9: Quarkus Cheat-Sheet

Itisreallyeasytosendmultipartform-datawithRestClient.

<dependency>

<groupId>org.jboss.resteasy</groupId>

<artifactId>resteasy-multipart-provider</artifactId>

</dependency>

Themodelobject:

importjava.io.InputStream;

importjavax.ws.rs.FormParam;importjavax.ws.rs.core.MediaType;

importorg.jboss.resteasy.annotations.providers.multipart.Part

Type;

publicclassMultipartBody{

@FormParam("file")@PartType(MediaType.APPLICATION_OCTET_STREAM)privateInputStreamfile;

@FormParam("fileName")@PartType(MediaType.TEXT_PLAIN)privateStringname;

//getter/setters

}

AndtheRestclientinterface:

importorg.jboss.resteasy.annotations.providers.multipart.Mult

ipartForm;

@Path("/echo")@RegisterRestClientpublicinterfaceMultipartService{

@POST@Consumes(MediaType.MULTIPART_FORM_DATA)@Produces(MediaType.TEXT_PLAIN)StringsendMultipartData(@MultipartFormMultipartBodydata);

}

SSL

Youcancon�gureRestClientkeystores.

org.acme.quickstart.WorldClockService/mp-rest/trustStore=classpath:/store.jksorg.acme.quickstart.WorldClockService/mp-rest/trustStorePassword=supersecret

Possiblecon�gurationproperties:

%s/mp-rest/trustStore

Truststorelocationde�nedwithclasspath: orfile: pre�x.

%s/mp-rest/trustStorePassword

Truststorepassword.

%s/mp-rest/trustStoreType

Truststoretype(default:JKS )

%s/mp-rest/hostnameVerifier

Customhostnameveri�erclassname.TodisableSSLveri�cationyoucanuseio.quarkus.restclient.NoopHostnameVerifier .

%s/mp-rest/keyStore

Keystorelocationde�nedwithclasspath: orfile: pre�x.

%s/mp-rest/keyStorePassword

Keystorepassword.

%s/mp-rest/keyStoreType

Keystoretype(default:JKS )

Timeout

Youcande�nethetimeoutoftheRestClient:

org.acme.quickstart.WorldClockService/mp-rest/connectTimeout=1000

org.acme.quickstart.WorldClockService/mp-rest/readTimeout=2000

Instantiateclientprogrammatically

MovieReviewServicereviewSvc=RestClientBuilder.newBuilder

()

.baseUri(apiUri)

.build(WorldClockService.class);

Testing

QuarkusarchetypeaddstestdependencieswithJUnit5andRest-AssuredlibrarytotestRESTendpoints.

@QuarkusTestpublicclassGreetingResourceTest{

@TestpublicvoidtestHelloEndpoint(){given()

.when().get("/hello")

.then()

.statusCode(200)

.body(is("hello"));

}

}

Test port can be set in quarkus.http.test-port property. Timeoutcanbesetinquarkus.http.test-timeout property.

YoucanalsoinjecttheURLwhereQuarkusisstarted:

@TestHTTPResource("index.html")URLurl;

@TestHTTPEndpoint(GreetingResource.class)@TestHTTPResourceURLurl;

@QuarkusTest@TestHTTPEndpoint(GreetingResource.class)publicclassGreetingResourceTest{@TestpublicvoidtestHelloEndpoint(){given()

.when().get()

.then()

.statusCode(200)

.body(is("hello"));

}

}

Root path is calculated automatically, not necessary to explicitlyset.

If youwantanychangesmade tobe rolledbackat theendofthetestyoucanusetheio.quarkus.test.TestTransaction annotation.

QuarkusTestPro�le

Youcande�neforeachTestclassadifferentcon�gurationoptions.

ThisimpliesthattheQuarkusserviceisrestarted.

Page 10: Quarkus Cheat-Sheet

publicclassMyProfileimplementsio.quarkus.test.junit.QuarkusTestProfile{

@OverridepublicMap<String,String>getConfigOverrides(){returnMap.of("greetings.message","ThisisaTest");

}

@OverridepublicStringgetConfigProfile(){return"my-test-profile";}

@OverridepublicSet<String>tags(){returnCollections.singleton("test1");}

}

@QuarkusTest@TestProfile(MyProfile.class)publicclassMyTestClass{}

quarkus.test.profile.tags property can be set to limit testexecutionoftestpro�les.Ifnotsetalltestsareexecuted.

quarkus.test.profile.tags=test1

QuarkusTestResource

You can execute some logic before the �rst test run (start ) andexecutesomelogicattheendofthetestsuite(stop ).

You need to create a class implementingQuarkusTestResourceLifecycleManager interfaceand register it in thetestvia@QuarkusTestResource annotation.

publicclassMyCustomTestResourceimplementsQuarkusTestResourceLifecycleManager{

@OverridepublicMap<String,String>start(){//returnsystempropertiesthat

//shouldbesetfortherunningtest

returnCollections.emptyMap();}

@Overridepublicvoidstop(){}

//optional

@Overridepublicvoidinject(ObjecttestInstance){}

//optional

@Overridepublicintorder(){return0;}

}

Returning new system properties implies running paralleltestsindifferentJVMs.

Andtheusage:

@QuarkusTestResource(MyCustomTestResource.class)publicclassMyTest{}

When using multiple QuarkusTestResource you can set parallel

attributetotrue tostartthemconcurrently.

TestingCallbacks

Youcanenrichall your @QuarkusTest classesby implementing thefollowingcallbackinterfaces:

io.quarkus.test.junit.callback.QuarkusTestBeforeClassCallback

io.quarkus.test.junit.callback.QuarkusTestAfterConstructCall

back

io.quarkus.test.junit.callback.QuarkusTestBeforeEachCallback

io.quarkus.test.junit.callback.QuarkusTestAfterEachCallback

publicclassSimpleAnnotationCheckerBeforeClassCallbackimplementsQuarkusTestBeforeClassCallback{@OverridepublicvoidbeforeClass(Class<?>testClass){}

}

AndneedstoberegisteredasJavaSPI:

META-INF/services/io.quarkus.test.junit.callback.QuarkusTestBeforeClassCallback

io.quarkus.it.main.SimpleAnnotationCheckerBeforeClassCallba

ck

Mocking

If you need to provide an alternative implementation of a service(for testing purposes) you can do it by using CDI @Alternativeannotationusingitinthetestserviceplacedatsrc/test/java :

@Alternative@Priority(1)@ApplicationScopedpublicclassMockExternalServiceextendsExternalService{}

Thisdoesnotworkwhenusingnativeimagetesting.

Astereotypeannotation io.quarkus.test.Mock isprovideddeclaring@Alternative ,@Priority(1) and@Dependent .

Mockito

Instead of creating stubs, you can also create mocks of yourservices with mockito. Add the following dependencyio.quarkus:quarkus-junit5-mockito :

@InjectMockGreetingServicegreetingService;

@BeforeEachpublicvoidsetup(){Mockito.when(greetingService.greet()).thenReturn("Hi");

}

@Path("/hello")publicclassExampleResource{

@InjectGreetingServicegreetingService;

}

Mock is automatically injected and only valid for the de�ned testclass.

Alsospy issupported:

@InjectSpyGreetingServicegreetingService;

Mockito.verify(greetingService,Mockito.times(1)).greet();

RESTClient

Page 11: Quarkus Cheat-Sheet

To Mock REST Client, you need to de�ne the interface with@ApplicationScope :

@ApplicationScoped@RegisterRestClientpublicinterfaceGreetingService{}

@InjectMock@RestClientGreetingServicegreetingService;

Mockito.when(greetingService.hello()).thenReturn("hello fro

mmockito");

Interceptors

TestsareactuallyfullCDIbeans,soyoucanapplyCDIinterceptors:

@QuarkusTest@Stereotype@Transactional@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public@interfaceTransactionalQuarkusTest{}

@TransactionalQuarkusTestpublicclassTestStereotypeTestCase{}

TestCoverage

Due the nature of Quarkus to calculate correctly the coverageinformationwithJaCoCo,youmightneedo�ineinstrumentation.

./mvnwquarkus:add-extension

-Dextensions="quarkus-jacoco"

Possiblecon�gurationparameterspre�xedquarkus.jacoco :

data-file

Thejacocodata�le.(default:jacoco-quarkus.exec )

report

IfQuarkusshouldgeneratetheJacocoreport.(default:true )

output-encoding

Encodingofthegeneratedreports.(default:UTF-8 )

title

NameoftherootnodeHTMLreportpages.

footer

FootertextusedinHTMLreportpages.

source-encoding

Encoding of the source �les (default: UTF-8 )

includes

Alistofclass�lestoincludeinthereport.(default:** )

excludes

Alistofclass�lestoexcludefromthereport.

report-location

Thelocationofthereport�les.(default:jacoco-report )

NativeTesting

Totestnativeexecutablesannotatethetestwith@NativeImageTest .

QuarkusIntegrationTests

@QuarkusIntegrationTest should be used to launch and test theartifact produced by theQuarkus build. If the result of aQuarkusbuild is a JAR then the app is launched as java-jar , if native islaunched as ./application , if container image is created (JiB,Dockerextensions)islaunchedasdockerrun .

Persistence

Quarkus works with JPA(Hibernate) as persistence solution. Butalso provides an Active Record pattern implementation underPanacheproject.

To use database access you need to add Quarkus JDBC driversinsteadoftheoriginalones.Atthistime ApacheDerby , H2 , MariaDB ,MySQL ,MSSQL andPostgreSQL driversaresupported.

./mvnwquarkus:add-extension

-Dextensions="io.quarkus:quarkus-hibernate-orm-panache,

io.quarkus:quarkus-jdbc-mariadb"

@EntitypublicclassDeveloperextendsPanacheEntity{

//idfieldisimplicit

publicStringname;}

Andcon�gurationinsrc/main/resources/application.properties :

quarkus.datasource.jdbc.url=jdbc:mariadb://localhost:3306/mydb

quarkus.datasource.db-kind=mariadbquarkus.datasource.username=developerquarkus.datasource.password=developerquarkus.hibernate-orm.database.generation=update

Listofdatasourceparameters.

quarkus.datasource aspre�xisskippedinthenexttable.

db-kind

Built-in datasource kinds so the JDBC driver is resolvedautomatically. Possible values: derby , h2 , mariadb , mssql , mysql ,postgresql ,db2 .

username

Usernametoaccess.

password

Passwordtoaccess.

driver

JDBCDriverclass.Itisnotnecessarytosetifdb-kind used.

credentials-provider

Setsacustomcredentialprovidername.

credentials-provider-name

It is the @Named value of the credentials provider bean. Notnecessaryifonlyoneimplementation.

Page 12: Quarkus Cheat-Sheet

jdbc.url

ThedatasourceURL.

jdbc.min-size

Thedatasourcepoolminimumsize.(default:0 )

jdbc.max-size

Thedatasourcepoolmaximumsize.(default:20 )

jdbc.initial-size

Theinitialsizeofthepool.

jdbc.background-validation-interval

The interval at which we validate idle connections in thebackground.(default:2M )

jdbc.acquisition-timeout

The timeout before cancelling the acquisition of a newconnection.(default:5 )

jdbc.leak-detection-interval

Theintervalatwhichwecheckforconnectionleaks.

jdbc.idle-removal-interval

Theintervalatwhichwetrytoremoveidleconnections.(default:5M )

jdbc.max-lifetime

Themaxlifetimeofaconnection.

jdbc.transaction-isolation-level

The transaction isolation level.Possiblevalues: UNDEFINED , NONE ,READ_UNCOMMITTED ,READ_COMMITTED ,REPEATABLE_READ ,SERIALIZABLE .

jdbc.detect-statement-leaks

Warn when a connection is returned to the pool without theapplicationhavingclosedallopenstatements.(default:true )

jdbc.new-connection-sql

Queryexecutedwhen�rstusingaconnection.

jdbc.validation-query-sql

Queryexecutedtovalidateaconnection.

jdbc.pooling-enabled

DisablepoolingtopreventreuseofConnections.(default:true )

jdbc.enable-metrics

Enable datasource metrics collection when using quarkus-

smallrye-metrics extension.

jdbc.additional-jdbc-properties.<extraProperty>

Unspeci�ed properties to be passed to the JDBC driver whencreatingnewconnections.

Hibernate con�guration properties. Pre�x quarkus.hibernate-orm isskipped.

dialect

ClassnameoftheHibernateORMdialect.

dialect.storage-engine

The storage enginewhen the dialect supportsmultiple storageengines.

sql-load-script

Nameofthe�lecontainingtheSQLstatementstoexecutewhenstarts. no-file force Hibernate to skip SQL import. (default:import.sql )

batch-fetch-size

Thesizeofthebatches.(default:-1disabled)

maxFetchDepth

The maximum depth of outer join fetch tree for single-endedassociations.

multitenant

De�nesthemethodformulti-tenancy.Possiblevalues: DATABASE ,NONE ,SCHEMA .(default:NONE )

multitenant-schema-datasource

De�nesthenameofthedatasourcetouseincaseofSCHEMAapproach.

query.query-plan-cache-max-size

Themaximumsizeofthequeryplancache.

query.default-null-ordering

Default precedence of null values in ORDERBY . Possible values:none ,first ,last .(default:none )

database.generation

Database schema is generation. Possible values: none , create ,drop-and-create ,drop ,update .(default:none )

database.generation.halt-on-error

Stoponthe�rsterrorwhenapplyingtheschema.(default:false )

database.generation.create-schemas

Hibernate ORM should create the schemas automatically (fordatabasessupportingthem).

database.default-catalog

Defaultcatalog.

database.default-schema

DefaultSchema.

database.charset

Charset.

jdbc.timezone

TimeZoneJDBCdriver.

jdbc.statement-fetch-size

Numberofrowsfetchedatatime.

jdbc.statement-batch-size

Numberofupdatessentatatime.

log.sql

ShowSQLlogs(default:false )

log.jdbc-warnings

statistics

Enablestatiscscollection.(default:false )

physical-naming-strategy

Class name of the Hibernate PhysicalNamingStrategyimplementation.

globally-quoted-identifiers

Shouldquoteallidenti�ers.(default:false )

metrics-enabled

Metrics published with smallrye-metrics extension (default:false )

second-level-caching-enabledEnable/Disable2ndlevelcache.(default:true )

Databaseoperations:

//Insert

Developerdeveloper=newDeveloper();developer.name="Alex";

developer.persist();

//FindAll

Developer.findAll().list();

//HibernateFilters

Person.findAll().filter("Person.hasName", Parameters.with(

"name","Alex"));

//FindByQuery

Developer.find("name","Alex").firstResult();

//Delete

Developerdeveloper=newDeveloper();developer.id=1;

developer.delete();

Person.deleteById(id);

//DeleteByQuery

longnumberOfDeleted=Developer.delete("name","Alex");

Remembertoannotatemethodswith @Transactional annotationtomakechangespersistedinthedatabase.

Ifqueriesstartwiththekeyword from thentheyaretreatedasHQLquery,ifnotthennextshortformissupported:

orderby whichexpandstofromEntityNameorderby…

Page 13: Quarkus Cheat-Sheet

<columnName> which expands to from EntityName where

<columnName>=?

<query> whichisexpandedtofromEntityNamewhere<query>

StaticMethods

findById :ObjectReturns object or null if not found. Overloaded version withLockModeType isprovided.

findByIdOptional :Optional<Object>Returnsobjectorjava.util.Optional .

find :String ,[Object…,Map<String,Object> ,Parameters ]Lists of entities meeting given query with parameters set.ReturningaPanacheQuery .

find :String ,Sort ,[Object…,Map<String,Object> ,Parameters ]ListsofentitiesmeetinggivenquerywithparameterssetsortedbySort attribute/s.ReturningaPanacheQuery .

findAll

Findsallentities.ReturningaPanacheQuery .

findAll :SortFinds all entities sorted by Sort attribute/s. Returning aPanacheQuery .

list :String ,[Object…,Map<String,Object> ,Parameters ]Lists of entities meeting given query with parameters set.ReturningaList .

list :String ,Sort ,[Object…,Map<String,Object> ,Parameters ]ListsofentitiesmeetinggivenquerywithparameterssetsortedbySort attribute/s.ReturningaList .

listAll

Findsallentities.ReturningaList .

listAll :SortFindsallentitiessortedbySort attribute/s.ReturningaList .

stream :String ,[Object…,Map<String,Object> ,Parameters ]java.util.stream.Stream of entities meeting given query withparametersset.

stream :String ,Sort ,[Object…,Map<String,Object> ,Parameters ]java.util.stream.Stream of entities meeting given query withparameterssetsortedbySort attribute/s.

streamAll

java.util.stream.Stream ofallentities.

streamAll :Sortjava.util.stream.Stream ofallentitiessortedbySort attribute/s.

count

Number of entities

count :String ,[Object…,Map<String,Object> ,Parameters ]Numberofentitiesmeetinggivenquerywithparametersset.

EnablesaHibernate�lterduringfetchingofresultsforthisquery.

deleteAll

Numberofdeletedentities.

delete :String ,[Object…,Map<String,Object> ,Parameters ]Numberofdeletedentitiesmeetinggivenquerywithparametersset.

deleteById :boolean ,[Object ]Deletebyid.Returnsifdeletedornot.

persist :[Iterable ,Steram ,Object…]Persistobject.

In case of using streams, remember to close them or use atry/catch block:try(Stream<Person>persons=Person.streamAll()) .

find methods de�nes a withLock(LockModeType) to de�nethe lock type and withHint(QueryHints.HINT_CACHEABLE,

"true") tode�nehints.

NamedQueries

@Entity@NamedQuery(name="Person.getByName",query="fromPersonwherename=:name")

publicclassPersonextendsPanacheEntity{

publicstaticPersonfindByName(Stringname){returnfind("#Person.getByName",name).firstResult();

}

}

Pagination

PanacheQuery<Person>livingPersons=Person

.find("status",Status.Alive);

livingPersons.page(Page.ofSize(25));

//getthefirstpage

List<Person>firstPage=livingPersons.list();

//getthesecondpage

List<Person>secondPage=livingPersons.nextPage().list();

Range

PanacheQuery<Person>livingPersons=Person

.find("status",Status.Alive);

List<Person>secondRange=livingPersons.range(25,49).list

();

You cannot mix pagination and range

Ifentitiesarede�ned inexternalJAR,youneedtoenable in theseprojectstheJandex plugininproject.

<plugin>

<groupId>org.jboss.jandex</groupId>

<artifactId>jandex-maven-plugin</artifactId>

<version>1.0.3</version>

<executions>

<execution>

<id>make-index</id>

<goals>

<goal>jandex</goal>

</goals>

</execution>

</executions>

<dependencies>

<dependency>

<groupId>org.jboss</groupId>

<artifactId>jandex</artifactId>

<version>2.1.1.Final</version>

</dependency>

</dependencies>

</plugin>

Panache includes an annotation processor that enhance yourentities. If you disable annotation processors you might need tocreate a marker �le on Panache archives at META-INF/panache-

archive.marker manually.

Testing

Tomockusingactiverecordpattern:

<dependency>

<groupId>io.quarkus</groupId>

<artifactId>quarkus-panache-mock</artifactId>

<scope>test</scope>

</dependency>

@TestpublicvoidtestPanacheMocking(){PanacheMock.mock(Person.class);

Mockito.when(Person.count()).thenReturn(23l);

Assertions.assertEquals(23,Person.count());

PanacheMock.verify(Person.class,Mockito.times(1)).coun

t();

}

DevServices

WhentestingorrunningindevmodeQuarkuscanevenprovideyouwith a zero con�g database out of the box. Depending on yourdatabase type youmay needdocker installed in order to use thisfeature.

Thefollowingopensourcedatabases:

Postgresql (container)

Page 14: Quarkus Cheat-Sheet

MySQL(container)

MariaDB(container)

H2(in-process)

ApacheDerby(in-process)

TouseDevServicesdon’tcon�gureadatabaseURL,usernameandpassword,Quarkuswillprovidethedatabaseandyoucanjuststartcodingwithoutworryingaboutcon�g.

quarkus.datasource.db-kind=mariadb%prod.quarkus.datasource.jdbc.url=jdbc:mariadb://db:3306/mydb

%prod.quarkus.datasource.username=developer%prod.quarkus.datasource.password=developer

Possiblecon�gurationvaluespre�xedwithquarkus.datasource :

devservices

Ifdevservicesisenabledornot.(default:true )

devservices.image-name

Thecontainerimagenametouseinsteadofthedefaultone.

devservices.properties

Generic properties that are added to the database connectionURL.

DAOpattern

AlsosupportsDAOpatternwithPanacheRepository<TYPE> .

@ApplicationScopedpublicclassDeveloperRepositoryimplementsPanacheRepository<Person>{publicPersonfindByName(Stringname){returnfind("name",name).firstResult();}

}

EntityManagerYoucaninjectEntityManager inyourclasses:

@InjectEntityManagerem;

@Injectorg.hibernate.Sessionsession;

@Injectorg.hibernate.SessionFactorysessionFactory;

em.persist(car);

Multipledatasources

Youcanregistermorethanonedatasource.

#default

quarkus.datasource.db-kind=h2quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:default

....

#usersdatasource

quarkus.datasource.users.devservices=falsequarkus.datasource.users.db-kind=h2quarkus.datasource.users.jdbc.url=jdbc:h2:tcp://localhost/mem:users

Notice that after datasource you set the datasource name, inpreviouscaseusers .

You can inject then AgroalDataSource withio.quarkus.agroal.DataSource .

@DataSource("users")AgroalDataSourcedataSource1;

Flushing

You can force �ush operation by calling .flush() or.persistAndFlush() tomakeitinasinglecall.

This �ush is less e�cient and you still need to committransaction.

Testing

There isaQuarkusTestResourcethatstartsandstopsH2serverbeforeandaftertestsuite.

Registerdependencyio.quarkus:quarkus-test-h2:test .

Andannotatethetest:

@QuarkusTestResource(H2DatabaseTestResource.class)publicclassFlywayTestResources{}

Transactions

Theeasiestwaytode�neyourtransactionboundariesistousethe@Transactional annotation.

Transactions are mandatory in case of none idempotentoperations.

@TransactionalpublicvoidcreateDeveloper(){}

Youcancontrolthetransactionscope:

@Transactional(REQUIRED) (default):startsatransactionifnonewasstarted,stayswiththeexistingoneotherwise.

@Transactional(REQUIRES_NEW) :startsatransactionifnonewasstarted;ifanexistingonewasstarted,suspendsitandstartsanewonefortheboundaryofthatmethod.

@Transactional(MANDATORY) :failsifnotransactionwasstarted;workswithintheexistingtransactionotherwise.

@Transactional(SUPPORTS) :ifatransactionwasstarted,joinsit;otherwiseworkswithnotransaction.

@Transactional(NOT_SUPPORTED) : if a transaction was started,suspendsitandworkswithnotransactionfortheboundaryofthemethod;otherwiseworkswithnotransaction.

@Transactional(NEVER) : if a transactionwas started, raises anexception;otherwiseworkswithnotransaction.

You can con�gure the default transaction timeout usingquarkus.transaction-manager.default-transaction-timeout

con�gurationproperty.Bydefaultitissetto60seconds.

You can set a timeout property, in seconds, that applies totransactions created within the annotated method by using@TransactionConfiguration annotation.

@Transactional@TransactionConfiguration(timeout=40)publicvoidcreateDeveloper(){}

If you want more control over transactions you can injectUserTransaction anduseaprogrammaticway.

@InjectUserTransactiontransaction

transaction.begin();

transaction.commit();

transaction.rollback();

You can implement your custom credentials provider (ie AzureKeyVault) to provide a username/password for the databaseconnection. Name information isnotnecessary if there isonlyonecustomcredentialprovider.

Page 15: Quarkus Cheat-Sheet

@ApplicationScoped@Unremovable@Named("my-credentials-provider")publicclassCustomCredentialsProviderimplementsCredentialsProvider{@InjectConfigconfig;

@Override publicPropertiesgetCredentials(StringcredentialsProviderName){

properties.put(CredentialsProvider.USER_PROPERTY_NA

ME,"hibernate_orm_test");

properties.put(CredentialsProvider.PASSWORD

_PROPERTY_NAME,"hibernate_orm_test");

}

}

quarkus.datasource.credentials-provider=custom

quarkus.datasource.credentials-provider-name=my-credentials-provider

HibernateMultitenancy

Multitenancy is supported using Schema or Database approach.Firstyouneedtode�nehowtenantisidenti�ed:

@RequestScoped@UnremovablepublicclassCustomTenantResolverimplementsTenantResolver{

@InjectRoutingContextcontext;

@OverridepublicStringgetDefaultTenantId(){return"base";}

@OverridepublicStringresolveTenantId(){}

}

Schemaapproach

quarkus.hibernate-orm.database.generation=none

quarkus.hibernate-orm.multitenant=SCHEMA

Databaseapproach

quarkus.hibernate-orm.database.generation=none

quarkus.hibernate-orm.multitenant=DATABASE

#defaulttenant

quarkus.datasource.base.db-kind=postgresqlquarkus.datasource.base.username=quarkus_test...

#Tenant'mycompany'

quarkus.datasource.mycompany.db-kind=postgresqlquarkus.datasource.mycompany.username=mycompanyquarkus.flyway.mycompany.locations=classpath:database/mycompany

...

Ifyouneedmoredynamicapproachimplement: @ApplicationScopedio.quarkus.hibernate.orm.runtime.tenant.TenantConnectionResolver

HibernateEnvers

QuarkussupportsHibernateEnvers.

./mvnwquarkus:add-extension

-Dextensions="hibernate-envers"

RESTDataPanache

RESTDatawith Panache extension can generate the basic CRUDendpointsforyourentitiesandrepositories.

./mvnwquarkus:add-extension

-Dextensions="hibernate-orm-rest-data-panache"

You also need to add the JDBC driver extension and a JSONMarshaller(ieresteasy-jackson ).

Thenyoucande�neinterfacesforde�ningendpoints:

IncaseofActiveRecordpattern:

publicinterfaceDeveloperResourceextendsPanacheEntityResource<Developer,Long>{}

IncaseofRepository:

publicinterfaceDeveloperResourceextendsPanacheRepositoryResource<DeveloperRepository,Developer,Long>{}

Quarkus will generate automatically the implementation for youfollowingthenextrules:

Default path is a hyphenated lowercase resource namewithout a su�x of or

get(@PathParam("id")) , list , add(Developer) ,update(@PathParam("id"),Developer) ,delete(@PathParam("id"))

Youcancustomizethesedefaultsbyusing@ResourceProperties and@MethodProperties annotations.

@ResourceProperties(hal=true,path="my-developer",halCollectionName="dev-collections")

publicinterfaceDeveloperResourceextendsPanacheEntityResource<Developer,Long>{@MethodProperties(path="all")List<Developer>list();@MethodProperties(exposed=false)voiddelete(Longid);}

If hal is true , you need to send the Accept:application/hal+jsonHTTPheadertogettheresponse.

HibernateReactive

./mvnwquarkus:add-extension

-Dextensions="quarkus-hibernate-reactive,quarkus-resteas

y-mutiny,"

Also you need to add the reactive driver (ie quarkus-reactive-pg-client ).

You can use: org.hibernate.reactive.mutiny.Mutiny ororg.hibernate.reactive.stage.Stage .

@Entity@Table(name="dev")publicclassDeveloper{}

@InjectCompletionStage<Stage.Session>stageSession;

@InjectUni<Mutiny.Session>mutinySession;

publicUni<Long>reactivePersist(){returnmutinySession.flatMap(s->s.persist(newDeveloper(1,"Alex")).flatMap(v->session.flush())

....

}

publicCompletionStage<Developer>reactiveFind(){returnstageSession.thenCompose(session->{

session.find(Developer.class,1);

});

}

In�nispan

Page 16: Quarkus Cheat-Sheet

QuarkusintegrateswithIn�nispan:

./mvnwquarkus:add-extension

-Dextensions="infinispan-client"

SerializationusesalibrarycalledProtostream.

Annotationbased

@ProtoFactorypublicAuthor(Stringname,Stringsurname){this.name=name;this.surname=surname;}

@ProtoField(number=1)publicStringgetName(){returnname;}

@ProtoField(number=2)publicStringgetSurname(){returnsurname;}

Initializertosetcon�gurationsettings.

@AutoProtoSchemaBuilder(includeClasses={Book.class,Author.class},

schemaPackageName="book_sample")

interfaceBookContextInitializerextendsSerializationContextInitializer{}

Userwrittenbased

Therearethreewaystocreateyourschema:

Proto�le

Createsa.proto �leintheMETA-INF directory.

packagebook_sample;

messageAuthor{

requiredstringname=1;

requiredstringsurname=2;

}

IncaseofhavingaCollection�eldyouneedtousetherepeated key(ierepeatedAuthorauthors=4 ).

Incode

Settingproto schemadirectlyinaproducedbean.

@ProducesFileDescriptorSourcebookProtoDefinition(){returnFileDescriptorSource.fromString("library.proto",

"packagebook_sample;\n"+

"messageAuthor{\n"+

"requiredstringname=1;\n"+

"requiredstringsurname=2;\n"+

"}");

}

Marshaller

Usingorg.infinispan.protostream.MessageMarshaller interface.

publicclassAuthorMarshallerimplementsMessageMarshaller<Author>{

@OverridepublicStringgetTypeName(){return"book_sample.Author";}

@OverridepublicClass<?extendsAuthor>getJavaClass(){returnAuthor.class;}

@OverridepublicvoidwriteTo(ProtoStreamWriterwriter,Authorauthor)throwsIOException{writer.writeString("name",author.getName());

writer.writeString("surname",author.getSurname());

}

@OverridepublicAuthorreadFrom(ProtoStreamReaderreader)throwsIOException{Stringname=reader.readString("name");

Stringsurname=reader.readString("surname");

returnnewAuthor(name,surname);}

}

Andproducingthemarshaller:

@ProducesMessageMarshallerauthorMarshaller(){returnnewAuthorMarshaller();}

In�nispanEmbedded

./mvnwquarkus:add-extension

-Dextensions="infinispan-embeddedy"

Con�gurationininfinispan.xml :

<local-cachename="quarkus-transaction">

<transaction

transaction-manager-lookup=

"org.infinispan.transaction.lookup.JBossStandaloneJ

TAManagerLookup"/>

</local-cache>

Setcon�guration�lelocationinapplication.properties :

quarkus.infinispan-embedded.xml-config=infinispan.xml

Andyoucaninjectthemainentrypointforthecache:

@Injectorg.infinispan.manager.EmbeddedCacheManagercacheManager;

Redis

QuarkusintegrateswithRedis.

./mvnwquarkus:add-extension

-Dextensions="redis-client"

Con�gureRedislocation:

quarkus.redis.hosts=localhost:6379

Youcanusesynchronousorreactiveclients:

@InjectRedisClientredisClient;

@InjectReactiveRedisClientreactiveRedisClient;

Page 17: Quarkus Cheat-Sheet

voidincrement(Stringkey,IntegerincrementBy){redisClient.incrby(key,incrementBy.toString());

}

Uni<List<String>>keys(){

returnreactiveRedisClient.keys("*")

.map(response->{

List<String>result=newArrayList<>();for(Responser:response){result.add(r.toString());

}

returnresult;});

}

MultipleRedisClients

quarkus.redis.hosts=localhost:6379quarkus.redis.second.hosts=localhost:6379

@InjectRedisClientdefaultRedisClient;

@Inject@RedisClientName("second")RedisClientredisClient2;

ListofRedisparameters.

quarkus.redis aspre�xisskippedinthenexttable.

health.enabled

Healthcheck ispublished incase thesmallrye-healthextensionispresent.(default:true )

password

TheRedispassword.

hosts

TheRedishosts.(default:localhost:6379 )

database

TheRedisdatabase.

timeout

Themaximumdelaytowaitbeforeablockingcommandtoredisservertimesout.(default:10s )

ssl

EnablesordisablestheSSLonconnect.

clinet-type

The Redis client type. Possible values: standalone , cluster ,sentinel (default:standalone )

Flyway

Quarkus integrateswith Flyway to help you on database schemamigrations.

./mvnwquarkus:add-extension

-Dextensions="quarkus-flyway"

Then place migration �les to the migrations folder(classpath:db/migration ).

You can inject org.flywaydb.core.Flyway to programmaticallyexecutethemigration.

@InjectFlywayflyway;

flyway.migrate();

Or can be automatically executed by setting migrate-at-start

propertytotrue .

quarkus.flyway.migrate-at-start=true

ListofFlywayparameters.

quarkus.flyway aspre�xisskippedinthenexttable.

clean-at-start

ExecuteFlywaycleancommand(default:false )

migrate-at-start

Flywaymigrationautomatically(default:false )

locations

CSV locations to scan recursively for migrations. Supportedpre�xes classpath and filesystem (default:classpath:db/migration ).

connect-retries

The maximum number of retries when attempting to connect(default:0)

schemas

CSVcase-sensitivelistofschemasmanaged(default:none)

table

The name of Flyway’s schema history table (default:flyway_schema_history )

out-of-order

Allowsmigrationstoberun"outoforder".

ignore-missing-migrations

Ignoremissingmigrationswhenreadingthehistorytable.

sql-migration-prefix

Pre�xforversionedSQLmigrations(default:V )

repeatable-sql-migration-prefix:: Pre�x for repeatable SQLmigrations(default:R )

baseline-on-migrate

Onlymigrationsabovebaseline-versionwillthenbeapplied

baseline-version

Versiontotaganexistingschemawithwhenexecutingbaseline(default:1)

baseline-description

Description to tag an existing schema with when executingbaseline(default:FlywayBaseline )

validate-on-migrate

Validate the applied migrations against the available ones(default:true )

placeholder-prefix

Pre�xofeveryplaceholder(default:${ )

placeholder-suffix

Su�xofeveryplaceholder(default:} )

callbacks

Comma-separated listoffullyquali�edclassnamesofCallbackimplementations.

ignore-future-migrations

Ignorefuturemigrationswhenreadingthehistorytable.

MultipleDatasources

To use multiple datasource in Flyway you just need to add thedatasourcenamejustaftertheflyway property:

quarkus.datasource.users.jdbc.url=jdbc:h2:tcp://localhost/mem:users

quarkus.datasource.inventory.jdbc.url=jdbc:h2:tcp://localhost/mem:inventory

#...

quarkus.flyway.users.schemas=USERS_TEST_SCHEMAquarkus.flyway.inventory.schemas=INVENTORY_TEST_SCHEMA#...

Liquibase

QuarkusintegrateswithLiquibasetohelpyouondatabaseschemamigrations.

./mvnwquarkus:add-extension

-Dextensions="quarkus-liquibase"

Page 18: Quarkus Cheat-Sheet

Thenplacechangelog�lestothe(src/main/resources/db )folder.

You can inject org.quarkus.liquibase.LiquibaseFactory toprogrammaticallyexecutethemigration.

@InjectLiquibaseFactoryliquibaseFactory;

try(Liquibaseliquibase=liquibaseFactory.createLiquibase()){

...

}

Or can be automatically executed by setting migrate-at-start

propertytotrue .

quarkus.liquibase.migrate-at-start=true

ListofLiquibaseparameters.

quarkus.liquibase aspre�xisskippedinthenexttable.

change-logThe change log �le. XML , YAML , JSON , SQL formats supported.(default:db/changeLog.xml )

change-log-parameters."<parameter-name>"Liquibasechangelogparameters.

migrate-at-startThemigrateatstart�ag.(default:false )

validate-on-migrateThevalidateonupdate�ag.(default:false )

clean-at-startThecleanatstart�ag.(default:false )

contextsThelistofcontexts.

labelsThelistoflabels.

database-change-log-table-nameThe database change log lock table name. (default:DATABASECHANGELOG )

database-change-log-lock-table-nameThe database change log lock table name. (default:DATABASECHANGELOGLOCK )

default-catalog-nameThedefaultcatalogname.

default-schema-nameThe default schema name

liquibase-catalog-nameTheliquibasetablescatalogname.

liquibase-schema-nameTheliquibasetablesschemaname.

liquibase-tablespace-nameTheliquibasetablestablespacename.

MultipleDatasources

Tousemultiple datasource in Liquibase you just need to add thedatasourcenamejustaftertheliquibase property:

quarkus.datasource.users.jdbc.url=jdbc:h2:tcp://localhost/mem:users

quarkus.datasource.inventory.jdbc.url=jdbc:h2:tcp://localhost/mem:inventory

#...

quarkus.liquibase.users.schemas=USERS_TEST_SCHEMAquarkus.liquibase.inventory.schemas=INVENTORY_TEST_SCHEMA#...

HibernateSearch

QuarkusintegrateswithElasticsearchtoprovideafull-featuredfull-textsearchusingHibernateSearchAPI.

./mvnwquarkus:add-extension

-Dextensions="quarkus-hibernate-search-elasticsearch"

You need to annotate your model with Hibernate Search API toindexit:

@Entity@IndexedpublicclassAuthorextendsPanacheEntity{

@FullTextField(analyzer="english")publicStringbio;

@FullTextField(analyzer="name")@KeywordField(name="firstName_sort",sortable=Sortable.YES,

normalizer="sort")

publicStringfirstName;

@OneToMany@IndexedEmbeddedpublicList<Book>books;

}

ItisnotmandatorytousePanache.

You need to de�ne the analyzers and normalizers de�ned inannotations. You only need to implementElasticsearchAnalysisConfigurer interfaceandcon�gureit.

publicclassMyQuarkusAnalysisConfigurerimplementsElasticsearchAnalysisConfigurer{

@Overridepublicvoidconfigure(ElasticsearchAnalysisDefinitionContainerContextct

x)

{

ctx.analyzer("english").custom()

.withTokenizer("standard")

.withTokenFilters("asciifolding",

"lowercase","porter_stem");

ctx.normalizer("sort").custom()

.withTokenFilters("asciifolding","lowercase");

}

}

UseHibernateSearchinRESTservice:

publicclassLibraryResource{

@InjectEntityManagerem;

@TransactionalpublicList<Author>searchAuthors(@QueryParam("pattern")Stringpattern){

returnSearch.getSearchSession(em).search(Author.class)

.predicate(f->

pattern==null||pattern.isEmpty()?f.matchAll():

f.simpleQueryString()

.onFields("firstName",

"lastName","books.title")

.matching(pattern)

)

.sort(f->f.byField("lastName_sort")

.then().byField("firstName_sort"))

.fetchHits();

}

When not using Hibernate ORM, index data usingSearch.getSearchSession(em).createIndexer()

.startAndWait() atstartuptime.

Con�guretheextensioninapplication.properties :

Page 19: Quarkus Cheat-Sheet

quarkus.hibernate-search.elasticsearch.version=7quarkus.hibernate-search.elasticsearch.

analysis-configurer=MyQuarkusAnalysisConfigurerquarkus.hibernate-search.elasticsearch.

automatic-indexing.synchronization-strategy=searchablequarkus.hibernate-search.elasticsearch.

index-defaults.lifecycle.strategy=drop-and-createquarkus.hibernate-search.elasticsearch.

index-defaults.lifecycle.required-status=yellow

List of Hibernate-Elasticsearch properties pre�xed withquarkus.hibernate-search.elasticsearch :

backends

Mapofcon�gurationofadditionalbackends.

version

VersionofElasticsearch

analysis-configurer

Classornameoftheneabusedtocon�gure.

hosts

ListofElasticsearchservershosts.

username

Usernameforauth.

password

Passwordforauth.

connection-timeout

Durationofconnectiontimeout.

max-connections

Maxnumberofconnectionstoservers.

max-connections-per-route

Maxnumberofconnectionstoserver.

indexes

Per-indexspeci�ccon�guration.

discovery.enabled

Enablesautomaticdiscovery.

discovery.refresh-interval

Refreshintervalofnodelist.

discovery.default-scheme

Schemetobeusedforthenewnodes.

automatic-indexing.synchronization-strategy

Status for which you wait before considering the operationcompleted(queued ,committed orsearchable ).

automatic-indexing.enable-dirty-check

When enabled, re-indexing of is skipped if the changes are onpropertiesthatarenotusedwhenindexing.

index-defaults.lifecycle.strategy

Index lifecycle (none , validate , update , create , drop-and-create ,drop-abd-create-drop )

index-defaults.lifecycle.required-status

Minimalclusterstatus(green ,yellow ,red )

index-defaults.lifecycle.required-status-wait-timeout

Waitingtimebeforefailingthebootstrap.

index-defaults.refresh-after-write

Setifindexshouldberefreshedafterwrites.

Possibleannotations:

@Indexed

Registerentityasfulltextindex

@FullTextField

Fulltextsearch.Needtosetananalyzertosplittokens.

@KeywordField

Thestringiskeptasonesingletokenbutcanbenormalized.

IndexedEmbedded

IncludetheBook�eldsintotheAuthorindex.

@ContainerExtraction

Setshowtoextractavaluefromcontainer,e.gfromaMap .

@DocumentId

Mapanunusualentityidenti�ertoadocumentidenti�er.

@GenericField

Fulltextindexforanysupportedtype.

@IdentifierBridgeRef

Referencetotheidenti�erbridgetousefora@DocumentId .

@IndexingDependency

Howadependencyoftheindexingprocesstoapropertyshouldaffectautomaticreindexing.

@ObjectPath

@ScaledNumberField

For java.math.BigDecimal or java.math.BigInteger that you needhigherprecision.

AmazonDynamoDB

Quarkusintegrateswithhttps://aws.amazon.com/dynamodb/:

./mvnwquarkus:add-extension

-Dextensions="quarkus-amazon-dynamodb"

@InjectDynamoDbClientdynamoDB;

TouseasycnhronousclientwithMutiny:

./mvnwquarkus:add-extension

-Dextensions="quarkus-amazon-dynamodb,resteasy-mutiny"

@InjectDynamoDbAsyncClientdynamoDB;

Uni.createFrom().completionStage(() -> dynamoDB.scan(scanRe

quest()))....

TouseitasalocalDynamoDBinstance:

quarkus.dynamodb.region=eu-central-1

quarkus.dynamodb.endpoint-override=http://localhost:8000

quarkus.dynamodb.credentials.type=STATICquarkus.dynamodb.credentials.static-provider

.access-key-id=test-keyquarkus.dynamodb.credentials.static-provider

.secret-access-key=test-secret

IfyouwanttoworkwithanAWSaccount,you’dneedtosetitwith:

quarkus.dynamodb.region=<YOUR_REGION>

quarkus.dynamodb.credentials.type=DEFAULT

DEFAULT credentialsproviderchain:

Systempropertiesaws.accessKeyId ,aws.secretKey

Env.VarablesAWS_ACCESS_KEY_ID ,AWS_SECRET_ACCESS_KEY

Credentialspro�le~/.aws/credentials

Credentials through theAmazonEC2container service if theAWS_CONTAINER_CREDENTIALS_RELATIVE_URI set

CredentialsthroughAmazonEC2metadataservice.

Con�gurationparameterspre�xedwithquarkus.dynamodb :

Parameter Default Description

enable-endpoint-

discoveryfalse

Endpoint discoveryforaserviceAPI thatsupports endpointdiscovery.

Page 20: Quarkus Cheat-Sheet

endpoint-override Con�gure theendpoint with whichthe SDK shouldcommunicate.

api-call-timeoutTime to complete anexecution.

interceptorsList of classinterceptors.

Con�gurationparameterspre�xedwithquarkus.dynamodb.aws :

Parameter Default Description

regionRegion that hostsDynamoDB.

credentials.type DEFAULT

Credentials thatshould be usedDEFAULT , STATIC ,SYSTEM_PROPERTY ,ENV_VARIABLE ,PROFILE , CONTAINER ,INSTANCE_PROFILE ,PROCESS ,ANONYMOUS

Credentials speci�c parameters pre�xed withquarkus.dynamodb.aws.credentials :

Parameter Default Description

DEFAULT

default-

provider.async-

credential-update-

enabled

falseShould fetchcredentialsasync.

default-

provider.reuse-last-

provider-enabled

true

Should reuse the lastsuccessfulcredentials.

STATIC

static-

provider.access-key-

id

AWSaccesskeyid.

static-

provider.secret-

access-key

AWS secret accesskey.

Parameter Default Description

PROFILE

profile-

provider.profile-namedefault

The name of thepro�letouse.

PROCESS

process-

provider.command

Commandtoexecuteto retrievecredentials.

process-

provider.process-

output-limit

1024 Max bytes to retrievefromprocess.

process-

provider.credential-

refresh-threshold

PT15S

The amount of timebetween credentialsexpire andcredentialsrefreshed.

process-

provider.async-

credential-update-

enabled

falseShould fetchcredentialsasync.

In case of synchronous client, the next parameters can becon�guredpre�xedbyquarkus.dynamodb.sync-client :

Parameter Default Description

connection-

acquisition-timeout10S

Connectionacquisationtimeout.

connection-max-idle-

time60S

Max time toconnection to beopened.

connection-timeout Connectiontimeout.

connection-time-to-

live0

Max time connectiontobeopen.

socket-timeout 30S Timetowaitfordata.

max-connections 50 Maxconnections.

expect-continue-

enabledtrue

Client send an HTTPexpect-continue

handsake.

Parameter Default Description

use-idle-connection-

reapertrue

Connections in poolshould be closedasynchronously.

proxy.endpointEndpointoftheproxyserver.

proxy.enabled false EnablesHTTPproxy.

proxy.username Proxyusername.

proxy.password Proxypassword.

proxy.ntlm-domainFor NTLM, domainname.

proxy.ntlm-

workstation

For NTLM,workstationname.

proxy.preemptive-

basic-authentication-

enabled

Authenticate pre-emptively.

proxy.non-proxy-

hosts

List of non proxyhosts.

tls-managers-

provider.typesystem-property

TLS manager: none ,system-property ,file-store

tls-managers-

provider.file-

store.path

Pathtokeystore.

tls-managers-

provider.file-

store.type

Keystoretype.

tls-managers-

provider.file-

store.password

Keystorepassword.

In case of asynchronous client, the next parameters can becon�guredpre�xedbyquarkus.dynamodb.async-client :

Parameter Default Description

connection-

acquisition-timeout10S

Connectionacquisationtimeout.

Page 21: Quarkus Cheat-Sheet

Parameter Default Description

connection-max-idle-

time60S

Max time toconnection to beopened.

connection-timeout Connectiontimeout.

connection-time-to-

live0

Max time connectiontobeopen.

max-concurrency 50

Max number ofconcurrentconnections.

use-idle-connection-

reapertrue

Connections in poolshould be closedasynchronously.

read-timeout 30S Readtimeout.

write-timeout 30S Writetimeout.

proxy.endpointEndpointoftheproxyserver.

proxy.enabled false EnablesHTTPproxy.

proxy.non-proxy-

hosts

List of non proxyhosts.

tls-managers-

provider.typesystem-property

TLS manager: none ,system-property ,file-store

tls-managers-

provider.file-

store.path

Pathtokeystore.

tls-managers-

provider.file-

store.type

Keystoretype.

tls-managers-

provider.file-

store.password

Keystorepassword.

ssl-provider

SSL Provider (jdk ,openssl , openssl-

refcnt ).

Parameter Default Description

protocol HTTP_1_1Sets the HTTPprotocol.

max-http2-streamsMax number ofconcurrentstreams.

event-loop.override falseEnable custom eventloopconf.

event-loop.number-of-

threads

Numberofthreadstouseineventloop.

event-loop.thread-

name-prefix

aws-java-sdk-

NettyEventLoop

Pre�x of threadnames.

AmazonS3

./mvnwquarkus:add-extension

-Dextensions="quarkus-amazon-s3"

@InjectS3Clients3Client;

YouneedtosetaHTTPclienteitherURLConnection :

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>url-connection-client</artifactId>

</dependency>

orApacheHTTP:

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>apache-client</artifactId>

</dependency>

quarkus.s3.sync-client.type=apache

Andcon�gureit:

quarkus.s3.endpoint-override=http://localhost:8008quarkus.s3.interceptors=io.quarkus.it.amazon.s3.S3ModifyResponse

quarkus.s3.aws.region=us-east-1quarkus.s3.aws.credentials.type=staticquarkus.s3.aws.credentials.static-provider.access-key-id=test-key

quarkus.s3.aws.credentials.static-provider.secret-access-key=test-secret

Youcaninjectasynchronousclienttoo:

@InjectS3AsyncClients3AsyncClient;

AndyouneedtoaddtheasynchronousNettyclient:

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>netty-nio-client</artifactId>

</dependency>

Con�gurationpropertiesare thesameasAmazonDynamoDB butchangingthepre�xfromdynamodb tos3 .

Neo4j

QuarkusintegrateswithNeo4j:

./mvnwquarkus:add-extension

-Dextensions="quarkus-neo4j"

@Injectorg.neo4j.driver.Driverdriver;

Con�gurationproperties:

quarkus.neo4j aspre�xisskippedinthenexttable.

Pre�xisquarkus.neo4j .

uri

URIofNeo4j.(default:localhost:7687 )

authentication.username

Username.(default:neo4j )

authentication.password

Password.(default:neo4j )

authentication.disabled

Disableauthentication.(default:false )

Page 22: Quarkus Cheat-Sheet

Enablemetrics.(default:false )

pool.log-leaked-sessions

Enableleakedsessionslogging.(default:`false`)

pool.max-connection-pool-size

Maxamountofconnections.(default:100 )

pool.max-connection-lifetime

Pooled connections olderwill be closed and removed from thepool.(default:1H )

pool.connection-acquisition-timeout

Timoutforconnectionadquisation.(default:1M)

pool.idle-time-before-connection-test

Pooledconnectionsidledinthepoolforlongerthanthistimeoutwillbetestedbeforetheyareused.(default:-1 )

As Neo4j uses SSL communication by default, to create a nativeexecutableyouneedtocompilewithnextoptionsGraalVMoptions:

-H:EnableURLProtocols=http,https --enable-all-security-services -

H:+JNI

AndQuarkusMavenPluginwithnextcon�guration:

<artifactId>quarkus-maven-plugin</artifactId>

<executions>

<execution>

<id>native-image</id>

<goals>

<goal>native-image</goal>

</goals>

<configuration>

<enableHttpUrlHandler>true

</enableHttpUrlHandler>

<enableHttpsUrlHandler>true

</enableHttpsUrlHandler>

<enableAllSecurityServices>true

</enableAllSecurityServices>

<enableJni>true</enableJni>

</configuration>

</execution>

</executions>

Alternatively, and as a not recommended way in production, youcan disable SSL and Quarkus will disable Bolt SSL as well.quarkus.ssl.native=false .

IfyouareusingNeo4j4.0,youcanusefullyreactive.Addthenextextension:quarkus-resteasy-mutiny .

@GETpublicPublisher<String>get(){returnMulti.createFrom().resource(driver::rxSession,session->session.readTransaction(tx->{

RxResultresult=tx.run("MATCH(f:Fruit)RETUR

Nf.nameasname");

returnMulti.createFrom().publisher(result.records())

.map(record->record.get("name").asStr

ing());

})

).withFinalizer(session->{

returnUni.createFrom().publisher(session.close());});

}

MongoDBClient

QuarkusintegrateswithMongoDB:

./mvnwquarkus:add-extension

-Dextensions="quarkus-mongodb-client"

@Injectcom.mongodb.client.MongoClientclient;

@Injectio.quarkus.mongodb.reactive.ReactiveMongoClientclient;

INFO:ReactiveclientusesexposesMutinyAPI.

quarkus.mongodb.connection-string=mongodb://localhost:27018quarkus.mongodb.write-concern.journal=false

MultiMongoDBsupport

Youcancon�guremultipleMongoDBclientsusingsameapproachaswith DataSource .Thesyntax is quarkus.mongodb.<optionalname>.<property> :

quarkus.mongodb.users.connection-string = mongodb://mongo2:27017/userdb

quarkus.mongodb.inventory.connection-string = mongodb://mongo3:27017/invdb

Inject the instance [email protected] annotation:

@Inject@MongoClientName("users")MongoClientmongoClient1;

quarkus.mongodb aspre�xisskippedinthefollowingtable.

Parameter Type Description

connection-string StringMongoDBconnectionURI.

hosts List<String>Addressespassedashost:port .

application-name String Applicationname.

max-pool-size IntMaximum number ofconnections.

min-pool-size IntMinimum number ofconnections.

max-connection-idle-

timeDuration

Idle time of a pooledconnection.

max-connection-life-

timeDuration

Life time of pooledconnection.

wait-queue-timeout DurationMaximum wait timefornewconnection.

maintenance-

frequencyDuration

Time period betweenruns of maintenancejob.

maintenance-initial-

delayDuration

Time to wait beforerunning the �rstmaintenancejob.

wait-queue-multiple Int

Multiplied with max-

pool-size gives maxnumer of threadswaiting.

connection-timeout Duration

socket-timeout Duration

tls-insecure boolean[false] InsecureTLS.

tls boolean[false] EnableTLS

Page 23: Quarkus Cheat-Sheet

Parameter Type Description

replica-set-name StringImplies hosts givenareaseedlist.

server-selection-

timeoutDuration

Time to wait forserverselection.

local-threshold Duration

Minimum ping timeto make a servereligible.

heartbeat-frequency Duration

Frequency todetermine the stateofservers.

read-preference

primary ,primaryPreferred ,secondary ,secondaryPreferred ,nearest

Readpreferences.

max-wait-queue-size Int

Max number ofconcurrentoperationsallowedtowait.

write-concern.safe boolean[true]Ensures are writesareack.

write-

concern.journalboolean[true]

Journal writingaspect.

write-concern.w StringValue to all writecommands.

write-concern.retry-

writesboolean[false]

Retry writes ifnetworkfails.

write-concern.w-

timeoutDuration

Timeout to all writecommands.

credentials.username String Username.

credentials.password String Password.

credentials.auth-

mechanism

MONGO-CR , GSSAPI ,PLAIN ,MONGODB-X509

Parameter Type Description

credentials.auth-

sourceString

Source of theauthenticationcredentials.

credentials.auth-

mechanism-propertiesMap<String,String>

Authenticationmechanismproperties.

MongoDBPanache

YoucanalsousethePanacheframeworktowritepersistencepartwhenusingMongoDB.

./mvnwquarkus:add-extension

-Dextensions="mongodb-panache"

MongoDBcon�gurationcomesfromMongoDBClientsection.

@MongoEntity(collection="ThePerson")publicclassPersonextendsPanacheMongoEntity{publicStringname;

@BsonProperty("birth")publicLocalDatebirthDate;

publicStatusstatus;}

Possible annotations in �elds: @BsonId (for custom ID),@BsonProperty and@BsonIgnore .

@MongoEntity isoptional.

Multi-tenancywithMongoDBPanache

@MongoEntity(collection="TheBook",clientName="client2",database="database2")

Methods provided are similar of the ones shown in Persistencesection.

person.persist();

person.update();

person.delete();

List<Person>allPersons=Person.listAll();

person=Person.findById(personId);

List<Person>livingPersons=Person.list("status",Status.A

live);

List<Person>persons=Person.list(Sort.by("name").and("bir

th"));

longupdated=Person.update("name","Mortal").where("status",Status.Alive);

longcountAll=Person.count();

Person.deleteById(id);

Person.delete("status",Status.Alive);

Alllist methodshaveequivalentstream versions.

Pagination

Youcanalsousepagination:

PanacheQuery<Person>livingPersons=

Person.find("status",Status.Alive);

livingPersons.page(Page.ofSize(25));

//getthefirstpage

List<Person>firstPage=livingPersons.list();

//getthesecondpage

List<Person>secondPage=livingPersons.nextPage().list();

Range

PanacheQuery<Person>livingPersons=Person

.find("status",Status.Alive);

List<Person>secondRange=livingPersons.range(25,49).list

();

Youcannotmixpaginationandrange.

Queries

Native MongoDB queries are supported (if they start with { ororg.bson.Document instance) aswell asPanacheQueries.PanacheQueriesequivalenceinMongoDB:

firstname=?1andstatus=?2 → {'firstname':?1,'status':?2}

amount > ?1 and firstname != ?2 → {'amount': {'$gt': ?1},'firstname':{'$ne':?2}}

lastnamelike?1 →{'lastname':{'$regex':?1}}

lastnameisnotnull →{'lastname':{'$exists':true}}

Page 24: Quarkus Cheat-Sheet

PanacheQLreferstotheObjectparameternamebutnativequeriesrefertoMongoDB�eldnames.

Projection

ProjectioncanbedoneforbothPanacheQLandnativequeries.

importio.quarkus.mongodb.panache.ProjectionFor;

@ProjectionFor(Person.class)(1)publicclassPersonName{publicStringname;}

PanacheQuery<PersonName>shortQuery=Person.find("status"

,Status.Alive).project(PersonName.class);

1 Entityclass.

Testing

Tomockusingactiverecordpattern:

<dependency>

<groupId>io.quarkus</groupId>

<artifactId>quarkus-panache-mock</artifactId>

<scope>test</scope>

</dependency>

@TestpublicvoidtestPanacheMocking(){PanacheMock.mock(Person.class);

Mockito.when(Person.count()).thenReturn(23l);

Assertions.assertEquals(23,Person.count());

PanacheMock.verify(Person.class,Mockito.times(1)).coun

t();

}

DAOpattern

@ApplicationScopedpublicclassPersonRepositoryimplementsPanacheMongoRepository<Person>{}

Jandex

Ifentitiesarede�ned inexternalJAR,youneedtoenable in theseprojectstheJandex plugininproject.

<plugin>

<groupId>org.jboss.jandex</groupId>

<artifactId>jandex-maven-plugin</artifactId>

<version>1.0.3</version>

<executions>

<execution>

<id>make-index</id>

<goals>

<goal>jandex</goal>

</goals>

</execution>

</executions>

<dependencies>

<dependency>

<groupId>org.jboss</groupId>

<artifactId>jandex</artifactId>

<version>2.1.1.Final</version>

</dependency>

</dependencies>

</plugin>

Panache includes an annotation processor that enhance yourentities. If you disable annotation processors you might need tocreate a marker �le on Panache archives at META-INF/panache-

archive.marker manually.

ReactivePanache

MongoDBwithPanacheallowsusing reactive implementation tooby using ReactivePanacheMongoEntity orReactivePanacheMongoEntityBase or ReactivePanacheMongoRepository

orReactivePanacheMongoRepositoryBase dependingonyourstyle.

publicclassReactivePersonextendsReactivePanacheMongoEntity{publicStringname;}

CompletionStage<Void>cs1=person.persist();

CompletionStage<List<ReactivePerson>>allPersons=Reactive

Person.listAll();

Publisher<ReactivePerson>allPersons=ReactivePerson.strea

mAll();

Uni<List<PersonName>> persons = ReactivePersonEntity.find(

"lastname",name).project(PersonName.class).list();

MongoDBRESTDataPanache

MongoDB REST Data with Panache extension can generate thebasicCRUDendpointsforyourentitiesandrepositories.

./mvnwquarkus:add-extension

-Dextensions="mongodb-rest-data-panache"

You also need to add the JDBC driver extension and a JSONMarshaller(ieresteasy-jackson ).

Thenyoucande�neinterfacesforde�ningendpoints:

IncaseofActiveRecordpattern:

publicinterfaceDeveloperResourceextendsPanacheMongoEntityResource<Developer,Long>{}

IncaseofRepository:

publicinterfaceDeveloperResourceextendsPanacheMongoRepositoryResource<DeveloperRepository,Developer,Long>{}

Cassandra

QuarkusintegrateswithCassandraandDataStaxObjectMapper.

<dependency>

<groupId>com.datastax.oss.quarkus</groupId>

<artifactId>cassandra-quarkus-client</artifactId>

</dependency>

Enities and DAOs are generated as you have been doing withDataStaxObjectMapper.

YouneedtocreateaDaoProducer:

@InjectpublicFruitDaoProducer(QuarkusCqlSessionsession){FruitMappermapper=newFruitMapperBuilder(session).build();

fruitDao=mapper.fruitDao();

}

@Produces@ApplicationScopedFruitDaoproduceFruitDao(){returnfruitDao;}

Cassandracon�guration:

quarkus.cassandra.contact-points=127.0.0.1:9042quarkus.cassandra.local-datacenter=datacenter1quarkus.cassandra.keyspace=k1quarkus.cassandra.auth.username=johnquarkus.cassandra.auth.password=s3cr3t

You can con�gure other Cassandra Java driver settings usingapplication.conf or application.json �les.Theyneedtobelocatedintheclasspathofyourapplication.Driversettingsreference.

If MicroPro�le Metrics extension is registered, the Cassandraextension can provide (if enabled) metrics about the session:

Page 25: Quarkus Cheat-Sheet

quarkus.cassandra.metrics.enabled=truequarkus.cassandra.metrics.session-enabled=connected-nodes,bytes-sent

quarkus.cassandra.metrics.node-enabled=pool.open-connections

Reactive

YoucanalsouseMutinytode�neareactiveDAO:

@DaopublicinterfaceFruitDaoReactive{

@UpdateUni<Void>update(Fruitfruit);

@SelectMutinyMappedReactiveResultSet<Fruit>findById(StringstoreId);

}

@MapperpublicinterfaceFruitMapper{

@DaoFactoryFruitDaoReactivefruitDaoReactive();}

ReactiveProgramming

QuarkusimplementsMicroPro�leReactivespecandusesRXJava2toprovidereactiveprogrammingmodel.

./mvnwquarkus:add-extension

-Dextensions="quarkus-smallrye-reactive-streams-operator

s"

Asynchronous HTTP endpoint is implemented by returning JavaCompletionStage .YoucancreatethisclasseithermanuallyorusingMicroPro�leReactiveStreamsspec:

@GET@Path("/reactive")@Produces(MediaType.TEXT_PLAIN)publicCompletionStage<String>getHello(){returnReactiveStreams.of("h","e","l","l","o").map(String::toUpperCase)

.toList()

.run()

.thenApply(list->list.toString());

}

Creating streams is also easy, you just need to return Publisherobject.

@GET@Path("/stream")@Produces(MediaType.SERVER_SENT_EVENTS)publicPublisher<String>publishers(){returnFlowable.interval(500,TimeUnit.MILLISECONDS)

.map(s->atomicInteger.getAndIncrement())

.map(i->Integer.toString(i));

}

MutinyandJAX-RS

Apart from the CompletionStage support, there is also support forMutiny.

./mvnwquarkus:add-extension

-Dextensions="quarkus-resteasy-mutiny"

@GET@Produces(MediaType.TEXT_PLAIN)publicUni<String>hello(){returnUni.createFrom().item(()->"hello");}

@GET@Produces(MediaType.TEXT_PLAIN)publicMulti<String>multi(){returnMulti.createFrom().items("hello","world");}

Mutiny

QuarkusintegrateswithMutinyasreactiveprogramminglibrary:

./mvnwquarkus:add-extension

-Dextensions="mutiny"

@ApplicationScopedpublicstaticclassReactiveHello{

publicUni<String>greeting(){returnUni.createFrom().item(()->"hello").emitOn(Infrastructure.getDefaultExecutor

());

}

publicMulti<String>stream(){returnMulti.createFrom().items("hello","world").emitOn(Infrastructure.getDefaultExecutor

());

}

}

Convertingfrom/toRxJava2 orReactor APIs:

RxJava2

<dependency>

<groupId>io.smallrye.reactive</groupId>

<artifactId>mutiny-rxjava</artifactId>

</dependency>

FromRxJava2 :

Page 26: Quarkus Cheat-Sheet

Uni<Void>uniFromCompletable=Uni.createFrom()

.converter(UniRxConvert

ers.fromCompletable(),completable);

Uni<String>uniFromSingle=Uni.createFrom()

.converter(UniRxConverters.

fromSingle(),single);

Uni<String>uniFromObservable=Uni.createFrom()

.converter(UniRxConverters.

fromObservable(),observable);

Uni<String>uniFromFlowable=Uni.createFrom()

.converter(UniRxConverters.

fromFlowable(),flowable);

...

Multi<Void>multiFromCompletable=Multi.createFrom()

.converter(MultiRxC

onverters.fromCompletable(),completable);

Multi<String>multiFromObservable=Multi.createFrom()

.converter(MultiRxC

onverters.fromObservable(),observable);

Multi<String>multiFromFlowable=Multi.createFrom()

.converter(MultiRxC

onverters.fromFlowable(),flowable);

...

ToRxJava2 :

Completablecompletable=uni.convert().with(UniRxConverter

s.toCompletable());

Single<Optional<String>>single=uni.convert().with(UniRxC

onverters.toSingle());

Observable<String>observable=uni.convert().with(UniRxCon

verters.toObservable());

Flowable<String>flowable=uni.convert().with(UniRxConvert

ers.toFlowable());

...

Completablecompletable=multi.convert().with(MultiRxConve

rters.toCompletable());

Single<Optional<String>>single=multi.convert().with(Mult

iRxConverters.toSingle());

Observable<String>observable=multi.convert().with(MultiR

xConverters.toObservable());

Flowable<String>flowable=multi.convert().with(MultiRxCon

verters.toFlowable());

...

ReactorAPI

<dependency>

<groupId>io.smallrye.reactive</groupId>

<artifactId>mutiny-reactor</artifactId>

</dependency>

FromReactor :

Uni<String>uniFromMono=Uni.createFrom().converter(UniRea

ctorConverters.fromMono(),mono);

Uni<String>uniFromFlux=Uni.createFrom().converter(UniRea

ctorConverters.fromFlux(),flux);

Multi<String> multiFromMono = Multi.createFrom().converter

(MultiReactorConverters.fromMono(),mono);

Multi<String> multiFromFlux = Multi.createFrom().converter

(MultiReactorConverters.fromFlux(),flux);

ToReactor :

Mono<String> mono = uni.convert().with(UniReactorConverter

s.toMono());

Flux<String> flux = uni.convert().with(UniReactorConverter

s.toFlux());

Mono<String>mono2=multi.convert().with(MultiReactorConve

rters.toMono());

Flux<String>flux2=multi.convert().with(MultiReactorConve

rters.toFlux());

CompletionStagesorPublisher

CompletableFuture<String>future=Uni

.createFrom().completionStage(CompletableFuture.sup

plyAsync(()->"hello"));

CompletationStage<String>cs=Uni

.createFrom().subscribeAsCompletionStage();

Multi implementsPublisher .

RESTEasyReactive

RESTEasy Reactive is a new implementation of JAX-RS but fullyreactive.

mvnquarkus:add-extension

-Dextensions="quarkus-resteasy-reactive"

packageorg.acme.rest;importjavax.ws.rs.GET;importjavax.ws.rs.Path;@Path("rest")publicclassEndpoint{

@Path("hello")@GETpublicStringhello(){//executedinevent-loop

return"Hello,World!";}

@GETpublicUni<Book>culinaryGuide(){//executedinevent-loopbutnotblocking

returnBook.findByIsbn("978-2081229297");}

@io.smallrye.common.annotation.Blocking@GETpublicStringblockingHello()throwsInterruptedException{

//executedinworker-thread

return"Yaaaawwwwnnnnnn…";}

}

ReactiveMessaging

Quarkus relies on MicroPro�le Reactive Messaging spec toimplementreactivemessagingstreams.

mvnquarkus:add-extension

-Dextensions="

io.quarkus:quarkus-smallrye-reactive-messaging"

Youcan juststartusing in-memorystreamsbyusing @Incoming toproducedataand@Outgoing toconsumedata.

Produceevery5secondsonepieceofdata.

@ApplicationScopedpublicclassProducerData{

@Outgoing("my-in-memory")publicFlowable<Integer>generate(){returnFlowable.interval(5,TimeUnit.SECONDS).map(tick->random.nextInt(100));

}

}

orinMutiny:

Page 27: Quarkus Cheat-Sheet

@ApplicationScopedpublicclassProducerData{@Outgoing("my-in-memory")publicMulti<Integer>generate(){returnMulti.createFrom().ticks().every(Duration.ofSeconds(5))

.onItem().apply(n->random.nextInt(100));

}

}

If you want to dispatch to all subscribers you can annotate themethodwith@Broadcast .

Consumesgenerateddatafrommy-in-memory stream.

@ApplicationScopedpublicclassConsumerData{@Incoming("my-in-memory")publicvoidrandomNumber(intrandomNumber){System.out.println("Received"+randomNumber);

}

}

Youcanalsoinjectanstreamasa�eld:

@Inject@Stream("my-in-memory")Publisher<Integer>randomRumbers;

@Inject@Stream("generated-price")Emitter<String>emitter;

Patterns

RESTAPI→Message

@Inject@Stream(“in”)Emitter<String>emitter;

emitter.send(message);

Message→Message

@Incoming(“in”)@Outgoing(“out”)publicStringprocess(Stringin){}

Message→SSE

@Inject@Stream(“out”)Publisher<String>result;

@GET@Produces(SERVER_SENT_EVENTS)publicPublisher<String>stream(){returnresult;}

Message→BusinessLogic

@ApplicationScopedpublicclassReceiverMessages{@Incoming("prices")publicvoidprint(Stringprice){}

}

To indicate that themethodshouldbeexecutedonaworkerpoolyoucanuse@Blocking :

@Outgoing("Y")@Incoming("X")@Blocking

Tocustomize:

@Blocking(value="my-custom-pool",ordered=false)

smallrye.messaging.worker.my-custom-pool.max-concurrency=3

Possibleimplementationsare:

In-Memory

If the stream is not con�gured then it is assumed to be an in-memory stream, if not then stream type is de�ned by connector�eld.

Kafka

TointegratewithKafkayouneedtoaddnextextensions:

mvnquarkus:add-extension

-Dextensions="

io.quarkus:quarkus-smallrye-reactive-messaging-kafka"

Then@Outgoing ,@Incoming or@Stream canbeused.

Kafka con�guration schema: mp.messaging.[outgoing|incoming].

{stream-name}.<property>=<value> .

Theconnector typeissmallrye-kafka .

mp.messaging.outgoing.generated-price.connector=smallrye-kafka

mp.messaging.outgoing.generated-price.topic=prices

mp.messaging.outgoing.generated-price.bootstrap.servers=localhost:9092mp.messaging.outgoing.generated-price.value.serializer=org.apache.kafka.common.serialization.IntegerSerializer

mp.messaging.incoming.prices.connector=smallrye-kafka

mp.messaging.incoming.prices.value.deserializer=org.apache.kafka.common.serialization.IntegerDeserializ

er

A complete list of supported properties are in Kafka site. For theproducerandforconsumer

JSON-BSerializer/Deserializer

YoucanuseJSON-Btoserialize/deserializeobjects.

./mvnwquarkus:add-extension

-Dextensions="quarkus-kafka-client"

To serialize you can useio.quarkus.kafka.client.serialization.JsonbSerializer .

To deserialize you need to extendio.quarkus.kafka.client.serialization.JsonbDeserializer andprovideatype.

publicclassBeerDeserializerextendsJsonbDeserializer<Beer>{

publicBeerDeserializer(){super(Beer.class);}

}

AMQP

TointegratewithAMQPyouneedtoaddnextextensions:

./mvnwquarkus:add-extension

-Dextensions="reactive-messaging-amqp"

Then@Outgoing ,@Incoming or@Stream canbeused.

AMQP con�guration schema: mp.messaging.[outgoing|incoming].

{stream-name}.<property>=<value> . Special properties amqp-usernameandamqp-password areusedtocon�gureAMQPbrokercredentials.

Theconnectortypeissmallrye-amqp .

Page 28: Quarkus Cheat-Sheet

amqp-username=quarkusamqp-password=quarkus#write

mp.messaging.outgoing.generated-price.connector=smallrye-amqp

mp.messaging.outgoing.generated-price.address=prices

mp.messaging.outgoing.generated-price.durable=true

#read

mp.messaging.incoming.prices.connector=smallrye-amqp

mp.messaging.incoming.prices.durable=true

AcompletelistofsupportedpropertiesforAMQP.

MQTT

TointegratewithMQTTyouneedtoaddnextextensions:

./mvnwquarkus:add-extension

-Dextensions="vertx,smallrye-reactive-streams-operator

s

smallrye-reactive-messaging"

And add io.smallrye.reactive:smallrye-reactive-messaging-mqtt-

1.0:0.0.10 dependencyinyourbuildtool.

Then@Outgoing ,@Incoming or@Stream canbeused.

MQTT con�guration schema: mp.messaging.[outgoing|incoming].

{stream-name}.<property>=<value> .

Theconnectortypeissmallrye-mqtt .

mp.messaging.outgoing.topic-price.type=smallrye-mqtt

mp.messaging.outgoing.topic-price.topic=prices

mp.messaging.outgoing.topic-price.host=localhost

mp.messaging.outgoing.topic-price.port=1883

mp.messaging.outgoing.topic-price.auto-generated-client-id=true

mp.messaging.incoming.prices.type=smallrye-mqtt

mp.messaging.incoming.prices.topic=prices

mp.messaging.incoming.prices.host=localhost

mp.messaging.incoming.prices.port=1883

mp.messaging.incoming.prices.auto-generated-client-id=true

KafkaStreams

CreatestreamingquerieswiththeKafkaStreamsAPI.

./mvnwquarkus:add-extension

-Dextensions="kafka-streams"

All we need to do for that is to declare a CDI producer methodwhich returns the Kafka Streamsorg.apache.kafka.streams.Topology :

@ApplicationScopedpublicclassTopologyProducer{@ProducespublicTopologybuildTopology(){org.apache.kafka.streams.StreamsBuilder.StreamsBuil

der

builder=newStreamsBuilder();//...

builder.stream()

.join()

//...

.toStream()

.to();

returnbuilder.build();}

}

Previousexampleproducescontenttoanotherstream.Ifyouwanttowriteinteractivequeries,youcanuseKafkastreams.

@InjectKafkaStreamsstreams;

returnstreams.store("stream",QueryableStoreTypes.keyValueStore

());

The Kafka Streams extension is con�gured via the Quarkuscon�guration�leapplication.properties .

quarkus.kafka-streams.bootstrap-servers=localhost:9092quarkus.kafka-streams.application-id=temperature-aggregatorquarkus.kafka-streams.application-server=${hostname}:8080quarkus.kafka-streams.topics=weather-stations,temperature-values

kafka-streams.cache.max.bytes.buffering=10240kafka-streams.commit.interval.ms=1000

IMPORTANT: All the properties within the kafka-streams

namespacearepassedthroughas-istotheKafkaStreamsengine.Changingtheirvaluesrequiresarebuildoftheapplication.

ReactiveDataSourceProperties

Common Reeactive DataSource Client con�guration propertiespre�xedwithquarkus.datasource :

reactive.cache-prepared-statements

Prepared statements should be cached on the client side.(default:false )

reactive.url

ThedatasourceURL.

reactive.max-size

Thedatasourcepoolmaximumsize.

reactive.trust-all

Allservercerti�catesshouldbetrusted.(default:false )

reactive.trust-certificate-pem

Trustcon�gurationinthePEMformat.

reactive.trust-certificate-jks

Trustcon�gurationintheJKSformat.

reactive.trust-certificate-pfx

Trustcon�gurationinthePFXformat.

reactive.key-certificate-pem

Key/certcon�gurationinthePEMformat.

reactive.key-certificate-jks

Key/certcon�gurationintheJKSformat.

reactive.key-certificate-pfx

Key/certcon�gurationinthePFXformat.

reactive.thread-local

Useoneconnectionpoolperthread.

reactive.reconnect-attempts

Thenumberofreconnectionattemptswhenapooledconnectioncannotbeestablishedon�rsttry.(default:0 )

reactive.reconnect-interval

The interval between reconnection attempts when a pooledconnectioncannotbeestablishedon�rsttry.(default:PT1S )

reactive.idle-timeout

The maximum time without data written to or read from aconnectionbeforeitisremovedfromthepool.

ReactivePostgreSQLClient

YoucanuseReactivePostgreSQLtoexecutequeriestoPostreSQLdatabaseinareactiveway,insteadofusingJDBCway.

./mvnwquarkus:add-extension

-Dextensions="quarkus-reactive-pg-client"

Page 29: Quarkus Cheat-Sheet

Database con�guration is the same as shown in Persistencesection,butURLisdifferentasitisnotajdbc.

quarkus.datasource.db-kind=postgresqlquarkus.datasource.reactive.url=postgresql:///your_database

Thenyoucaninjectio.vertx.mutiny.pgclient.PgPool class.

@InjectPgPoolclient;

Uni<List<Fruit>>fruits=

client.preparedQuery("SELECT*FROMfruits")

.onItem().apply(rowSet->{

JsonArrayjsonArray=newJsonArray();for(Rowrow:rowSet){jsonArray.add(from(row));

}

returnjsonArray;})

ReactiveMySQLClient

You can use Reactive MySQL to execute queries to MySQLdatabaseinareactiveway,insteadofusingJDBC.

./mvnwquarkus:add-extension

-Dextensions="quarkus-reactive-mysql-client"

Database con�guration is the same as shown in Persistencesection,butURLisdifferentasitisnotajdbc.

quarkus.datasource.db-kind=mysqlquarkus.datasource.reactive.url=mysql:///your_database

Thenyoucaninjectio.vertx.mutiny.mysqlclient.MySQLPool class.

ReactiveDB2Client

YoucanuseReactiveDB2toexecutequeriestoDB2databaseinareactiveway,insteadofusingJDBC.

./mvnwquarkus:add-extension

-Dextensions="quarkus-reactive-db2-client"

Database con�guration is the same as shown in Persistencesection,butURLisdifferentasitisnotajdbc.

quarkus.datasource.db-kind=db2quarkus.datasource.reactive.url=vertx-reactive:db2://localhost:50005/hreact

Then you can inject i i db2 li 2 l class

ReactiveTransactions

io.vertx.mutiny.sqlclient.SqlClientHelper is an util class thatallowsyoutorunreactivepersistencodewithinatransaction.

Uni<Void>r=SqlClientHelper.inTransactionUni(client,tx-

>{

Uni<RowSet<Row>>insertOne=tx.preparedQuery("INSE

RTINTOfruits(name)VALUES($1)RETURNING(id)")

.execute(Tuple.of(fruit1.name));

});

ActiveMQArtemis

Quarkus uses Reactive Messaging to integrate with messagingsystems,but incaseyouneeddeepercontrolwhenusingApacheActiveMQArtemisthereisalsoanextension:

./mvnwquarkus:add-extension

-Dextensions="quarkus-artemis-core"

And then you can injectorg.apache.activemq.artemis.api.core.client.ServerLocator

instance.

@ApplicationScopedpublicclassArtemisConsumerManager{

@InjectServerLocatorserverLocator;

privateClientSessionFactoryconnection;

@PostConstructpublicvoidinit()throwsException{connection=serverLocator.createSessionFactory();

}

}

Andcon�gureServerLocator inapplication.properties :

quarkus.artemis.url=tcp://localhost:61616

Youcancon�gureActiveMQArtemis in application.properties �lebyusingnextpropertiespre�xedwithquarkus :

artemis.url

ConnectionURL.

artemis.username

Usernameforauthentication.

artemis.password

Passwordforauthentication.

ArtemisJMS

If you want to use JMS with Artemis, you can do it by using itsextension:

./mvnwquarkus:add-extension

-Dextensions="quarkus-artemis-jms"

Andthenyoucaninjectjavax.jms.ConnectionFactory :

@ApplicationScopedpublicclassArtemisConsumerManager{

@InjectConnectionFactoryconnectionFactory;

privateConnectionconnection;

@PostConstructpublicvoidinit()throwsJMSException{connection=connectionFactory.createConnection();

connection.start();

}

}

Con�gurationoptionsarethesameasArtemiscore.

Vert.XReactiveClients

Vert.X Reactive clients in Quarkus, the next clients are supportedandyouneedtoaddthedependencytousethem:

Vert.XMailClientio.smallrye.reactive:smallrye-mutiny-vertx-mail-client

Vert.XMongoDBClientio.smallrye.reactive:smallrye-mutiny-vertx-mongo-client

Vert.XRedisClientio.smallrye.reactive:smallrye-mutiny-vertx-redis-client

Vert.XCassandraClientio.smallrye.reactive:smallrye-mutiny-vertx-cassandra-client

Vert.XConsulClientio.smallrye.reactive:smallrye-mutiny-vertx-consul-client

Vert.XKafkaClientio.smallrye.reactive:smallrye-mutiny-vertx-kafka-client

Vert.XAMQPClientio.smallrye.reactive:smallrye-mutiny-vertx-amqp-client

Vert.XRabbitMQClientio.smallrye.reactive:smallrye-mutiny-vertx-rabbitmq-client

Page 30: Quarkus Cheat-Sheet

ExampleofVert.XWebClient:

@InjectVertxvertx;

privateWebClientclient;

@PostConstructvoidinitialize(){this.client=WebClient.create(vertx,...);}

AmazonSQSClient

./mvnwquarkus:add-extension

-Dextensions="amazon-sqs"

Injectingtheclient:

@Injectsoftware.amazon.awssdk.services.sqs.SqsClientsqs;

SendMessageResponseresponse=sqs.sendMessage(m->m.queue

Url(queueUrl).messageBody(message));

List<Message>messages=sqs.receiveMessage(m->m.maxNumbe

rOfMessages(10).queueUrl(queueUrl)).messages();

Andcon�gureit:

quarkus.sqs.endpoint-override=http://localhost:8010quarkus.sqs.aws.region=us-east-1quarkus.sqs.aws.credentials.type=staticquarkus.sqs.aws.credentials.static-provider.access-key-id=test-key

quarkus.sqs.aws.credentials.static-provider.secret-access-key=test-secret

YouneedtosetaHTTPclienteitherURLConnection :

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>url-connection-client</artifactId>

</dependency>

orApacheHTTP:

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>apache-client</artifactId>

</dependency>

quarkus.sqs.sync-client.type=apache

YoucangoasyncbyusingMutiny:

@Injectsoftware.amazon.awssdk.services.sqs.SqsAsyncClientsqs;

Uni.createFrom()

.completionStage(

sqs.sendMessage(m->m.queueUrl(queueUrl).messageBo

dy(message))

)

.onItem()...

returnUni.createFrom().completionStage(

sqs.receiveMessage(m->m.maxNumberOfMessages(10).q

ueueUrl(queueUrl))

)

.onItem()

AndyouneedtoaddtheasynchronousNettyclient:

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>netty-nio-client</artifactId>

</dependency>

Con�gurationpropertiesare thesameasAmazonDynamoDB butchangingthepre�xfromdynamodb tosqs .

TLS

You can trust all certi�cates globally by using quarkus.tls.trust-all=true

RBAC

YoucansetRBACusingannotationsorinapplication.properties .

Annotations

You can de�ne roles by usingjavax.annotation.security.RolesAllowed annotation.

@RolesAllowed("Subscriber")

You can use io.quarkus.security.Authenticated as a shortcut of@RolesAllowed("*") .

ToalterRBACbehaviourtherearetwocon�gurationproperties:

quarkus.security.deny-unannotated=true

Con�gurationoptions:

quarkus.jaxrs.deny-uncovered

IftruedeniesbydefaulttoallJAX-RSendpoints.(default:false )

quarkus.security.deny-unannotated

IftruedeniesbydefaultallCDImethodsandJAX-RSendpoints.(default:false )

Bydefault inQuarkus, ifan incoming requesthasacredential therequestwillalwaysbeauthenticated(even if thetargetpagedoesnotrequireauthentication).

You can change this behaviour by settingquarkus.http.auth.proactive propertytofalse .

FileCon�guration

De�ning RBAC in application.properties instead of usingannotations.

Page 31: Quarkus Cheat-Sheet

quarkus.http.auth.policy.role-policy1.roles-allowed=user,admin

quarkus.http.auth.permission.roles1.paths=/roles-secured/*,/other/*,/api/*

quarkus.http.auth.permission.roles1.policy=role-policy1

quarkus.http.auth.permission.permit1.paths=/public/*

quarkus.http.auth.permission.permit1.policy=permit

quarkus.http.auth.permission.permit1.methods=GET

quarkus.http.auth.permission.deny1.paths=/forbidden

quarkus.http.auth.permission.deny1.policy=deny

You need to provide permissions set by using the roles-allowedpropertyorusethebuilt-inonesdeny ,permit orauthenticated .

You can use enabled property (iequarkus.http.auth.permission.permit1.enabled ) to enable the entirepermissionset.

Testing

Quarkus provides explicit support for testingwith different users,andwiththesecuritysubsystemdisabled.

<dependency>

<groupId>io.quarkus</groupId>

<artifactId>quarkus-test-security</artifactId>

<scope>test</scope>

</dependency>

@Test@TestSecurity(authorizationEnabled=false)voidsomeTestMethod(){...

}

@Test@TestSecurity(user="testUser",roles={"admin","user"})voidsomeTestMethod(){...

}

BouncyCastle

Quarkus supports BouncyCastle, you only need to add theBouncyCastledependencyandcon�gurethesecurityprovider:

quarkus.security.security-providers=BCquarkus.security.security-providers=BCJSSEquarkus.security.security-providers=BCFIPSquarkus.security.security-providers=BCFIPSJSSE

JWT

QuarkusimplementsMicroPro�leJWTRBACspec.

mvnquarkus:add-extension

-Dextensions="io.quarkus:quarkus-smallrye-jwt"

Minimum JWT required claims: typ , alg , kid , iss , sub , exp , iat ,jti ,upn ,groups .

YoucaninjecttokenbyusingJsonWebToken oraclaimindividuallybyusing@Claim .

@InjectJsonWebTokenjwt;

@Inject@Claim(standard=Claims.preferred_username)Stringname;

@Inject@Claim("groups")Set<String>groups;

@InjectJWTParserparser;

Set of supported types: String , Set<String> , Long , Boolean,

`javax.json.JsonValue , Optional ,org.eclipse.microprofile.jwt.ClaimValue .

Andcon�gurationinsrc/main/resources/application.properties :

mp.jwt.verify.publickey.location=META-INF/resources/publicKey.pem

mp.jwt.verify.issuer=https://quarkus.io/using-jwt-rbac

Con�gurationoptions:

mp.jwt.verify.publickey

PublicKeytextitselftobesuppliedasastring.

mp.jwt.verify.publickey.location Relative path or URL of a publickey.

mp.jwt.verify.issuer

iss acceptedasvalid.

smallrye.jwt.token.header

Setsheadersuchas Cookie isused topass the token. (default:Authorization ).

smallrye.jwt.token.cookie

Nameofthecookiecontainingatoken.

smallrye.jwt.token.schemes

Comma-separatedlistcontaininganalternativesingleormultipleschemes.(default:Bearer ).

smallrye.jwt.require.named-principal

Atokenmusthaveaupnorpreferred_usernameorsubclaimsetifusing java.security.Principal . True makesthrowanexceptionifnotset.(default:false ).

smallrye.jwt.path.sub

Pathtotheclaimwithsubjectname.

smallrye.jwt.claims.sub

Defaultsubclaimvalue.

smallrye.jwt.path.groups

Pathtotheclaimcontainingthegroups.

smallrye.jwt.groups-separator

Separatorforsplittingastringwhichmaycontainmultiplegroupvalues.(default.``).

smallrye.jwt.claims.groups

Defaultgroupsclaimvalue.

smallrye.jwt.jwks.refresh-interval

JWKcacherefreshintervalinminutes.(default:60 ).

smallrye.jwt.expiration.grace

Expirationgraceinseconds.(default:60 ).

smallrye.jwt.verify.aud

Comma separated list of the audiences that a token aud claimmaycontain.

smallrye.jwt.verify.algorithm

Signaturealgorith.(defsult:RS256 )

smallrye.jwt.token.kid

Ifsetthentheveri�cationJWKkeyaswelleveryJWTtokenmusthaveamatchingkid header.

smallrye.jwt.time-to-live

ThemaximumnumberofsecondsthataJWTmaybeissuedforuse.

smallrye.jwt.sign.key-location

Locationof a private keywhichwill be used to sign the claimswhen either a no-argument sign() or innerSign() method iscalled.

smallrye.jwt.encrypt.key-location

Page 32: Quarkus Cheat-Sheet

LocationofapublickeywhichwillbeusedtoencrypttheclaimsorinnerJWTwhenano-argumentencrypt() methodiscalled.

Supportedpublickeyformats:

PKCS#8PEM

JWK

JWKS

JWKBase64URL

JWKSBase64URL

To send a token to server-side you should use Authorization

header:curl-H"Authorization:BearereyJraWQiOi…" .

To inject claim values, the bean must be @RequestScoped CDIscoped. Ifyouneedto injectclaimvalues inscopewitha lifetimegreater than @RequestScoped then you need to usejavax.enterprise.inject.Instance interface.

@Inject@Claim(standard=Claims.iat)privateInstance<Long>providerIAT;

RBAC

JWTgroups claimisdirectlymappedtorolestobeusedinsecurityannotations.

@RolesAllowed("Subscriber")

Generatetokens

JWTgenerationAPI:

Jwt.claims()

.issuer("https://server.com")

.claim("customClaim",3)

.sign(createKey());

JwtSignatureBuilderjwtSignatureBuilder=Jwt.claims("/test

JsonToken.json").jws();

jwtSignatureBuilder

.signatureKeyId("some-key-id")

.signatureAlgorithm(SignatureAlgorithm.ES256)

.header("custom-header","custom-value");

.sign(createKey());

Jwt.claims("/testJsonToken.json")

.encrypt(createKey());

JwtEncryptionBuilderjwtEncryptionBuilder=Jwt.claims("/te

stJsonToken.json").jwe();

jwtEncryptionBuilder

.keyEncryptionKeyId("some-key-id")

.keyEncryptionAlgorithm(KeyEncryptionAlgorithm.ECDH_E

S_A256KW)

.header("custom-header","custom-value");

.encrypt(createKey());

Jwt.claims("/testJsonToken.json")

.innerSign(createKey());

.encrypt(createKey());

OpenIdConnect

Quarkus can use OpenId Connect or OAuth 2.0 authorizationserverssuchasKeycloak toprotect resourcesusingbearer tokenissuedbyKeycloakserver.

mvnquarkus:add-extension

-Dextensions="using-openid-connect"

Youcanalsoprotectresourceswithsecurityannotations.

@GET@RolesAllowed("admin")

Con�gureapplicationtoKeycloakservicein application.properties�le.

quarkus.oidc.realm=quarkusquarkus.oidc.auth-server-url=http://localhost:8180/authquarkus.oidc.resource=backend-servicequarkus.oidc.bearer-only=truequarkus.oidc.credentials.secret=secret

Con�gurationoptionswithquarkus.oidc pre�x:

enabled

The OIDC is enabled. (default: true )

tenant-enabled

Ifthetenantcon�gurationisenabled.(default:true )

application-type

Theapplicationtype.Possiblevalues: web_app , service . (default:service )

connection-delay

Themaximumamountoftimetheadapterwilltryconnecting.

auth-server-url

ThebaseURLoftheOpenIDConnect(OIDC)server.

introspection-path

RelativepathoftheRFC7662introspectionservice.

jwks-path

RelativepathoftheOIDCservicereturningaJWKset.

public-key

PublickeyforthelocalJWTtokenveri�cation

client-id

Theclient-idoftheapplication.

roles.role-claim-path

Pathtotheclaimcontaininganarrayofgroups.(realm/groups )

roles.role-claim-separator

Separatorforsplittingastringwhichmaycontainmultiplegroupvalues.

token.issuer

Issuerclaimvalue.

token.audience

Audienceclaimvalue.

token.expiration-grace

Expirationgraceperiodinseconds.

token.principal-claim

Nameoftheclaimwhichcontainsaprincipalname.

token.refresh-expired

Ifpropertyisenabledthenarefreshtokenrequestisperformed.

credentials.secret

Theclientsecret

authentication.redirect-path

Relativepathforcalculatingaredirect_uri queryparameter.

authentication.restore-path-after-redirect

The original request URI used before the authenticationwill berestored after the user has been redirected back to theapplication.(default:true )

Page 33: Quarkus Cheat-Sheet

authentication.scopes

Listofscopes.

authentication.extra-params

Additional properties which will be added as the queryparameters.

authentication.cookie-path

Cookiepathparameter.

proxy.host

Thehost(nameorIPaddress)oftheProxy.

proxy.port

TheportnumberoftheProxy.(default:80 )

proxy.username

Theusernametoauthenticate.

proxy.password

Thepasswordtoauthenticate.

end-session-path

RelativepathoftheOIDCend_session_endpoint .

logout.path

Therelativepathofthelogoutendpointattheapplication.

logout.post-logout-path

Relativepathof theapplicationendpointwhere theusershouldberedirectedtoafterloggingout.

tls.verification

Sets the TLs veri�cation. Possible values: REQUIRED , NONE .(default:REQUIRED ).

With Keycloak OIDC serverhttps://host:port/auth/realms/{realm} where {realm} hastobereplacedbythenameoftheKeycloakrealm.You can use quarkus.http.cors property to enableconsumingformdifferentdomain.

Multi-tenancy

Multi-tenancy is supported by adding a sub-category to OIDCcon�gurationproperties(iequarkus.oidc.{tenent_id}.property ).

quarkus.oidc.auth-server-url=http://localhost:8180/auth/realms/quarkus

quarkus.oidc.client-id=multi-tenant-clientquarkus.oidc.application-type=web-app

quarkus.oidc.tenant-b.auth-server-url=https://accounts.google.com

quarkus.oidc.tenant-b.application-type=web-appquarkus.oidc.tenant-b.client-id=xxxxquarkus.oidc.tenant-b.credentials.secret=yyyyquarkus.oidc.tenant-b.token.issuer=https://accounts.google.com

quarkus.oidc.tenant-b.authentication.scopes=email,profile,openid

OAuth2

Quarkus integrates with OAuth2 to be used in case of opaquetokens (none JWT) and its validation against an introspectionendpoint.

mvnquarkus:add-extension

-Dextensions="security-oauth2"

Andcon�gurationinsrc/main/resources/application.properties :

quarkus.oauth2.client-id=client_idquarkus.oauth2.client-secret=secretquarkus.oauth2.introspection-url=http://oauth-server/introspect

Andyoucanmaprolestobeusedinsecurityannotations.

@RolesAllowed("Subscriber")

Con�gurationoptions:

quarkus.oauth2.enabled

DetermineiftheOAuth2extensionisenabled.(default:true )

quarkus.oauth2.client-id

TheOAuth2clientidusedtovalidatethetoken.

quarkus.oauth2.client-secret

TheOAuth2clientsecretusedtovalidatethetoken.

quarkus.oauth2.introspection-url

URL used to validate the token and gather the authenticationclaims.

quarkus.oauth2.role-claim

Theclaimthatisusedintheendpointresponsetoloadtheroles((default:scope )

AuthenticatingviaHTTP

HTTP basic auth is enabled by the quarkus.http.auth.basic=trueproperty.

HTTP form auth is enabled by thequarkus.http.auth.form.enabled=true property.

Thenyouneedtoadd elytron-security-properties-file or elytron-security-jdbc .

SecuritywithPropertiesFile

Youcanalsoprotectendpointsandstore identities(user, roles) inthe�lesystem.

mvnquarkus:add-extension

-Dextensions="elytron-security-properties-file"

Youneedtocon�guretheextensionwithusersandroles�les:

Andcon�gurationinsrc/main/resources/application.properties :

quarkus.security.users.file.enabled=truequarkus.security.users.file.users=test-users.propertiesquarkus.security.users.file.roles=test-roles.propertiesquarkus.security.users.file.auth-mechanism=BASICquarkus.security.users.file.realm-name=MyRealmquarkus.security.users.file.plain-text=true

Thenusers.properties androles.properties :

scott=jb0ssjdoe=p4ssw0rd

scott=Admin,admin,Tester,userjdoe=NoRolesUser

IMPORTANT: If plain-text is set to false (or omitted) thenpasswords must be stored in the form MD5(username :`realm`:`password`).

Elytron File Properties con�guration properties. Pre�xquarkus.security.users isskipped.

file.enabled

The�lerealmisenabled.(default:false )

file.auth-mechanism

Theauthenticationmechanism.(default:BASIC )

file.realm-name

Theauthenticationrealmname.(default:Quarkus )

file.plain-text

Page 34: Quarkus Cheat-Sheet

IfpasswordsareinplainorinMD5.(default:false )

file.users

Classpath resource of user/password. (default:users.properties )

file.roles

Classpathresourceofuser/role.(default:roles.properties )

EmbeddedRealm

You can embed user/password/role in the sameapplication.properties :

quarkus.security.users.embedded.enabled=truequarkus.security.users.embedded.plain-text=truequarkus.security.users.embedded.users.scott=jb0ssquarkus.security.users.embedded.roles.scott=admin,tester,user

quarkus.security.users.embedded.auth-mechanism=BASIC

IMPORTANT: If plain-text is set to false (or omitted) thenpasswords must be stored in the form MD5(username :`realm`:`password`).

Pre�xquarkus.security.users.embedded isskipped.

algorithm

Determine which algorithm to use. Possible values: DIGEST_MD5 ,DIGEST_SHA , DIGEST_SHA_256 , DIGEST_SHA_384 , DIGEST_SHA_512 ,DIGEST_SHA_512_256 .(default:DIGEST_MD5 )

file.enabled

The�lerealmisenabled.(default:false )

file.auth-mechanism

Theauthenticationmechanism.(default:BASIC )

file.realm-name

Theauthenticationrealmname.(default:Quarkus )

file.plain-text

IfpasswordsareinplainorinMD5.(default:false )

file.users.*

* isuserandvalueispassword.

file.roles.*

* isuserandvalueisrole.

SecuritywithaJDBCRealm

Youcanalsoprotectendpointsandstoreidentitiesinadatabase.

mvnquarkus:add-extension

-Dextensions="elytron-security-jdbc"

Youstillneedtoaddthedatabasedriver(iejdbc-h2 ).

Youneedtocon�gureJDBCandElytronJDBCRealm:

quarkus.datasource.url=quarkus.datasource.driver=org.h2.Driverquarkus.datasource.username=saquarkus.datasource.password=sa

quarkus.security.jdbc.enabled=truequarkus.security.jdbc.principal-query.sql=SELECTu.password,u.roleFROMtest_useruWHEREu.user=?

quarkus.security.jdbc.principal-query

.clear-password-mapper.enabled=truequarkus.security.jdbc.principal-query

.clear-password-mapper.password-index=1quarkus.security.jdbc.principal-query

.attribute-mappings.0.index=2quarkus.security.jdbc.principal-query

.attribute-mappings.0.to=groups

Youneedtosettheindex(1-based)ofpasswordandrole.

Elytron JDBC Realm con�guration properties. Pre�xquarkus.security.jdbc isskipped.

auth-mechanism

Theauthenticationmechanism.(default:BASIC )

realm-name

Theauthenticationrealmname.(default:Quarkus )

enabled

Ifthepropertiesstoreisenabled.(default:false )

principal-query.sql

Thesqlqueryto�ndthepassword.

principal-query.datasource

Thedatasourcetouse.

principal-query.clear-password-mapper.enabled

Iftheclear-password-mapperisenabled.(default:false )

principal-query.clear-password-mapper.password-index

Theindexofcolumncontainingclearpassword.(default:1 )

principal-query.bcrypt-password-mapper.enabled

Ifthebcrypt-password-mapperisenabled.(default:false )

principal-query.bcrypt-password-mapper.password-index

Theindexofcolumncontainingpasswordhash.(default:0 )

principal-query.bcrypt-password-mapper.hash-encoding

Astringreferencingthepasswordhashencoding(BASE64 or HEX ).(default:BASE64 )

principal-query.bcrypt-password-mapper.salt-index

TheindexcolumncontainingtheBcryptsalt.(default:0 )

principal-query.bcrypt-password-mapper.salt-encoding

A string referencing the salt encoding (BASE64 or HEX ). (default:BASE64 )

principal-query.bcrypt-password-mapper.iteration-count-index

TheindexcolumncontainingtheBcryptiterationcount.(default:0 )

Formultipledatasourcesyoucanusethedatasourcename in theproperties:

quarkus.datasource.url=quarkus.security.jdbc.principal-query.sql=

quarkus.datasource.permissions.url=quarkus.security.jdbc.principal-query.permissions.sql=

SecuritywithJPA

Youcanalsoprotectendpointsandstore identities inadatabaseusingJPA.

mvnquarkus:add-extension

-Dextensions="security-jpa"

Also you might require jdbc-postgresql , resteasy ,hibernate-orm-panache .

Page 35: Quarkus Cheat-Sheet

@io.quarkus.security.jpa.UserDefinition@Table(name="test_user")@EntitypublicclassUserextendsPanacheEntity{@io.quarkus.security.UsernamepublicStringname;

@io.quarkus.security.PasswordpublicStringpass;

@ManyToMany@RolespublicList<Role>roles=newArrayList<>();

publicstaticvoidadd(Stringusername,Stringpassword){

Useruser=newUser();user.username=username;

user.password=BcryptUtil.bcryptHash(password);

user.persist();

}

}

@EntitypublicclassRoleextendsPanacheEntity{

@ManyToMany(mappedBy="roles")publicList<ExternalRolesUserEntity>users;

@io.quarkus.security.RolesValuepublicStringrole;}

Youneedtocon�gureJDBC:

quarkus.datasource.url=jdbc:postgresql:security_jpaquarkus.datasource.driver=org.postgresql.Driverquarkus.datasource.username=quarkusquarkus.datasource.password=quarkus

quarkus.hibernate-orm.database.generation=drop-and-create

SecuritywithLDAP

Youcanalsoprotectendpointsandstore identities inadatabaseusingLDAP.

mvnquarkus:add-extension

-Dextensions="elytron-security-ldap"

quarkus.security.ldap.enabled=truequarkus.security.ldap.dir-context.principal=uid=tool,ou=accounts,o=YourCompany,c=DE

quarkus.security.ldap.dir-context.url=ldaps://ldap.server.local

quarkus.security.ldap.dir-context.password=PASSWORDquarkus.security.ldap.identity-mapping.rdn-identifier=uidquarkus.security.ldap.identity-mapping.search-base-dn=ou=users,ou=tool,o=YourCompany,c=DE

quarkus.security.ldap.identity-mapping.attribute-mappings."0".from=cnquarkus.security.ldap.identity-mapping.attribute-mappings."0".to=groupsquarkus.security.ldap.identity-mapping.attribute-mappings."0".filter=(member=uid={0})quarkus.security.ldap.identity-mapping.attribute-mappings."0".filter-base-dn=ou=roles,ou=tool,o=YourCompany,c=DE

Testing

ThereisaQuarkusTestResourcethatstartsandstopsInMemoryLDAPserver before andafter test suite. It is running in localhostwith dc=quarkus,dc=io and binding credentials("uid=admin,ou=system","secret" ). ImportsLDIF froma�le locatedatrootoftheclasspathnamedquarkus-io.ldif .

Registerdependencyio.quarkus:quarkus-test-ldap:test.

Andannotatethetest:

@QuarkusTestResource(io.quarkus.test.ldap.LdapServerTestResource.class)

publicclassElytronLdapExtensionTestResources{}

Elytron LDAP Realm con�guration properties. Pre�xquarkus.security.ldap isskipped.

enabled

EnabletheLDAPelytronmodule(default:false )

realm-name

Theelytronrealmname(default:Quarkus )

direct-verification

Providedcredentialsareveri�edagainstLDAP(default:true )

dir-context.url

TheurloftheLDAPserver.

dir-context.principal

User(bindDn )whichisusedtoconnecttoLDAPserver.

dir-context.password

Thepassword(bindCredential )whichbelongstotheprincipal.

identity-mapping.rdn-identifier

The identi�er (baseFilter )whichcorrelates to theprovideduser(default:uid )

identity-mapping.search-base-dn

Thednwherewelookforusers.

identity-mapping.attribute-mappings.<id>.from

TheroleAttributeId fromwhichismapped

identity-mapping.attribute-mappings.<id>.to

Theidenti�erwhomtheattributeismappedto(default:gropus )

identity-mapping.attribute-mappings.<id>.filter

The�lter(roleFilter )

identity-mapping.attribute-mappings.<id>.filter-base-dn

The�lterbasedn(rolesContextDn )

Vault

Quarkus integrates with Vault to manage secrets or protectingsensitivedata.

mvnquarkus:add-extension

-Dextensions="vault"

Andcon�guringVaultinapplication.properties :

#vaulturl

quarkus.vault.url=http://localhost:8200

quarkus.vault.authentication.userpass.username=bob

quarkus.vault.authentication.userpass.password=sinclair

#pathwithinthekvsecretengine

quarkus.vault.secret-config-kv-path=myapps/vault-quickstart/config

quarkus.vault.secret-config-kv-prefix.singer.paths=multi/singer1,multi/singer2

vault kv put secret/myapps/vault-quickstart/config a-private-

key=123456

vaultkvputsecret/multi/singer1firstname=paul

@ConfigProperty(name="a-private-key")StringprivateKey;

@ConfigProperty(name="singer.firstname")StringfirstName;

YoucanaccesstheKVengineprogrammatically:

Page 36: Quarkus Cheat-Sheet

@InjectVaultKVSecretEnginekvSecretEngine;

kvSecretEngine.readSecret("myapps/vault-quickstart/" + vaul

tPath).toString();

Map<String,String>secrets;

kvSecretEngine.writeSecret("myapps/vault-quickstart/crud",

secrets);

kvSecretEngine.deleteSecret("myapps/vault-quickstart/crud"

);

FetchingcredentialsDB

With the next kv vault kv put secret/myapps/vault-quickstart/dbpassword=connor

quarkus.vault.credentials-provider.mydatabase.kv-path=myapps/vault-quickstart/db

quarkus.datasource.db-kind=postgresql

quarkus.datasource.username=sarah

quarkus.datasource.credentials-provider=mydatabase

quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/mydatabase

NopasswordissetasitisfetchedfromVault.

Dynamiccredentialsarealsosupported:

Runningthefollowingdynamicdatabasecon�ginVault:

vault write database/config/mydb plugin_name=postgresql-database-

plugin…..

Youcancon�gureas:

quarkus.vault.credentials-provider

.mydatabase.database-credentials-role=mydbrole

quarkus.datasource.db-kind=postgresql

quarkus.datasource.credentials-provider=mydatabase

quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/mydatabase

UsernameandpasswordarefetchedfromVault

Transit

@InjectVaultTransitSecretEnginetransit;

transit.encrypt("my_encryption",text);

transit.decrypt("my_encryption",text).asString();

transit.sign("my-sign-key",text);

TransitKey

@InjectVaultTransitSecretEnginetransit;

transit.createKey(KEY_NAME, new KeyCreationRequestDetail().setExportable(true));transit.readKey(KEY_NAME);

transit.listKeys();

transit.exportKey(KEY_NAME, VaultTransitExportKeyType.encry

ption,null);transit.updateKeyConfiguration(KEY_NAME, new KeyConfigRequestDetail().setDeletionAllowed(true));transit.deleteKey(KEY_NAME);

VaultTOTP

TOTP secret engine is supported by usingio.quarkus.vault.VaultTOTPSecretEngine class:

@InjectVaultTOTPSecretEnginevaultTOTPSecretEngine;

CreateKeyParameterscreateKeyParameters=newCreateKeyParameters("Google","[email protected]");

createKeyParameters.setPeriod("30m");

/**GenerateKey(QRcode)*/

finalOptional<KeyDefinition>myKey=vaultTOTPSecretEngine.createKey("my_

key_2",createKeyParameters);

/**Generatekeynumbertologin*/

final String keyCode = vaultTOTPSecretEngine.generateCode("my_key_2");

/**Loginlogic*/

booleanvalid=vaultTOTPSecretEngine.validateCode("my_key_2",keyCode);

VaultProvisioning

Vault extension offers façade classes to Vault provisioningfunctions:

@InjectVaultSystemBackendEnginevaultSystemBackendEngine;

@InjectVaultKubernetesAuthServicevaultKubernetesAuthService;

Stringrules="path\"transit/*\"{\n"+

"capabilities=[\"create\",\"read\",\"updat

e\"]\n"+

"}";

StringpolicyName="sys-test-policy";

vaultSystemBackendEngine.createUpdatePolicy(policyName, rul

es);

vaultKubernetesAuthService

.createRole(roleName,newVaultKubernetesAuthRole().setBoundServiceAccountNames(boundServiceAccountN

ames)

.setBoundServiceAccountNamespaces(boundServiceAcc

ountNamespaces)

.setTokenPolicies(tokenPolicies));

Vaultcon�gurationproperties.Pre�xquarkus.vault isskipped.

url

VaultserverURL

authentication.client-token

Vaulttokentoaccess

authentication.app-role.role-id

RoleIdforAppRoleauth

authentication.app-role.secret-id

SecretIdforAppRoleauth

authentication.app-role.secret-id-wrapping-token

WrappingtokencontainingaSecretId. secret-id and secret-id-wrapping-token areexclusive.

authentication.userpass.username

Usernameforuserpassauth

authentication.userpass.password

Passwordforuserpassauth

authentication.userpass.password-wrapping-token

Wrapping token containing a password. password and password-wrapping-token areexclusive.

authentication.kubernetes.role

Kubernetesauthenticationrole

authentication.kubernetes.jwt-token-path

Locationofthe�lecontainingtheKubernetesJWTtoken

renew-grace-period

Page 37: Quarkus Cheat-Sheet

Renewgraceperiodduration(default:1H )

secret-config-cache-period

Vaultcon�gsourcecacheperiod(default:10M )

secret-config-kv-path

Vaultpathinkvstore.ListofpathsissupportedinCSV

log-confidentiality-level

Used to hide con�dential infos. low , medium , high (default:medium )

kv-secret-engine-version

Kvsecretengineversion(default:1)

kv-secret-engine-mount-path Kvsecretenginepath(default:secret )

tls.skip-verify

Allows to bypass certi�cate validation on TLS communications(default:false )

tls.ca-cert

Certi�catebundleusedtovalidateTLScommunications

tls.use-kubernetes-ca-cert

TLSwillbeactive(default:true )

connect-timeout

Tiemouttoestablishaconnection(default:5S )

read-timeout

Requesttimeout(default:1S )

credentials-provider."credentials-provider".database-credentials-

role

Databasecredentialsrole

credentials-provider."credentials-provider".kv-path

Apathinvaultkvstore,wherewewill�ndthekv-key

credentials-provider."credentials-provider".kv-key

Keynametosearchinvaultpathkv-path(default:password )

AmazonKMS

mvnquarkus:add-extension

-Dextensions="amazon-kms"

@InjectKmsClientkms;

kms.encrypt(req->req.keyId(keyArn).plaintext(

SdkBytes.fromUtf8String(data))).ciphertextBlob();

quarkus.kms.endpoint-override=http://localhost:8011quarkus.kms.aws.region=us-east-1quarkus.kms.aws.credentials.type=staticquarkus.kms.aws.credentials.static-provider.access-key-id=test-key

quarkus.kms.aws.credentials.static-provider.secret-access-key=test-secret

YouneedtosetaHTTPclienteitherURLConnection :

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>url-connection-client</artifactId>

</dependency>

orApacheHTTP:

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>apache-client</artifactId>

</dependency>

quarkus.sqs.sync-client.type=apache

YoucangoasyncbyusingMutiny:

@Injectsoftware.amazon.awssdk.services.kms.KmsAsyncClientkms;

Uni.createFrom().completionStage(

kms.encrypt(req->req.keyId(keyArn).plaintext(SdkByte

s.fromUtf8String(data))

))

AndyouneedtoaddtheasynchronousNettyclient:

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>netty-nio-client</artifactId>

</dependency>

Con�gurationpropertiesare thesameasAmazonDynamoDB butchangingthepre�xfromdynamodb tokms .

AmazonIAM

mvnquarkus:add-extension

-Dextensions="quarkus-amazon-iam"

YouneedtosetaHTTPclienteitherURLConnection :

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>url-connection-client</artifactId>

</dependency>

orApacheHTTP:

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>apache-client</artifactId>

</dependency>

AndyouneedtoaddtheasynchronousNettyclient:

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>netty-nio-client</artifactId>

</dependency>

@InjectIamClientclient;

@InjectIamAsyncClientasync;

quarkus.iam.endpoint-override=${iam.url}quarkus.iam.aws.region=us-east-1quarkus.iam.aws.credentials.type=staticquarkus.iam.aws.credentials.static-provider.access-key-id=test-key

quarkus.iam.aws.credentials.static-provider.secret-access-key=test-secret

Con�gurationpropertiesare thesameasAmazonDynamoDB butchangingthepre�xfromdynamodb toiam .

Page 38: Quarkus Cheat-Sheet

HTTPCon�guration

Youcancon�gureHTTPparameters.Usingquarkus.http pre�x:

cors

EnableCORS.(default:false )

cors.origins

CSVoforiginsallowed.(dedault:Anyrequestvalid.)

cors.methods

CSVofmethodsvalid.(default:Anymethodvalid.)

cors.headers

CSV of valid allowed headers. (default: Any requested headervalid.)

cors.exposed-headers

CSVofvalidexposedheaders.

port

TheHTTPport.(default:8080 )

test-port

TheHTTPtestport.(default:8081 )

host

TheHTTPhost.(default:0.0.0.0 )

host-enabled

Enablelisteningtohost:port.(default:true )

ssl-port

TheHTTPSport.(default8443 )

test-ssl-port

TheHTTPSportusedtoruntests.(default8444 )

proxy-address-forwarding

Theaddress,schemeetcwillbesetfromheadersforwardedbytheproxyserver.

allow-forwarded

Proxyaddressforwardingisenabledthenthestandard Forwardedheader will be used, rather than the more common but notstandardX-Forwarded-For .

insecure-requests

If insecure requests are allowed. Possible values: enabled ,redirect ,disable .(default:enabled )

http2

EnablesHTTP/2.(default:true )

ssl.port

TheHTTPSport.(default:8443 )

ssl certificate file

The�le path to a service certi�cate or certi�cate chain inPEMformat.Relativetosrc/main/resources .

ssl.certificate.key-file

The�lepathtothecorrespondingcerti�cateprivatekey inPEMformat.Relativetosrc/main/resources .

ssl.certificate.key-store-file

The key store contains the certi�cate information. Relative tosrc/main/resources .

ssl.certificate.key-store-file-type

Thekeystoretype.Itisautomaticallydetectedbasedonthe�lenameorcanbesetmanually.Supportedvaluesare: JKS , JCEKS ,P12 ,PKCS12 orPFX .

ssl.certificate.key-store-password

Thepasswordtoopenthekeystore�le.

ssl.certificate.trust-store-file The trust store location whichcontains the certi�cate information of the certi�cates to trust.Relativetosrc/main/resources .

ssl.certificate.trust-store-file-type

Thetruststoretype.Itisautomaticallydetectedbasedonthe�lenameorcanbesetmanually.

ssl.certificate.trust-store-password

Thepasswordtoopenthetruststore�le.

ssl.cipher-suites

A list of strings of cipher suites to use. If not provided, areasonabledefaultisselected.

ssl.protocols

The list of protocols to explicitly enable. (default: TLSv1.3 andTLSv1.2 ).

ssl.client-auth

Con�gures the engine to require/request client authentication.Possiblevaluesare:none ,request andrequired .(default:none ).

io-threads

ThenumberifIOthreadsusedtoperformIO.

limits.max-header-size

Themaximumlengthofallheaders.(default:20k )

limits.max-body-size

Themaximumsizeofarequestbody.(default:10M )

limits.max-chunk-size

ThemaxHTTPchunksize.

limits.max-initial-line-length

Themaximumlengthoftheinitialline.(default:4096 )

idle-timeout

Htt ti idl ti t (d f lt )

enable-compression

Ifresponsesshouldbecompressed.

read-timeout

HttpconnectionreadtimeoutforblockingIO.(default:60s )

body.handle-file-uploads

If the �les sent using multipart/form-data will be stored locally.(default:true )

body.uploads-directory

The directory where the �les sent using multipart/form-data

shouldbestored.(default:file-uploads )

body.merge-from-attributes

Iftheformattributesshouldbeaddedtotherequestparameters.(default:true )

body.delete-uploaded-files-on-end

Iftheuploaded�lesshouldberemovedafterservingtherequest.

body.preallocate-body-buffer

If the body buffer should pre-allocated based on the Content-Length headervalue.(default:1K )

auth.session.encryption-key

Theencryptionkeythatisusedtostorepersistentlogins.

so-reuse-port

Enablesocketreuseport.

tcp-quick-ack

Enabletcpquickack.

tcp-cork

Enabletcpcork.

tcp-fast-open

Enabletcpfastopen.

domain-socket

Path to a unix domain socket. (default:/var/run/io.quarkus.app.socket )

domain-socket-enabled

Enablesdomainsocket.

record-request-start-time

If enabled then start timewill be recorded to enable loggingoftotalrequesttime.(default:false )

access-log.enabled

Ifaccessloggingisenabled.(default:false )

access-log.pattern

Theaccesslogpattern.(default:common )

l l t fil

Page 39: Quarkus Cheat-Sheet

Ifloggingshouldbedonetoaseparate�le.(default:false )

access-log.base-file-name

Theaccesslog�lebasename.(default:quarkus )

access-log.log-directory

Thelogdirectorytousewhenloggingaccesstoa�le.

access-log.log-directory

Thelogdirectorytousewhenloggingaccesstoa�le.

access-log.log-suffix

Thelog�lesu�x.(default:.log )

access-log.category

Thelogcategorytouseifloggingisbeingdoneviathestandardlogmechanism.(default:io.quarkus.http.access-log )

access-log.rotate

Ifthelogshouldberotateddaily.(default:true )

same-site-cookie.<name>.case-sensitive

Ifthecookiepatterniscasesensitive.

same-site-cookie.<name>.value

Thevaluetosetinthesamesiteattribute.

same-site-cookie.<name>.enable-client-checker

Some User Agents break when sent SameSite=None, this willdetectthemandavoidsendingthevalue.(default:true )

same-site-cookie.<name>.add-secure-for-none

Ifthisistruethenthe'secure'attributewillautomaticallybesentoncookieswithaSameSiteattributeofNone.(default:true )

If metrics extension is registered, you can enable to get HTTPmetricsbysettingquarkus.resteasy.metrics.enabled totrue.

JAX-RS

Quarkus uses JAX-RS to de�ne REST-ful web APIs. Under thecovers,Rest-EASYisworkingwithVert.XdirectlywithoutusinganyServlet.

It is important to know that if you want to use any feature thatimplies a Servlet (ie Servlet Filters) then you need to add thequarkus-undertow extension to switch back to the Servlet

ecosystem but generally speaking, you don’t need to add it aseverythingelseiswell-supported.

@Path("/book")publicclassBookResource{

@GET@Produces(MediaType.APPLICATION_JSON)publicList<Book>getAllBooks(){}

@POST@Produces(MediaType.APPLICATION_JSON)publicResponsecreateBook(Bookbook){}

@DELETE@Path("{isbn}")@Produces(MediaType.APPLICATION_JSON)publicResponsedeleteBook(@PathParam("isbn")Stringisbn){}

@GET@Produces(MediaType.APPLICATION_JSON)@Path("search")publicResponsesearchBook(@QueryParam("description")Stringdescription){}

}

Togetinformationfromrequest:

@PathParam

Gets content from request URI. (example: /book/{id}

@PathParam("id") )

@QueryParam

Gets query parameter. (example: /book?desc=""

@QueryParam("desc) )

@FormParam

Getsformparameter.

@MatrixParam

Get URI matrix parameter. (example:/book;author=mkyong;country=malaysia )

@CookieParam

Getscookieparambyname.

@HeaderParam

Getsheaderparameterbyname.

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 HTTPmethods notde�nedbythespec.

@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@HttpMethod("LOCK")public@interfaceLOCK{}

@LOCKpublicvoidlockIt(){}}

Injecting

Using@Context annotationtoinjectJAX-RSandServletinformation.

@GETpublicStringgetBase(@ContextUriInfouriInfo){returnuriInfo.getBaseUri();}

Possible injectable objects: SecurityContext , Request , Application ,Configuration , Providers , ResourceContext , ServletConfig ,ServletContext , HttpServletRequest , HttpServletResponse ,HttpHeaders ,Urinfo ,SseEventSink andSse .

HTTPFilters

HTTP requestand responsecanbe intercepted tomanipulate themetadata (ie headers, parameters, media type, …) or abort arequest. You only need to implement the nextContainerRequestFilter and ContainerResponseFilter JAX-RSinterfacesrespectively.

@ProviderpublicclassLoggingFilterimplementsContainerRequestFilter{

@ContextUriInfoinfo;

@ContextHttpServletRequestrequest;

@Overridepublicvoidfilter(ContainerRequestContextcontext){finalStringmethod=context.getMethod();finalStringpath=info.getPath();finalStringaddress=request.getRemoteAddr();System.out.println("Request%s%sfromIP%s",

method,path,address);

}

}

ExceptionMapper

You can map exceptions to produce a custom output byimplementingExceptionMapper interface:

Page 40: Quarkus Cheat-Sheet

@ProviderpublicclassErrorMapperimplementsExceptionMapper<Exception>{

@OverridepublicResponsetoResponse(Exceptionexception){intcode=500;if(exceptioninstanceofWebApplicationException){code=((WebApplicationException)exception)

.getResponse().getStatus();

}

returnResponse.status(code).entity(

Json.createObjectBuilder()

.add("error",exception.getMessage())

.add("code",code)

.build()

)

.build();

}

}

Caching

AnnotationstosetCache-Controlheaders:

@Produces(MediaType.APPLICATION_JSON)@org.jboss.resteasy.annotations.cache.NoCachepublicUserme(){}

@Produces(MediaType.APPLICATION_JSON)@org.jboss.resteasy.annotations.cache.Cache(maxAge=2000,

noStore=false)

publicUseryou(){}

Vert.XFiltersandRoutes

Programmatically

You can also register Vert.X Filters and Router programmaticallyinsideaCDIbean:

importio.quarkus.vertx.http.runtime.filters.Filters;importio.vertx.ext.web.Router;importjavax.enterprise.context.ApplicationScoped;importjavax.enterprise.event.Observes;

@ApplicationScopedpublicclassMyBean{

publicvoidfilters(@ObservesFiltersfilters){

filters

.register(

rc->{

rc.response()

.putHeader("X-Filter","filter1");

rc.next();

},

10);

}

publicvoidroutes(@ObservesRouterrouter){

router

.get("/")

.handler(rc->rc.response().end("OK"));

}

}

Declarative

You can use @Route annotation to use reactive routes and@RouteFilter tosuereactive�ltersinadeclarativeway:

./mvnwquarkus:add-extension

-Dextensions="quarkus-vertx-web"

@ApplicationScopedpublicclassMyDeclarativeRoutes{

@Route(path="/hello",methods=HttpMethod.GET)publicvoidgreetings(RoutingContextrc){Stringname=rc.request().getParam("name");

if(name==null){name="world";

}

rc.response().end("hello"+name);

}

@RouteFilter(20)voidfilter(RoutingContextrc){rc.response().putHeader("X-Filter","filter2");

rc.next();

}

@RouteStringhello(@ParamOptional<String>name){}

@RouteStringhelloFromHeader(@Header("My-Header")Stringheader){}

@RouteStringcreatePerson(@BodyPersonperson){}

}

GraphQL

Quarkus integrates with GraphQL using MicroPro�le GraphQLintegration.

./mvnwquarkus:add-extension

-Dextensions="graphql"

@GraphQLApipublicclassFilmResource{

@Query("allFilms")publicList<String>films(){}

@QuerypublicStringgetFilm(@Name("filmId")intid)){}

@QuerypublicList<Hero>getHeroesWithSurname(@DefaultValue("Skywalker")Stringsurname){

}

@MutationpublicGreetingsload(Greetingsgreetings){}

}

Page 41: Quarkus Cheat-Sheet

If name not provided, then query name is resolved frommethodname.

You can see the full schema at /graphql/schema.graphql . AlsoGraphiQLUIisenabledatdevandtestmodeat/graphql-ui/ .

Extensioncanbecon�guredwiththefollwoingparamterspre�xedwithquarkus.smallrye-graphql .

root-path

The rootPath under which queries will be served. (default:/graphql )

root-path-ui

ThepathwhereGraphQLUIisavailable.(default:/graphql-ui )

always-include-ui

ThepathwhereGraphQLUIisavailable.(default:/graphql-ui )

root-path-ui

AlwaysincludetheUI.Bydefaultthiswillonlybeincludedindevandtest.(default:false )

enable-ui

IfGraphQLUIshouldbeenabled.(default:false )

metrics.enabled

Enablemetrics.(default:false )

Vert.XVerticle

Vert.XVerticlesarealsosupported:

@ApplicationScopedpublicclassVerticleDeployer{

@InjectVertxvertx;

publicvoidinit(@ObservesStartupEventev){CountDownLatchlatch=newCountDownLatch(1);vertx.deployVerticle(BareVerticle::new,newDeploymentOptions().setConfig(

newJsonObject().put("id","bare")

)

)

.thenAccept(x->latch.countDown());

latch.countDown();

}

}

Verticlescanbe:

bareextendingio.vertx.core.AbstractVerticle .

mutiny

extendigio.smallrye.mutiny.vertx.core.AbstractVerticle .

GZipSupport

You can con�gure Quarkus to use GZip in theapplication.properties �le using the next properties withquarkus.resteasy su�x:

gzip.enabled

EnableGZip.(default:false )

gzip.max-input

Con�guretheupperlimitonde�atedrequestbody.(default:10M )

GRPC

QuarkusintegrateswithgRPC:

./mvnwquarkus:add-extension

-Dextensions="quarkus-grpc"

Then you need to con�gure buildtool with gRPC plugins. In thecase of Maven, the kr.motd.maven:os-maven-plugin extension andorg.xolstice.maven.plugins:protobuf-maven-plugin

Protos�lesarestoredatsrc/main/proto .

When java �les are created two service implementations areprovided:onewithdefaultgRPCAPIandotherwithMutinysupport.

With quarkus.grpc.server pre�x, the next con�guration propertiescanbeset:

port

ThegRPCServerport.(default:9000 )

host

ThegRPCserverhost.(default:0.0.0.0 )

handshake-timeout

ThegRPChandshaketimeout.

max-inbound-message-size

Themaxinboundmessagesizeinbytes.

plain-text

Useplaintext.(default:true )

alpn

TWhetherALPNshouldbeused.(default:true )

enable-reflection-service

EnablesthegRPCRe�ectionService.(default:false )

ssl.certificate

The �le path to a server certi�cate or certi�cate chain in PEMformat.

ssl.key

The �le path to the corresponding certi�cate private key �le inPEMformat.

ssl.key-store

An optional key store which holds the certi�cate informationinsteadofspecifyingseparate�les.

ssl.key-store-type

Anoptionalparametertospecifythetypeofthekeystore�le.

ssl.key-store-password

A parameter to specify the password of the key store �le.(default:password )

ssl.trust-store

Trust store which holds the certi�cate information of thecerti�catestotrust

ssl.trust-store-type

Parametertospecifytypeofthetruststore�le.

ssl.trust-store-password

Aparametertospecifythepasswordofthetruststore�le.

ssl.cipher-suites

Alistoftheciphersuitestouse.

ssl.protocols

The list of protocols to explicitly enable. (default:TLSv1.3,TLSv1.2 )

transport-security.certificate

Thepathtothecerti�cate�le.

transport-security.key

Thepathtotheprivatekey�le.

Toconsumetheservice:

@GrpcService("hello")GreeterGrpc.GreeterBlockingStubclient;

@GrpcService("hello")io.grpc.Channelchannel;

Some con�guration example to set the host and the SSLparameters:

quarkus.grpc.clients.hello.host=localhostquarkus.grpc.clients.hello.plain-text=falsequarkus.grpc.clients.hello.ssl.certificate=src/main/resources/tls/client.pem

quarkus.grpc.clients.hello.ssl.key=src/main/resources/tls/client.key

quarkus.grpc.clients.hello.ssl.trust-store=src/main/resources/tls/ca.pem

Page 42: Quarkus Cheat-Sheet

FaultTolerance

QuarkususesMicroPro�leFaultTolerancespec:

./mvnwquarkus:add-extension

-Dextensions="io.quarkus:quarkus-smallrye-fault-toleranc

e"

MicroPro�le Fault Tolerance spec usesCDI interceptor and it canbeusedinseveralelementssuchasCDIbean,JAX-RSresourceorMicroPro�leRestClient.

Todoautomaticretriesonamethod:

@Path("/api")@RegisterRestClientpublicinterfaceWorldClockService{@GET@Path("/json/cet/now")@Produces(MediaType.APPLICATION_JSON)@Retry(maxRetries=2)WorldClockgetNow();}

You can set fallback code in case of an error by using @Fallbackannotation:

@Retry(maxRetries=1)@Fallback(fallbackMethod="fallbackMethod")WorldClockgetNow(){}

publicWorldClockfallbackMethod(){returnnewWorldClock();}

fallbackMethod musthavethesameparametersandreturntypeastheannotatedmethod.

Youcanalsosetlogicintoaclassthatimplements FallbackHandlerinterface:

publicclassRecoverFallbackimplementsFallbackHandler<WorldClock>{@OverridepublicWorldClockhandle(ExecutionContextcontext){}

}

And set it in the annotation as value@Fallback(RecoverFallback.class) .

Incaseyouwanttousecircuitbreakerpattern:

@CircuitBreaker(requestVolumeThreshold=4,failureRatio=0.75,

delay=1000)

WorldClockgetNow(){}

If 3 (4 x 0.75) failures occur among the rolling window of 4consecutiveinvocationsthenthecircuitisopenedfor1000msandthen be back to half open. If the invocation succeeds then thecircuitisbacktoclosedagain.

Youcanusebulkahead pattern to limit the number of concurrentaccess to the same resource. If the operation is synchronous ituses a semaphore approach, if it is asynchronous a thread-poolone. When a request cannot be processed BulkheadException isthrown. It can be used together with any other fault toleranceannotation.

@Bulkhead(5)@Retry(maxRetries=4,delay=1000,

retryOn=BulkheadException.class)

WorldClockgetNow(){}

Faulttoleranceannotations:

Annotation Properties

@Timeout unit

@Retry

maxRetries , delay , delayUnit ,maxDuration , durationUnit ,jitter , jitterDelayUnit , retryOn ,abortOn

@Fallback fallbackMethod

@BulkheadwaitingTaskQueue (only valid inasynchronous)

@CircuitBreaker

failOn , delay , delayUnit ,requestVolumeThreshold ,failureRatio ,successThreshold

@Asynchronous

Youcanoverrideannotationparametersviacon�guration�leusingproperty[classname/methodname/]annotation/parameter :

org.acme.quickstart.WorldClock/getNow/Retry/maxDuration=30#Classscope

org.acme.quickstart.WorldClock/Retry/maxDuration=3000#Global

Retry/maxDuration=3000

You can also enable/disable policies using special parameterenabled .

org.acme.quickstart.WorldClock/getNow/Retry/enabled=false#Disableeverythingexceptfallback

MP_Fault_Tolerance_NonFallback_Enabled=false

MicroPro�le Fault Tolerance integrates with MicroPro�leMetrics spec. You can disable it by settingMP_Fault_Tolerance_Metrics_Enabled tofalse.

Observability

HealthChecks

Quarkus relies on MicroPro�le Health spec to provide healthchecks.

./mvnwquarkus:add-extension

-Dextensions="io.quarkus:quarkus-smallrye-health"

Byjustaddingthisextension,anendpointisregisteredto/q/healthprovidingadefaulthealthcheck.

{

"status":"UP",

"checks":[

]

}

To create a custom health check you need to implement theHealthCheck interfaceandannotateeitherwith @Readiness (readytoprocessrequests)or@Liveness (isrunning)annotations.

@ReadinesspublicclassDatabaseHealthCheckimplementsHealthCheck{@OverridepublicHealthCheckResponsecall(){HealthCheckResponseBuilderresponseBuilder=

HealthCheckResponse.named("Databaseconn");

try{checkDatabaseConnection();

responseBuilder.withData("connection",true);responseBuilder.up();

}catch(IOExceptione){//cannotaccessthedatabase

responseBuilder.down()

.withData("error",e.getMessage());

}

returnresponseBuilder.build();}

}

Buildsthenextoutput:

Page 43: Quarkus Cheat-Sheet

{

"status":"UP",

"checks":[

{

"name":"Databaseconn",

"status":"UP",

"data":{

"connection":true

}

}

]

}

SincehealthchecksareCDIbeans,youcando:

@ApplicationScopedpublicclassDatabaseHealthCheck{

@LivenessHealthCheckcheck1(){returnio.smallrye.health.HealthStatus.up("successful-live");

}

@ReadinessHealthCheckcheck2(){returnHealthStatus.state("successful-read",this::isReady)}

privatebooleanisReady(){}}

You can ping liveness or readiness health checks individually byquerying/q/health/live or/q/health/ready .

Quarkus comes with some HealthCheck implementations forcheckingservicestatus.

SocketHealthCheck: checks if host is reachable using asocket.

UrlHealthCheck:checksifhost isreachableusingaHttpURLconnection.

InetAddressHealthCheck: checks if host is reachable usingInetAddress.isReachable method.

@LivenessHealthCheckcheck1(){returnnewUrlHealthCheck("https://www.google.com").name("Google-Check");

}

Ifyouwant tooverrideorsetmanually readiness/livenessprobes,youcandoitbysettinghealthproperties:

quarkus.smallrye-health.root-path=/helloquarkus.smallrye-health.liveness-path=/customlivequarkus.smallrye-health.readiness-path=/customready

Automaticreadinessprobes

Somedefaultreadinessprobesareprovidedbydefaultifanyofthenextfeaturesareadded:

datasourceAprobetocheckdatabaseconnectionstatus.

kafkaAprobetocheckkafkaconnectionstatus.Inthiscaseyouneedto enable manually by setting quarkus.kafka.health.enabled totrue .

mongoDBAprobetocheckMongoDBconnectionstatus.

neo4jAprobetocheckNeo4Jconnectionstatus.

artemisAprobetocheckArtemisJMSconnectionstatus.

kafka-streamsLiveness (for stream state) and Readiness (topics created)probes.

vaultAprobetocheckVaultconectionstatus.

gRPCAreadinessprobeforthegRPCservices.

CassandraAreadinessprobetocheckCassandraconnectionstatus.

RedisAreadinessprobetocheckRedisconnectionstatus.

You can disable the automatic generation by setting<component>.health.enabled tofalse.

quarkus.kafka-streams.health.enabled=falsequarkus.mongodb.health.enabled=falsequarkus.neo4j.health.enabled=false

InthecaseofVaultyoucanpassparameterstomodifythecallofthestatus endpointinVault.

quarkus.vault.health.enabled=truequarkus.vault.health.stand-by-ok=truequarkus.vault.health.performance-stand-by-ok=true

Health groups are supported to provide custom health checksgroups:

@io.smallrye.health.HealthGroup("mygroup1")public class SimpleHealthGroupCheck implements HealthCheck{

}

Youcanpinggroupedhealthchecksbyquerying/group/mygroup1 .

Grouprootpathcanbecon�gured:

quarkus.smallrye-health.group-path=/customgroup

Metrics

QuarkuscanutilizetheMicroPro�leMetricsspectoprovidemetricssupport.

./mvnwquarkus:add-extension

-Dextensions="io.quarkus:quarkus-smallrye-metrics"

ThemetricscanbereadwithJSONortheOpenMetricsformat.Anendpointisregisteredautomaticallyat /q/metrics providingdefaultmetrics.

MicroPro�leMetricsannotations:

@Timed

Trackstheduration.

@SimplyTimed

Tracksthedurationwithoutmeananddistributioncalculations.

@Metered

Tracksthefrequencyofinvocations.

@Counted

Countsnumberofinvocations.

@Gauge

Samplesthevalueoftheannotatedobject.

@ConcurrentGauge

Gaugetocountparallelinvocations.

@Metric

Used to inject a metric. Valid types Meter , Timer , Counter ,Histogram .Gauge onlyonproducermethods/�elds.

Page 44: Quarkus Cheat-Sheet

@GET//...

@Timed(name="checksTimer",description="Ameasureofhowlongittakes

toperformahello.",

unit=MetricUnits.MILLISECONDS)

publicStringhello(){}

@Counted(name="countWelcome",description="Howmanywelcomehavebeenperformed.")

publicStringhello(){}

@Gauge annotationreturningameasureasagauge.

@Gauge(name="hottestSauce",unit=MetricUnits.NONE,description="HottestSaucesofar.")

publicLonghottestSauce(){}

Injectingahistogramusing@Metric .

@Inject@Metric(name="histogram")Histogramhistorgram;

Youcancon�gureMetrics:

quarkus.smallrye-metrics.path=/mymetrics

Pre�xisquarkus.smallrye-metrics .

path

Thepathtothemetricshandler.(default:/q/metrics )

extensions.enabled

Metricsareenabledornot.(default:true )

micrometer.compatibility

ApplyMicrometercompatibilitymode.(default:false )

quarkus.hibernate-orm.metrics.enabled set to true exposesHibernatemetricsundervendor scope.

quarkus.mongodb.metrics.enabled set to true exposes MongoDBmetricsundervendor scope.

YoucanapplymetricsannotationsviaCDIstereotypes:

@Stereotype@Retention(RetentionPolicy.RUNTIME)@Target({ ElementType.TYPE, ElementType.METHOD, ElementTyp

e.FIELD})

@Timed(name="checksTimer",description="Ameasureofhowlongittakes

toperformahello.",

unit=MetricUnits.MILLISECONDS)

public@interfaceTimedMilliseconds{}

There is a tight integration with Micrometer in the form of anextension:

./mvnwquarkus:add-extension

-Dextensions="micrometer"

Addamicrometerdependencyfortheregistryofyourchoosing:

<dependency>

<groupId>io.micrometer</groupId>

<artifactId>micrometer-registry-prometheus</artifactId>

</dependency>

Youcancon�gureMicrometer.Pre�xisquarkus.micrometer :

enabled

Micrometermetricssupport.(default:true )

registry-enabled-default

MicrometerMeterRegistrydiscovery.(default:true )

binder-enabled-default

MicrometerMeterBinderdiscovery.(default:true )

binder.vertx.enabled

Vert.xmetricssupport.

binder.mp-metrics.enabled

Micropro�leMetricssupport.

binder.jvm

MicrometerJVMmetricssupport.(default:true )

binder.system

MicrometerSystemmetricssupport.(default:true )

export.datadog.enabled

SupportforexporttoDatadogSupportforDatadog.

export.jmx.enabled

SupportforexporttoJMXSupportforJMX.

export.prometheus.enabled

SupportforexporttoPrometheus.

export.prometheus.path

The path for the prometheus metrics endpoint (producestext/plain).(default:/q/metrics )

export.azuremonitor.enabled

SupportforexporttoAzureMonitor.

export.azuremonitor.instrumentation-key

ThepathfortheazuremonitorinstrumentationKey.

export.statsd.enabled

SupportforexporttoStatsD.

export.stackdriver.enabled

Micrometermetricssupport.(default:true )

export.signalfx.enabled

Micrometermetricssupport.(default:true )

export.signalfx.uri

SignalfxURI.

export.signalfx.access-token

AccessToken.

binder.vertx.match-patterns

Comma-separated case-sensitive list of regular expressionsde�ningPathsthatshouldbematchedandusedastags

binder.vertx.ignore-patterns

Comma-separated case-sensitive list of regular expressionsde�ningPathsthatshouldbeignored/notmeasured.

export.datadog

Datadog MeterRegistry con�guration in Map<String, String>

format.

export.jmx

JMX registry con�guration properties in Map<String, String>

format.

export.prometheus

Prometheus registry con�guration properties in Map<String,

String> format.

export.stackdriver

Stackdriver registry con�guration properties in Map<String,

String> format.

Tracing

QuarkuscanutilizetheMicroPro�leOpenTracingspec.

./mvnwquarkus:add-extension

-Dextensions="io.quarkus:quarkus-smallrye-opentracing"

Requestssenttoanyendpointaretracedautomatically.

Page 45: Quarkus Cheat-Sheet

ThisextensionincludesOpenTracingsupportandJaeger tracer.

Jaegertracercon�guration:

quarkus.jaeger.service-name=myservicequarkus.jaeger.sampler-type=constquarkus.jaeger.sampler-param=1quarkus.jaeger.endpoint=http://localhost:14268/api/tracesquarkus.jaeger.metrics.enabled=true

@Traced annotationcanbesettodisabletracingatclassormethodlevel.

Tracer classcanbeinjectedintotheclass.

@InjectTracertracer;

tracer.activeSpan().setBaggageItem("key","value");

Youcandisable Jaeger extensionbyusing quarkus.jaeger.enabledproperty.

YoucanlogthetraceId ,spanId andsampled innormallog:

quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId},

spanId=%X{spanId},sampled=%X{sampled}[%c{2.}](%t)%s%e%n

Additionaltracers

JDBCTracer

AddsaspanforeachJDBCqueries.

<dependency>

<groupId>io.opentracing.contrib</groupId>

<artifactId>opentracing-jdbc</artifactId>

</dependency>

Con�gureJDBCdriverapartfromtracingpropertiesseenbefore:

#add':tracing'toyourdatabaseURL

quarkus.datasource.url=jdbc:tracing:postgresql://localhost:5432/mydatabase

quarkus.datasource.driver=io.opentracing.contrib.jdbc.TracingDriver

quarkus.hibernate-orm.dialect=org.hibernate.dialect.PostgreSQLDialect

OpenTelemetry

Quarkus integrateswith theOpenTelemetry project. For exportingtraces to a Jaeger collector, use the quarkus-opentelemetry-

exporter-jaeger extension

KafkaTracer

Adds a span for eachmessage sent to or received from a Kafkatopic.

<dependency>

<groupId>io.opentracing.contrib</groupId>

<artifactId>opentracing-kafka-client<</artifactId>

</dependency>

Andcon�gureit:

...

mp.messaging.outgoing.generated-price.topic=prices

#ForProduces

mp.messaging.outgoing.generated-price.interceptor.classes=io.opentracing.contrib.kafka.TracingProducerInterceptor

...

#Forconsumers

mp.messaging.incoming.prices.interceptor.classes=io.opentracing.contrib.kafka.TracingConsumerInterceptor

AWSXRay

If you are building native images, and want to use AWS X-RayTracingwithyour lambdayouwill need to include quarkus-amazon-lambda-xray asadependencyinyourpom.

NativeExecutable

Youcanbuildanative imagebyusingGraalVM.Thecommonusecase is creating a Docker image so you can execute the nextcommands:

./mvnwpackage-Pnative-Dquarkus.native.container-build=tr

ue

dockerbuild-fsrc/main/docker/Dockerfile.native

-tquarkus/getting-started.

dockerrun-i--rm-p8080:8080quarkus/getting-started

You can use quarkus.native.container-runtime to select thecontainerruntimetouse.Now docker (default)and podman are thevalidoptions.

./mvnwpackage-Pnative-Dquarkus.native.container-runtime=

podman

Tocon�gurenativeapplication,youcancreateaconfig directoryatthe same place as the native �le and place anapplication.properties �leinside.config/application.properties .

SSL

Tocreateanative imagewithSSLyouneedtocopySunEClibraryandcerti�cates:

Java8:

FROM quay.io/quarkus/ubi-quarkus-native-image:{graalvm-vers

ion}-java8asnativebuilder

RUNmkdir-p/tmp/ssl-libs/lib\

&&cp/opt/graalvm/jre/lib/security/cacerts/tmp/ssl-libs

\

&&cp/opt/graalvm/jre/lib/amd64/libsunec.so/tmp/ssl-lib

s/lib/

FROMregistry.access.redhat.com/ubi8/ubi-minimal

WORKDIR/work/

COPY--from=nativebuilder/tmp/ssl-libs//work/

COPYtarget/*-runner/work/application

RUNchmod775/work/work/application

EXPOSE8080

CMD["./application","-Dquarkus.http.host=0.0.0.0","-Djav

a.library.path=/work/lib", "-Djavax.net.ssl.trustStore=/wor

k/cacerts"]

Java11:

Page 46: Quarkus Cheat-Sheet

FROM quay.io/quarkus/ubi-quarkus-native-image:{graalvm-vers

ion}-java11asnativebuilder

RUNmkdir-p/tmp/ssl-libs/lib\

&&cp/opt/graalvm/lib/security/cacerts/tmp/ssl-libs\

&&cp/opt/graalvm/lib/libsunec.so/tmp/ssl-libs/lib/

FROMregistry.access.redhat.com/ubi8/ubi-minimal

WORKDIR/work/

COPY--from=nativebuilder/tmp/ssl-libs//work/

COPYtarget/*-runner/work/application

RUNchmod775/work/work/application

EXPOSE8080

CMD["./application","-Dquarkus.http.host=0.0.0.0","-Djav

a.library.path=/work/lib", "-Djavax.net.ssl.trustStore=/wor

k/cacerts"]

Inclusionofresources

By default, no resources are included in native executable.quarkus.native.resources.includes allowstosetglobexpressionstoincluderesourcesbasedonsrc/main/resources path.

Givensrc/main/resources/foo/selected.png :

quarkus.native.resources.includes=foo/**

Exclusionofresources

Bydefault,noresourcesareexcluded.

quarkus.native.resources.excludes=foo/**

Nativecon�gurationpropertiespre�xedwithquarkus.native :

additional-build-args

Additionalargumentstopasstothebuildprocess.

enable-http-url-handler

IftheHTTPurlhandlershouldbeenabled.(default:true )

enable-https-url-handler

IftheHTTPSurlhandlershouldbeenabled.

enable-all-security-services

Ifallsecurityservicesshouldbeaddedtothenativeimage.

user-language

De�nes the user language used for building the nativeexecutable.

user-country

De�nestheusercountryusedforbuildingthenativeexecutable.

file-encoding

De�nesthe�leencoding.

Ifallcharactersetsshouldbeaddedtothenativeimage.

graalvm-home

ThelocationoftheGraaldistribution.

java-home

ThelocationoftheJDK.

native-image-xmx

The maximum Java heap to be used during the native imagegeneration.

debug-build-process

If the native image build should wait for a debugger to beattachedbeforerunning.

publish-debug-build-process-port

Ifthedebugportshouldbepublishedwhenbuildingwithdockeranddebug-build-process.(default:true )

cleanup-server

Ifthenativeimageservershouldberestarted.

enable-isolates

Ifisolatesshouldbeenabled.(default:true )

enable-fallback-images

IfaJVMbased'fallbackimage'shouldbecreatedifnativeimagefails.

enable-server

Ifthenativeimageservershouldbeused.

auto-service-loader-registration

If all META-INF/services entries should be automaticallyregistered.

dump-proxies

Ifthebytecodeofallproxiesshouldbedumpedforinspection.

container-build

Ifthisbuildshouldbedoneusingacontainerruntime.

remote-container-build

Ifthisbuildisdoneusingaremotedockerdaemon.

builder-image

Thedockerimagetousetodotheimagebuild.

container-runtime

Thecontainer runtime that isused todoan imagebasedbuild.(docker ,podman )

container-runtime-options

Optionstopasstothecontainerruntime.

enable-vm-inspection

If the resulting image should allow VM introspection

full-stack-traces

Iffullstacktracesareenabledintheresultingimage.

enable-reports

If the reports on call paths and includedpackages/classes/methodsshouldbegenerated.

report-exception-stack-traces

Ifexceptionsshouldbereportedwithafullstacktrace.

report-errors-at-runtime

Iferrorsshouldbereportedatruntime.

enable-dashboard-dump

Generatethereport�lesforGraalVMDashboard.

resources.includes

A comma separated list of globs tomatch resource paths thatshouldbeaddedtothenativeimage.

resources.excludes

A comma separated list of globs tomatch resource paths thatshouldexcludetothenativeimage.

debug.enabled

Ifdebugisenabledanddebugsymbolsaregenerated.

ContainerImagesCreation

Youcan levarage toQuarkus togenerationand releaseofDockercontainers.Itprovidesseveralextensionstomakeitso.

mvncleanpackage

-Dquarkus.container-image.build=true

-Dquarkus.container-image.push=true

-Dquarkus.container-image.registry=quay.io

Pre�xisquarkus.container-image :

group

Thegroup/repositoryoftheimage.(default:the${user.name} )

name

Thenameoftheimage.(default:theapplicationname)

tag

Thetagoftheimage.(default:theapplicationversion)

additional-tags

Additionaltagsofthecontainerimage.

registry

Theregistrytouseforpushing.(default:docker.io )

username

Theregistryusername.

Page 47: Quarkus Cheat-Sheet

password

Theregistrypassword.

insecure

Flagtoallowinsecureregistries.(default:false )

build

Booleantosetifimageshouldbebuilt.(default:false )

push

Booleantosetifimageshouldbepushed.(default:false )

Jib

./mvnwquarkus:add-extensions

-Dextensions="quarkus-container-image-jib"

Quarkuscopiesany�leunder src/main/jib intothebuiltcontainerimage.

Pre�xisquarkus.container-image-jib :

base-jvm-image

The base image to use for the jib build. (default: fabric8/java-alpine-openjdk8-jre )

base-native-image

The base image to use for the native build. (default:registry.access.redhat.com/ubi8/ubi-minimal )

jvm-arguments

The arguments to pass to java. (default: -

Dquarkus.http.host=0.0.0.0,-

Djava.util.logging.manager=org.jboss.logmanager.LogManager )

native-arguments

The arguments to pass to the native application. (default: -Dquarkus.http.host=0.0.0.0 )

environment-variables

Mapofenvironmentvariables.

jvm-entrypoint

AcustomentrypointofthecontainerimageinJVMmode.

native-entrypoint

Acustomentrypointofthecontainerimageinnativemode.

labels

Customlabelstoaddtothegeneratedimage.

base-registry-username

The username to use to authenticate with the registry used topullthebaseJVMimage.

base-registry-password

Thepasswordtousetoauthenticatewiththeregistryusedtopull

ports

Theportstoexpose.

user

Theusertouseingeneratedimage.

always-cache-base-image

Controls theoptimizationwhich skipsdownloadingbase imagelayersthatexistinatargetregistry(default:false ).

appcds-builder-image

WhenAppCDSgenerationisenabled, ifthisproperty isset,thenthe JVM used to generate the AppCDS �le will be the JVMpresentinthecontainerimage.

platforms

Listoftargetplatforms.(ielinux/amd64 ).

Docker

./mvnwquarkus:add-extensions

-Dextensions="quarkus-container-image-docker"

Pre�xisquarkus.container-image-s2i :

dockerfile-jvm-path

Path to the JVM Docker�le. (default:${project.root}/src/main/docker/Dockerfile.jvm )

dockerfile-native-path

Path to the native Docker�le. (default:${project.root}/src/main/docker/Dockerfile.native )

S2I

./mvnwquarkus:add-extensions

-Dextensions="quarkus-container-image-s2i"

Pre�xisquarkus.container-image-docker :

base-jvm-image

Thebase image to use for the s2i build. (default: fabric8/java-alpine-openjdk8-jre )

base-native-image

The base image to use for the native build. (default:registry.access.redhat.com/ubi8/ubi-minimal )

Kubernetes

QuarkuscanuseDekoratetogenerateKubernetesresources.

./mvnwquarkus:add-extensions

-Dextensions="quarkus-kubernetes"

Running ./mvnwpackage the Kubernetes resources are created attarget/kubernetes/ directory.

Container Images Creation integrates with Kubernetesextension,sononeedofextraKubernetesproperties.

Generated resource is integrated with MicroPro�le Healthannotations.

Also,youcancustomizethegeneratedresourcebysettingthenewvaluesinapplication.properties :

quarkus.kubernetes.namespace=mynamespace

quarkus.kubernetes.replicas=3

quarkus.kubernetes.labels.foo=bar

quarkus.kubernetes.readiness-probe.period-seconds=45

quarkus.kubernetes.mounts.github-token.path=/deployment/github

quarkus.kubernetes.mounts.github-token.read-only=true

quarkus.kubernetes.secret-volumes.github-token.volume-name=github-token

quarkus.kubernetes.secret-volumes.github-token.secret-name=greeting-security

quarkus.kubernetes.secret-volumes.github-token.default-mode=420

quarkus.kubernetes.config-map-volumes.github-token.config-map-name=my-secret

quarkus.kubernetes.expose=truequarkus.kubernetes.ingress.expose=truequarkus.kubernetes.ingress.host=example.com

quarkus.kubernetes.env.vars.my-env-var=foobarquarkus.kubernetes.env.configmaps=my-config-map,another-config-map

quarkus.kubernetes.env.secrets=my-secret,my-other-secret

quarkus.kubernetes.resources.requests.memory=64Miquarkus.kubernetes.resources.requests.cpu=250mquarkus.kubernetes.resources.limits.memory=512Miquarkus.kubernetes.resources.limits.cpu=1000m

All possible values are explained athttps://quarkus.io/guides/kubernetes#con�guration-options.

LabelsandAnnotations

The generatedmanifest use the Kubernetes recommended labelsandannotations.

Page 48: Quarkus Cheat-Sheet

"labels":{

"app.kubernetes.io/part-of":"todo-app",

"app.kubernetes.io/name":"todo-rest",

"app.kubernetes.io/version":"1.0-rc.1"

}

"annotations":{

"app.quarkus.io/vcs-url":"<someurl>",

"app.quarkus.io/commit-id":"<somegitSHA>",

}

Youcanoverridethelabelsbyusingthenextproperties:

quarkus.kubernetes.part-of=todo-appquarkus.kubernetes.name=todo-restquarkus.kubernetes.version=1.0-rc.1

Oraddnewlabelsand/orannotations:

quarkus.kubernetes.labels.foo=barquarkus.kubernetes.annotations.foo=bar

metrics

When using metrics extension, Prometheus annotations aregenerated:

prometheus.io/scrape:"true"

prometheus.io/path:/metrics

prometheus.io/port:"8080"

KubernetesDeploymentTargets

You can generate different resources setting the propertyquarkus.kubernetes.deployment-target .

Possiblevaluesare kubernetes , openshift and knative .Thedefaultvalueiskubernetes .

KnativeProperties

Most of the Kubernetes properties are valid in Knative output byjust changing the kubernetes pre�x to knative pre�x (iequarkus.kubernetes.readiness-probe.period-seconds toquarkus.knative.readiness-probe.period-seconds ).

Therearealsospeci�cpropertiesforKnative:

quarkus.kubernetes.deployment-target=knativequarkus.knative.revision-name=my-revisionquarkus.knative.traffic.my-revision.percentage=80

Listofcon�gurationoptions:

kuberneteshttps://quarkus io/guides/kubernetes#con�guration options

openshifthttps://quarkus.io/guides/kubernetes#openshift

Knativehttps://quarkus.io/guides/kubernetes#knative

UsingExistingResources

YouanprovideyourKubernetesresourcesinformofyaml/jsonandtheywill provide additional resources or be used as base for thegenerationprocess:

Resources are added in src/main/kubernetes directory with thetarget name (kubernetes.json , openshift.json , knative.json , or theyml equivalents) with one orm ore Kubernetes resources. Anyresourcefoundwillbeaddedinthegeneratedmanifests.Ifoneoftheprovidedresourceshasthesamenameasoneofthegeneratedones, then the generated resource will be created on top of theprovidedresource,respectingexistingcontent.

To override the name of the generated resource you can use:quarkus.kubernetes.name , quarkus.openshift.name andquarkus.knative.name .

Deployment

Todeployautomatically thegenerated resources, youneed to setquarkus.container.deploy �agtotrue .

mvncleanpackage-Dquarkus.kubernetes.deploy=true

If you set this �ag to true , the build and push �ags fromcontainer-imagearesettotrue too.

To deploy the application, the extension uses thehttps://github.com/fabric8io/kubernetes-client. All optionsdescribedatKubernetesClientarevalidhere.

KubernetesServiceBinding

Quarkus supports binding services to applications via theServiceBindingSpeci�cationforKubernetes.

ThefollowingQuarkusextensionssupportthisfeature:

quarkus-jdbc-mariadb

quarkus-jdbc-mssql

quarkus-jdbc-mysql

quarkus-jdbc-postgresql

quarkus-kafka-client

quarkus-smallrye-reactive-messaging-kafka

./mvnwquarkus:add-extensions

-Dextensions="quarkus-kubernetes-service-binding"

Datasource con�gurationpart is absent as it is aut-discoveredbyQuarkus.

Minikube

Quarkus has a Minikube extension which creates KubernetesmanifeststhataretailoredforMinikube.

./mvnwquarkus:add-extension

-Dextensions="minikube"

Remember to execute eval$(minikube-pminikubedocker-env) tobuildimagesdirectlyinsideMinkubecluster.

OpenShift

Instead of adding Kubernetes extension, set container image s2iand the target to openshift for working with OpenShift, anextensiongroupingalloftheiscreated:

./mvnwquarkus:add-extension

-Dextensions="openshift"

KubernetesCon�gurationExtension

Integration between MicroPro�le Con�g spec and Con�gMaps &Secrets:

./mvnwquarkus:add-extensions

-Dextensions="quarkus-kubernetes-config"

quarkus.kubernetes-config.enabled=truequarkus.kubernetes-config.config-maps=cmap1,cmap2

@ConfigProperty(name="some.prop1")StringsomeProp1;

@ConfigProperty(name="some.prop2")StringsomeProp2;

If the con�g key is a Quarkus con�guration �leapplication.properties/application.yaml ,thecontentisparsedandeachkeyofthecon�guration�leisusedascon�gproperty.

ListofKubernetesCon�gparameters.

quarkus.kubernetes-config aspre�xisskippedinthenexttable.

enabled

Theapplicationwillattempttolookupthecon�gurationfromtheAPIserver.(default:false )

fail-on-missing-config

Page 49: Quarkus Cheat-Sheet

The application will not start if any of the con�gured con�gsourcescannotbelocated.(default:true )

config-maps

Con�gMaps to look for in the namespace that the KubernetesClienthasbeencon�guredfor.SupportsCSV.

namespace

AccesstoCon�gMapsfromaspeci�cnamespace.

secrets.enabled

Whetherornotcon�gurationcanbereadfromsecrets.(default:false )

KubernetesClient

QuarkusintegrateswithFabric8KubernetesClient.

./mvnwquarkus:add-extension

-Dextensions="quarkus-kubernetes-client"

ListofKubernetesclientparameters.

quarkus.kubernetes-client aspre�xisskippedinthenexttable.

trust-certs

Trustself-signedcerti�cates.(default:false )

master-url

URLofKubernetesAPIserver.

namesapce

Defaultnamespace.

ca-cert-file

CAcerti�catedata.

client-cert-file

Clientcerti�cate�le.

client-cert-data

Clientcerti�catedata.

client-key-data

Clientkeydata.

client-key-algorithm

Clientkeyalgorithm.

client-key-passphrase

Clientkeypassphrase.

username

Username.

password

Password

watch-reconnect-interval

Watchreconnectinterval.(default:PT1S )

watch-reconnect-limit

Maximumreconnectattempts.(default:-1 )

connection-timeout

Maximum amount of time to wait for a connection. (default:PT10S )

request-timeout

Maximumamountoftimetowaitforarequest.(default:PT10S )

rolling-timeout

Maximumamountoftimetowaitforarollout.(default:PT15M )

http-proxy

HTTPproxyusedtoaccesstheKubernetes.

https-proxy

HTTPSproxyusedtoaccesstheKubernetes.

proxy-username

Proxyusername.

proxy-password

Proxypassword.

no-proxy

IPaddressesorhoststoexcludefromproxying

Orprogrammatically:

@DependentpublicclassKubernetesClientProducer{

@ProducespublicKubernetesClientkubernetesClient(){Configconfig=newConfigBuilder().withMasterUrl("https://mymaster.com")

.build();

returnnewDefaultKubernetesClient(config);}

}

Andinjectitoncode:

@InjectKubernetesClientclient;

ServiceListmyServices=client.services().list();

Servicemyservice=client.services()

.inNamespace("default")

.withName("myservice")

.get();

CustomResourceDefinitionListcrds=client

.customResourceDefinitions()

.list();

dummyCRD=newCustomResourceDefinitionBuilder()...

.build()

client.customResourceDefinitions()

.create(dummyCRD);

Testing

Quarkus provides a Kubernetes Mock test resource that starts amock of Kubernetes API server and sets the proper environmentvariablesneededbyKubernetesClient.

Register next dependency: io.quarkus:quarkus-test-kubernetes-

client:test .

@QuarkusTestResource(KubernetesMockServerTestResource.class)

@QuarkusTestpublicclassKubernetesClientTest{

@MockServerprivateKubernetesMockServermockServer;

@Testpublicvoidtest(){finalPodpod1=...mockServer

.expect()

.get()

.withPath("/api/v1/namespaces/test/pods")

.andReturn(200,

newPodListBuilder().withNewMetadata()

.withResourceVersion("1")

.endMetadata()

.withItems(pod1,pod2)

.build())

.always();

}

}

AWSLambda

QuarkusintegrateswithAmazonLambda.

Page 50: Quarkus Cheat-Sheet

./mvnwquarkus:add-extension

-Dextensions="io.quarkus:quarkus-amazon-lambda"

And then implementcom.amazonaws.services.lambda.runtime.RequestHandler interface.

publicclassTestLambdaimplementsRequestHandler<MyInput,MyOutput>{@OverridepublicMyInputhandleRequest(MyOutputinput,Contextcontext){

}

}

The interfacecom.amazonaws.services.lambda.runtime.RequestStreamHandler is alsosupported.

Theinterfacecom.amazon.ask.SkillStreamHandler isalsosupported.

You can set the handler name by using quarkus.lambda.handlerproperty or by annotating the Lambda with the CDI @Named

annotation.

Test

YoucanwritetestsforAmazonlambdas:

<dependency>

<groupId>io.quarkus</groupId>

<artifactId>quarkus-test-amazon-lambda</artifactId>

<scope>test</scope>

</dependency>

@TestpublicvoidtestLambda(){MyInputin=newMyInput();in.setGreeting("Hello");

in.setName("Stu");

MyOutputout=LambdaClient.invoke(MyOutput.class,in);

}

ToscaffoldaAWSLambdarun:

mvnarchetype:generate\

-DarchetypeGroupId=io.quarkus\

-DarchetypeArtifactId=quarkus-amazon-lambda-archetype\

-DarchetypeVersion={version}

AzureFunctions

Quarkus can make a microservice be deployable to the AzureFunctions.

ToscaffoldadeployablemicroservicetotheAzureFunctionsrun:

mvnarchetype:generate\

-DarchetypeGroupId=io.quarkus\

-DarchetypeArtifactId=quarkus-azure-functions-http-archet

ype\

-DarchetypeVersion={version}

Funqy

QuarkusFunqyispartofQuarkus’sserverlessstrategyandaimstoprovideaportableJavaAPItowritefunctionsdeployabletovariousFaaSenvironmentslikeAWSLambda,AzureFunctions,Knative,andKnativeevents.

publicclassGreetingFunction{

@InjectGreetingServiceservice;

@io.quarkus.funqy.FunqpublicStringgreet(Stringname){}

@io.quarkus.funqy.Funq("HelloCustomer")publicStringgreet(Customername){}

@FunqpublicGreetinggreet(Friendfriend,@io.quarkus.funqy.ContextAwsContextctx){}

}

In case of Amazon Lambda, only one Funqy function can beexported per Amazon Lambda deployment. If there is only onemethodannotatedwith @Funq thennoprob, ifnot,youneedtosetthefunctionnamewithquarkus.funqy.export property.

FunqyHTTP

You can invoke on Funqy functions in a pure HTTP environmentwithsimpleaddingtheFunqyHTTPextension.

<dependency>

<groupId>io.quarkus</groupId>

<artifactId>quarkus-funqy-http</artifactId>

</dependency>

FunqyCloudEvents

Addtheextension:

<dependency>

<groupId>io.quarkus</groupId>

<artifactId>quarkus-funqy-knative-events</artifactId>

</dependency>

@FunqpublicStringdefaultChain(Stringinput){}

TheCloudEvent type that triggers the function is defaultChain . ItgeneratesaresponsethattriggersanewCloudEventwhosetypeisdefaultChain.output andtheeventsourceisdefaultChain .

Itcanbechangedbyusingthenextproperties:

quarkus.funqy.knative-events.mapping.defaultChain.trigger=configChain.output

quarkus.funqy.knative-events.mapping.defaultChain.response-type=annotatedquarkus.funqy.knative-events.mapping.defaultChain.response-source=configChain

The properties are of form: quarkus.funqy.knative-events.mapping.{functionname}. .

Also can be overriden [email protected] annotation.

@Funq@CloudEventMapping(trigger = "annotated", responseSource ="annotated",responseType="lastChainLink")

publicStringannotatedChain(Stringinput){}

responseType chains annotatedChain response to lastChainLink

function.

@FunqpublicvoidlastChainLink(Stringinput,@Contextio.quarkus.funqy.knative.events.CloudE

ventevent){}

AK-NativeTriggerlookslike:

apiVersion:eventing.knative.dev/v1alpha1

kind:Trigger

metadata:

name:defaultchain

spec:

filter:

attributes:

type:defaultChain

subscriber:

ref:

apiVersion:serving.knative.dev/v1

kind:Service

name:funqy-knative-events-quickstart

Andtocurl frominsidetheKubernetescluster:

Page 51: Quarkus Cheat-Sheet

curl -v "http://default-broker.knativetutorial.svc.cluster.

local"\

-XPOST\

-H"Ce-Id:1234"\

-H"Ce-Specversion:1.0"\

-H"Ce-Type:defaultChain"\

-H"Ce-Source:curl"\

-H"Content-Type:application/json"\

-d'"Start"'

ApacheCamel

Apache Camel Quarkus has its own site:https://github.com/apache/camel-quarkus

WebSockets

Quarkuscanbeusedtohandlingwebsockets.

./mvnwquarkus:add-extension

-Dextensions="quarkus-websockets"

Andwebsocketsclassescanbeused:

@ServerEndpoint("/chat/{username}")@ApplicationScopedpublicclassChatSocket{

@OnOpenpublicvoidonOpen(Sessionsession,@PathParam("username")Stringusername){}

@OnClosepublicvoidonClose(..){}

@OnErrorpublicvoidonError(...,Throwablethrowable){}

@OnMessagepublicvoidonMessage(...){}

}

OpenAPI

QuarkuscanexposeitsAPIdescriptionasOpenAPIspecandtestitusingSwaggerUI.

./mvnwquarkus:add-extension

-Dextensions="io.quarkus:quarkus-smallrye-openapi"

Thenyouonlyneedtoaccessto /openapi togetOpenAPIv3specofservices.

You can update the OpenApi path by setting quarkus.smallrye-openapi.path property.

Also, incaseofstartingQuarkusapplication in dev or test mode,Swagger UI is accessible at /swagger-ui . If you want to use it inproduction mode you need to set quarkus.swagger-ui.always-

include propertytotrue .

You can update the Swagger UI path by setting quarkus.swagger-ui.path property.

quarkus.swagger-ui.path=/my-custom-path

PossibleSwaggerUIoptionswithquarkus.swagger-ui pre�x:

urls

The urls that will be included as options. (ie quarkus.swagger-ui.urls.petstore=https://petstore.swagger.io/v2/swagger.json )

urls-primary-name

If urls option is used, this will be the name of the defaultselection.

title

Thehtmltitleforthepage.

theme

SwaggerUIthemetobeused.

footer

Afooterforthehtmlpage.Nothingbydefault.

deep-linking

Enablesdeeplinkingfortagsandoperations.

display-operation-id

ControlsthedisplayofoperationIdinoperationslist.

default-models-expand-depth

Thedefaultexpansiondepthformodels.

default-model-expand-depth

Thedefaultexpansiondepthforthemodelonthemodel-examplesection.

default-model-rendering

ControlshowthemodelisshownwhentheAPIis�rstrendered.

display-request-duration

Controlsthedisplayoftherequestduration(inmilliseconds)for"Tryitout"requests.

doc-expansion

Controls the default expansion setting for the operations andtags.

filter

Enables�ltering.

max-displayed-tags

Limitsthenumberoftaggedoperationsdisplayedtoatmostthismany.

operations-sorter

Apply a sort to the operation list of each API. (alpha , method ,function )

show-extensions

Controlsthedisplayofvendorextension.

show-common-extensions

Page 52: Quarkus Cheat-Sheet

Controlsthedisplayofextensions.

tag-sorter

ApplyasorttothetaglistofeachAPI.

on-complete

Provides a mechanism to be noti�ed when Swagger UI has�nishedrenderinganewlyprovidedde�nition.

syntax-highlight

Set to false to deactivate syntax highlighting of payloads andcURLcommand.

oauth2-redirect-url

OAuthredirectURL.

request-interceptor

Functiontointerceptremotede�nition,"Tryitout",andOAuth2.0requests.

request-curl-options

Arrayofcommandlineoptionsavailabletothecurlcommand.

response-interceptor

Functiontointerceptremotede�nition,"Tryitout",andOAuth2.0responses.

show-mutated-request

Usesthemutatedrequest returnedfromarequestInterceptor toproducethecurlcommandintheUI.

supported-submit-methods

ListofHTTPmethodsthathavethe"Tryitout"featureenabled.

validator-url

Swagger UI attempts to validate specs against swagger.io’sonlinevalidator.

with-credentials

Enablespassingcredentials,asde�nedintheFetchstandard,inCORSrequeststhataresentbythebrowser.

model-property-macro

Functiontosetdefaultvaluestoeachpropertyinmodel.

parameter-macro

Functiontosetdefaultvaluetoparameters.

persist-authorization

Itpersistsauthorizationdataanditwouldnotbelostonbrowserclose/refresh.

layout

Thenameofacomponentavailableviathepluginsystemtouseasthetop-levellayoutforSwaggerUI.

plugins

AlistofpluginfunctionstouseinSwaggerUI.

presets

AlistofpresetstouseinSwaggerUI.

YoucancustomizetheoutputbyusingOpenAPIv3annotations.

@Schema(name="Developers",description="POJOthatrepresentsadeveloper.")

publicclassDeveloper{@Schema(required=true,example="Alex")privateStringname;}

@POST@Path("/developer")@Operation(summary="Createdeeloper",description="Onlybedonebyadmin.")

publicResponsecreateDeveloper(@RequestBody(description="Developerobject",

required=true,content=@Content(schema=

@Schema(implementation=Developer.class)))

Developerdeveloper)

All possible annotations can be seen atorg.eclipse.micropro�le.openapi.annotationspackage.

You can also serve OpenAPI Schema from static �les instead ofdynamicallygeneratedfromannotationscanning.

You need to put OpenAPIdocumentation under META-INF directory(ie:META-INF/openapi.yaml ).

Arequestto /openapi willserve thecombinedOpenAPIdocumentfrom the static �le and the generated from annotations. You candisable the scanningdocumentsby adding the next con�gurationproperty:mp.openapi.scan.disable=true .

Other valid document paths are: META-INF/openapi.yml , META-

INF/openapi.json , WEB-INF/classes/META-INF/openapi.yml , WEB-

INF/classes/META-INF/openapi.yaml , WEB-INF/classes/META-

INF/openapi.json .

You can store generated OpenAPI schema if quarkus.swagger-

ui.store-schema-directory isset.

PossibleOpenAPIoptionswithquarkus.smallrye-openapi pre�x:

pathThe path at which to register the OpenAPI Servlet. (default:openapi )

store-schema-directoryThegeneratedOpenAPI schemadocumentswill be storedhereonbuild.

security-schemeAdd a certain SecurityScheme with con�g. (basic , jwt , oidc ,oauth2Implicit )

security-scheme-name

Add a Security Scheme name to the generated OpenAPIdocument.(default:SecurityScheme )

security-scheme-descriptionAdd a description to the Security Scheme. (default:Authentication )

basic-security-scheme-valueAdd a scheme value to the Basic HTTP Security Scheme.(default:basic )

jwt-security-scheme-valueAdd a scheme value to the JWT Security Scheme. (default:bearer )

jwt-bearer-formatAddabearerformattotheJWTSecurityScheme.(default:JWT )

oidc-open-id-connect-urlAddaopenIdConnectUrlvaluetotheOIDCSecurityScheme

oauth2-implicit-refresh-urlAdd a implicit �ow refreshUrl value to the OAuth2 SecurityScheme

oauth2-implicit-authorization-urlAddanimplicit�owauthorizationUrlvaluetotheOAuth2SecurityScheme

oauth2-implicit-token-urlAdd an implicit �ow tokenUrl value to the OAuth2 SecurityScheme

MailSender

YoucansendemailsbyusingQuarkusMailerextension:

./mvnwquarkus:add-extension

-Dextensions="io.quarkus:quarkus-mailer"

You can inject two possible classes io.quarkus.mailer.Mailer forsynchronous API or io.quarkus.mailer.reactive.ReactiveMailer forasynchronous/reactiveAPI.

@InjectMailermailer;

Andthenyoucanusethemtosendanemail:

mailer.send(

Mail.withText("[email protected]","Subject","Body")

);

ReactiveMailclient

Page 53: Quarkus Cheat-Sheet

@InjectReactiveMailerreactiveMailer;

CompletionStage<Response>stage=

reactiveMailer.send(

Mail.withText("[email protected]","Subject","Body")

)

.subscribeAsCompletionStage()

.thenApply(x->Response.accepted().build());

If you are using quarkus-resteasy-mutiny , you can returnio.smallrye.mutiny.Uni type.

Mail class contains methods to add cc , bcc , headers , bounce

address ,replyto ,attachments ,inlineattachments andhtmlbody .

mailer.send(Mail.withHtml("[email protected]","Subject",body)

.addInlineAttachment("quarkus.png",

newFile("quarkus.png"),"image/png","<[email protected]>"));

If you need deep control you can inject Vert.xmail client@InjectMailClientclient;

Youneedtocon�gureSMTPpropertiestobeabletosendanemail:

[email protected]=smtp.sendgrid.netquarkus.mailer.port=465quarkus.mailer.ssl=truequarkus.mailer.username=....quarkus.mailer.password=....

ListofMailerparameters.quarkus. asapre�xisskippedinthenexttable.

Parameter Default Description

mailer.from Defaultaddress.

mailer.mockfalse in prod , true indev andtest .

Emails not sent, justprinted and stored inaMockMailbox .

mailer.bounce-

addressDefaultaddress.

mailer.host mandatory SMTPhost.

mailer.port 25 SMTPport.

mailer.username Theusername.

Parameter Default Description

mailer.password Thepassword.

mailer.ssl false EnablesSSL.

mailer.trust-all false Trustallcerti�cates.

mailer.max-pool-size 10 Max openconnections.

mailer.own-host-name

Hostname forHELO/EHLO andMessage-ID

mailer.keep-alive trueConnection poolenabled.

mailer.disable-esmtp false DisableESMTP.

mailer.start-tls OPTIONAL

TLS security mode.DISABLED , OPTIONAL ,REQUIRED .

mailer.login NONELogin mode. NONE ,OPTIONAL ,REQUIRED .

mailer.auth-methods Allmethods. Space-separatedlist.

mailer.key-store Pathofthekeystore.

mailer.key-store-

passwordKeystorepassword.

if you enable SSL for themailer and you want to build anativeexecutable,youwillneedtoenabletheSSLsupportquarkus.ssl.native=true .

Testing

If quarkus.mailer.mock is set to true , which is the default value indev and test mode, you can inject MockMailbox to get the sentmessages.

@InjectMockMailboxmailbox;

@BeforeEachvoidinit(){mailbox.clear();

}

List<Mail>sent=mailbox

.getMessagesSentTo("[email protected]");

ScheduledTasks

YoucanscheduleperiodictaskswithQuarkus.

@ApplicationScopedpublicclassCounterBean{

@Scheduled(every="10s",delayed="1s")voidincrement(){}

@Scheduled(cron="01510**?")voidmorningTask(){}}

every and cron parameters can be surrounded with {} and thevalueisusedascon�gpropertytogetthevalue.

@Scheduled(cron="{morning.check.cron.expr}")

voidmorningTask(){}

Andcon�gurethepropertyintoapplication.properties :

morning.check.cron.expr=01510**?

BydefaultQuarkusexpresion isused,butyoucanchange thatbysettingquarkus.scheduler.cron-type property.

quarkus.scheduler.cron-type=unix

org.quartz.Scheduler can be injected as any other bean andscehdulejobsprogrammatically.

@Injectorg.quartz.Schedulerquartz;

quartz.scheduleJob(job,trigger);

Kogito

Quarkus integrates with Kogito, a next-generation businessautomation toolkit from Drools and jBPM projects for addingbusinessautomationcapabilities.

Page 54: Quarkus Cheat-Sheet

Tostartusingityouonlyneedtoaddthenextextension:

./mvnwquarkus:add-extension

-Dextensions="kogito"

ApacheTika

Quarkus integrates with Apache Tika to detect and extractmetadata/textfromdifferent�letypes:

./mvnwquarkus:add-extension

-Dextensions="quarkus-tika"

@Injectio.quarkus.tika.TikaParserparser;

@POST@Path("/text")@Consumes({"text/plain","application/pdf","application/vnd.oasis.opendocument.text"})

@Produces(MediaType.TEXT_PLAIN)publicStringextractText(InputStreamstream){returnparser.parse(stream).getText();}

You can con�gure Apache Tika in application.properties �le byusingnextpropertiespre�xedwithquarkus :

Parameter Default Description

tika.tika-config-

pathtika-config.xml

Path to the Tikacon�gurationresource.

quarkus.tika.parsers

CSV of theabbreviated or fullparser class to beloaded by theextension.

tika.append-embedded-

contenttrue

The document mayhaveotherembeddeddocuments. Set ifautmaticallyappend.

JGit

QuarkusintegrateswithJGittointegratewithGitrepositories:

./mvnwquarkus:add-extension

-Dextensions="quarkus-jgit"

AndthenyoucanstartusingJGit:

try(Gitgit=Git.cloneRepository().setDirectory(tmpDir)

.setURI(url)

.call()){

returntmpDir.toString();}

Whenrunning innativemode,makesure tocon�gureSSLaccesscorrectlyquarkus.ssl.native=true (NativeandSSL).

WebResources

YoucanservewebresourceswithQuarkus.Youneedtoplacewebresources at src/main/resources/META-INF/resources and then theyareaccessible(iehttp://localhost:8080/index.html)

Bydefault static resources as servedunder the root context. Youcanchangethisbyusingquarkus.http.root-path property.

TransactionalMemory

QuarkusintegrateswiththeSoftwareTransactionalMemory(STM)implementationprovidedbytheNarayanaproject.

./mvnwquarkus:add-extension

-Dextensions="narayana-stm"

Transactional objects must be interfaces and annotated withorg.jboss.stm.annotations.Transactional .

@Transactional@NestedTopLevelpublicinterfaceFlightService{intgetNumberOfBookings();voidmakeBooking(Stringdetails);}

The pessimistic strategy is the default one, you can change tooptimisticbyusing@Optimistic .

Thenyouneedtocreatetheobjectinsideorg.jboss.stm.Container .

Container<FlightService>container=newContainer<>();FlightServiceImplinstance=newFlightServiceImpl();FlightServiceflightServiceProxy=container.create(instanc

e);

Theimplementationoftheservicesetsthelockingandwhatneedstobesaved/restored:

importorg.jboss.stm.annotations.ReadLock;importorg.jboss.stm.annotations.State;importorg.jboss.stm.annotations.WriteLock;

publicclassFlightServiceImplimplementsFlightService{@StateprivateintnumberOfBookings;

@ReadLockpublicintgetNumberOfBookings(){returnnumberOfBookings;}

@WriteLockpublicvoidmakeBooking(Stringdetails){numberOfBookings+=1;

}

}

Any member is saved/restored automatically (@State is notmandatory).Youcanuse@NotState toavoidbehaviour.

Transactionboundaries

Declarative

@NestedTopLevel : De�nes that the containerwill create a newtop-leveltransactionforeachmethodinvocation.

@Nested :De�nesthatthecontainerwillcreateanewtop-levelornestedtransactionforeachmethodinvocation.

Programmatically

AtomicActionaa=newAtomicAction();

aa.begin();

{

try{flightService.makeBooking("BA123...");

taxiService.makeBooking("EastCoastTaxis...");

aa.commit();

}catch(Exceptione){aa.abort();

}

}

Quartz

Quarkus integrates with Quartz to schedule periodic clusteredtasks.

./mvnwquarkus:add-extension

-Dextensions="quartz"

Page 55: Quarkus Cheat-Sheet

@ApplicationScopedpublicclassTaskBean{

@Transactional@Scheduled(every="10s")voidschedule(){Tasktask=newTask();task.persist();

}

}

Tocon�gureinclusteredmodevidaDataSource:

quarkus.datasource.url=jdbc:postgresql://localhost/quarkus_

test

quarkus.datasource.driver=org.postgresql.Driver

#...

quarkus.quartz.clustered=true

quarkus.quartz.store-type=db

Youneedtode�nethedatasourceusedbyclusteredmodeand also import the database tables following the Quartzschema.

Quartz can be con�gured usinf the following properties withquarkus.quartz pre�x:

clustered

Enableclustermodeornot.

store-type

Thetypeofstoretouse.Possiblevalues:ram ,db (default:ram )

datasource

Thenameofthedatasourcetouse.

table-prefix

Thepre�xforquartzjobstoretables.(default:QRTZ_ )

trigger-listeners.<name>.class

Classnameforthetrigger.

trigger-listeners.<name>.property-name

Thepropertiespassedtotheclass.

job-listeners.<name>.class

Classnameforthejob.

job-listeners.<name>.property-name

Thepropertiespassedtotheclass.

plugins.<name>.class

Classnamefortheplugin.

plugins.<name>.property-name

The properties passed to the class

instance-name

The name of the Quartz instance. (default:QuarkusQuartzScheduler )

thread-count

Thesizeofschedulerthreadpool.(default:25 )

thread-priority

Threadpriorityofworkerthreadsinthepool.(default:5 )

force-start

The scheduler will be started even if no scheduled businessmethodsarefound.

start-mode

Scheduler can be started in different modes: normal , forced orhalted .(default:normal )

Qute

Qute is a templating engine designed speci�cally to meet theQuarkus needs. Templates should be placed by default atsrc/main/resources/templates aandsubdirectories.

./mvnwquarkus:add-extension

-Dextensions="quarkus-resteasy-qute"

Templatescanbede�nedinanyformat,incaseofHTML:

item.html

{@org.acme.Itemitem}

<!DOCTYPEhtml><html>

<head>

<metacharset="UTF-8">

<title>{item.name}</title>

</head>

<body>

<h1>{item.name?:'Unknown'}</h1>

<h2>{str:reverse('Hello')}</h2>

<div>Price:{item.price}</div>

{#ifitem.price>100}

<div>DiscountedPrice:{item.discountedPrice}</div>

{/if}

</body>

</html>

First line is notmandatory but helpsondoingproperty checksatcompilationtime.

Includingtemplatespassingparameters:

<html>

<head>

<metacharset="UTF-8">

<title>SimpleInclude</title>

</head>

<body>

{#includefoolimit=10/}

</body>

</html>

Torenderthetemplate:

publicclassItem{publicStringname;publicBigDecimalprice;}

@Injectio.quarkus.qute.Templateitem;

@GET@Path("{id}")@Produces(MediaType.TEXT_HTML)publicTemplateInstanceget(@PathParam("id")Integerid){returnitem.data("item",service.findItem(id));}

@TemplateExtensionstaticBigDecimaldiscountedPrice(Itemitem){returnitem.price.multiply(newBigDecimal("0.9"));}

@TemplateExtension(namespace="str")publicstaticclassStringExtensions{staticStringreverse(Stringval){returnnewStringBuilder(val).reverse().toString();}

}

If@ResourcePath isnotusedinTemplate thenthenameofthe�eldisused as �le name. In this case the �le should besrc/main/resources/templates/item.{} . Extension of the �le is notrequiredtobeset.

discountedPrice is not a �eld of the POJO but a method call.Methodde�nitionmust be annotatedwith @TemplateExtension andbestaticmethod.Firstparameterisusedtomatchthebaseobject(Item ).@TemplateExtension canbeusedatclasslevel:

@TemplateExtensionpublicclassMyExtensions{staticBigDecimaldiscountedPrice(Itemitem){returnitem.price.multiply(newBigDecimal("0.9"));}

}

Methodswithmultipleparametersaresupportedtoo:

Page 56: Quarkus Cheat-Sheet

{item.discountedPrice(2)}

staticBigDecimaldiscountedPrice(Itemitem,intscale){returnitem.price.multiply(scale);}

Qute for syntax supports any instance of Iterable , Map.EntrySet ,Stream orInteger .

{#foriintotal}

{i}:

{/for}

Thenextmapmethodsaresupported:

{#forkeyinmap.keySet}

{#forvalueinmap.values}

{map.size}

{#ifmap.isEmpty}

{map['foo']

Thenextlistmethodsaresupported:

{list[0]}

Thenextnumbermethodsaresupported:

{#ifcounter.mod(5)==0}

Switch/When

{#switchperson.name}

{#case'John'}

HeyJohn!

{#case'Mary'}

HeyMary!

{/switch}

{#whenitems.size}

{#is1}(1)Thereisexactlyoneitem!

{#is>10}(2)Therearemorethan10items!

{#else}(3)Thereare2-10items!

{/when}

Followingoperatorscanbeusedeitherinwhen and switch : not,ne,!= ,gt,> ,ge,>= ,lt,< ,le,<= ,in ,ni,!in .

MessageBundling

@io.quarkus.qute.i18n.MessageBundlepublicinterfaceAppMessages{@io.quarkus.qute.i18n.Message("Hello{name}!")Stringhello_name(Stringname);}

Thereare3methodstoinjectthemessage:

MessageBundles.get(AppMessages.class).hello_name("Lucie");

or

@InjectAppMessagesapp;

app.hello_name("Lucie");

or

<p>{msg:hello_name('Lucie')}</p>

Localization

Therearetwowaystosetlocalizedmessage:

@io.quarkus.qute.i18n.Localized("de")publicinterfaceGermanAppMessages{

@[email protected]("Hallo{name}!")Stringhello_name(Stringname);}

or

msg_de.properties

hello_name=Hallo{name}!

Youcanrenderprogrammaticalythetemplatestoo:

//filelocatedatsrc/main/resources/templates/reports/v1/

report_01.{}

@ResourcePath("reports/v1/report_01")Templatereport;

Stringoutput=report

.data("samples",service.get())

.render();

ValueResolvers

Valueresolversareinvokedwhenevaluatingexpressions.

voidconfigureEngine(@ObservesEngineBuilderbuilder){builder.addValueResolver(ValueResolver.builder()

.appliesTo(ctx->ctx.getBase()instanceofLong&&ctx.getName().equals("tenTimes"))

.resolveSync(ctx->(Long)ctx.getBase()*10)

.build());

}

ContentFilters

Content�lterscanbeusedtomodifythetemplatecontentsbeforeparsing.

voidconfigureEngine(@ObservesEngineBuilderbuilder){builder.addParserHook(newParserHook(){@OverridepublicvoidbeforeParsing(ParserHelperparserHelper){

parserHelper.addContentFilter(contents->content

s.replace("${","$\\{"));

}

});

}

ReactiveandAsync

CompletionStage<String>async=report.renderAsync();

Multi<String>publisher=report.createMulti();

Uni<String>content=io.smallrye.mutiny.Uni.createFrom()

.completionStage(()->report.r

enderAsync());

QuteMailIntegration

@InjectMailTemplatehello;

CompletionStage<Void>c=hello.to("[email protected]")

.subject("HellofromQutetemplate")

.data("name","John")

.send();

INFO: Template located at src/main/resources/templates/hello.

[html|txt] .

Sentry

Quarkus integrates with Sentry for logging errors into an errormonitoringsystem.

./mvnwquarkus:add-extension

-Dextensions="quarkus-logging-sentry"

Page 57: Quarkus Cheat-Sheet

And the con�guration to send all errors occuring in the packageorg.example toSentrtywithDSNhttps://[email protected]/1234 :

quarkus.log.sentry=truequarkus.log.sentry.dsn=https://[email protected]/1234quarkus.log.sentry.level=ERRORquarkus.log.sentry.in-app-packages=org.example

Fulllistofcon�gurationpropertieshavingquarkus.log aspre�x:

sentry.enable

EnabletheSentryloggingextension(default:false)

sentry.dsn

Wheretosendevents.

sentry.level

Loglevel(default:WARN )

sentry.server-name

Setstheservernamethatwillbesentwitheachevent.

sentry.in-app-packages

Con�gurewhichpackagepre�xesyourapplicationuses.

JSch

QuarkusintegrateswithJschforSSHcommunication.

./mvnwquarkus:add-extension

-Dextensions="quarkus-jsch"

JSchjsch=newJSch();Sessionsession=jsch.getSession(null,host,port);session.setConfig("StrictHostKeyChecking","no");

session.connect();

Cache

Quarkuscancachemethodcallsbyusingaskeythetuple(method+arguments).

./mvnwquarkus:add-extension

-Dextensions="cache"

@io.quarkus.cache.CacheResult(cacheName="weather-cache")publicStringgetDailyForecast(LocalDatedate,Stringcity){}

@CacheInvalidate removes the element represented by thecalculatedcachekey fromcache. @CacheInvalidateAll removesallentriesfromthecache. @CacheKey tospeci�callysetthearguments

b d k d f ll

@ApplicationScopedpublicclassCachedBean{

@CacheResult(cacheName="foo")publicObjectload(Objectkey){}

@CacheInvalidate(cacheName="foo")publicvoidinvalidate(Objectkey){}

@CacheInvalidateAll(cacheName="foo")publicvoidinvalidateAll(){}}

You can disable the caching system by settingquarkus.cache.enabled propertytofalse .

ThisextensionusesCaffeineasitsunderlyingcachingprovider.

Eachcachecanbecon�guredindividually:

quarkus.cache.caffeine."foo".initial-capacity=10quarkus.cache.caffeine."foo".maximum-size=20quarkus.cache.caffeine."foo".expire-after-write

quarkus.cache.caffeine."bar".maximum-size=1000

Full list of con�guration properties having quarkus.cache.caffeine.[cache-name] aspre�x:

initial-capacity

Minimumtotalsizefortheinternaldatastructures.

maximum-size

Maximumnumberofentriesthecachemaycontain.

expire-after-write

Speci�esthateachentryshouldbeautomaticallyremovedfromthe cache once a �xed duration has elapsed after the entry’screation,orlastwrite.

expire-after-access

Speci�esthateachentryshouldbeautomaticallyremovedfromthe cache once a �xed duration has elapsed after the entry’screation,orlastwrite.

Youcanmultiplecacheannotationsonasinglemethod.

If you see a javax.enterprise.context.ContextNotActiveException ,you need to add the quarkus-smallrye-context-propagation

extension.

Banner

Bannerisprintedbydefault.Itisnotanextensionbutplacedinthecore.

quarkus.banner.path

Path is relative to root of the classpath. (default:)

quarkus.banner.enabled

Enablesbanner.(default:true )

OptaPlanner

QuarkusintegrateswithOptaPlanner.

./mvnwquarkus:add-extension

-Dextensions="quarkus-optaplanner,quarkus-optaplanner-ja

ckson"

@PlanningSolutionpublicclassTimeTable{}

@InjectprivateSolverManager<TimeTable,UUID>solverManager;

UUIDproblemId=UUID.randomUUID();

SolverJob<TimeTable, UUID> solverJob = solverManager.solve

(problemId,problem);

TimeTablesolution=solverJob.getFinalBestSolution();

Possiblecon�gurationoptionspre�xedwithquarkus.optaplanner :

solver-config-xml

Aclasspath resource to read thesolver con�gurationXML.Notmandatory.

solver.environment-mode

Enable runtime assertions to detect common bugs in yourimplementation during development. Possible values:FAST_ASSERT , FULL_ASSERT , NON_INTRUSIVE_FULL_ASSERT ,NON_REPRODUCIBLE ,REPRODUCIBLE .(default:REPRODUCIBLE )

solver.move-thread-count

Enable multithreaded solving for a single problem. Possiblevalues: MOVE_THREAD_COUNT_NONE , MOVE_THREAD_COUNT_AUTO ,anumberor formula based on the available processors. (default:MOVE_THREAD_COUNT_NONE )

solver.termination.spent-limit

Howlongthesolvercanrun.(ie5s )

solver.termination.unimproved-spent-limit

Howlongthesolvercanrunwithout�ndinganewbestsolutionafter�ndinganewbestsolution.(ie2h )

solver.termination.best-score-limit

Terminates thesolverwhenaspeci�corhigherscorehasbeenreached.(ie0hard/-1000soft )

solver-manager.parallel-solver-count

The number of solvers that run in parallel. (default:PARALLEL_SOLVER_COUNT_AUTO )

Context Propagation

Page 58: Quarkus Cheat-Sheet

./mvnwquarkus:add-extension

-Dextensions="quarkus-smallrye-context-propagation"

If using mutiny extension together you already get contextpropagation for ArC, RESTEasy and transactions. WithCompletionStage youneedto:

@InjectThreadContextthreadContext;@InjectManagedExecutormanagedExecutor;

threadContext.withContextCapture(..)

.thenApplyAsync(r->{},managedExecutor);

If youaregoing tousesecurity ina reactiveenvironmentyouwilllikelyneedSmallryeContentPropagationtopropagatetheidentitythroughoutthereactivecallback.

Con�gurationfromHasiCorpConsul

Youcanreadruntimecon�gurationfromHashiCorpConsul.

./mvnwquarkus:add-extension

-Dextensions="consul-config"

Youneedtocon�gureConsul:

quarkus.consul-config.enabled=truequarkus.consul-config.agent.host-port=localhost:8500quarkus.consul-config.properties-value-keys=config/consul-test

@ConfigProperty(name="greeting.message")Stringmessage;

InConsul:

"Key":"config/consul-test",

"Value":"greeting.message=HellofromConsul"

Possible con�guration parameters, pre�xed with quarkus.consul-config :

enabled

The application will attempt to look up the con�guration fromConsul.(default:false )

prefix

Commonpre�xthatallkeyssharewhenlookingupthekeysfromConsul. The pre�x is not included in the keys of the usercon�guration

raw-value-keys

Keyswhosevalueisarawstring.Thekeysthatendupintheusercon�gurationarethekeysspeci�edherwith'/'replacedby'.'

properties-value-keys

Keyswhosevaluerepresentsaproperties-like�leconttent.

fail-on-missing-key

If the application will not start if any of the con�gured con�gsourcescannotbelocated.(default:true )

trust-store

TrustStore to be used containing the SSL certi�cate used byConsulagent.

trust-store-password

PasswordofTrustStoretobeusedcontainingtheSSLcerti�cateusedbyConsulagent.

key-password

Password to recover key from KeyStore for SSL clientauthenticationwithConsulagent.

agent.host-port

Consulagenthost.(default:localhost:8500 )

agent.use-https

UseHTTPSwhencommunicatingwiththeagent.(default:false )

agent.token

Consultokentobeprovidedwhenauthenticationisenabled.

agent.key-store

KeyStore(classpathor�lesystem)tobeusedcontainingtheSSLcerti�cateusedbyConsulagent.

agent.key-store-password

PasswordofKeyStore.

agent.trust-certs

Totrustallcerti�catesornot.

agent.connection-timeout

Connectiontimeout.(default:10S )

agent.read-timeout

Readingtimeout.(default:60S )

AmazonAlexa

YoucanuseAmazonAlexabyaddingtheextension:

./mvnwquarkus:add-extension

-Dextensions="quarkus-amazon-alexa"

WebJarLocator

Tochangehowyoucanrefer towebjarsskipping theversionpartyoucanuseWebJarslocatorextension.

./mvnwquarkus:add-extension

-Dextensions="webjars-locator"

Then the JavaScript location is changed from/webjars/jquery/3.1.1/jquery.min.js to/webjars/jquery/jquery.min.js inyourHTML�les.

AmazonSES

mvnquarkus:add-extension

-Dextensions="amazon-ses"

@Injectsoftware.amazon.awssdk.services.ses.SesClientsesClient;

@Injectsoftware.amazon.awssdk.services.ses.SesAsyncClient sesClien

t;

quarkus.ses.endpoint-override=http://localhost:8012quarkus.ses.aws.region=us-east-1quarkus.ses.aws.credentials.type=staticquarkus.ses.aws.credentials.static-provider.access-key-id=test-key

quarkus.ses.aws.credentials.static-provider.secret-access-key=test-secret

YouneedtosetaHTTPclienteitherURLConnection :

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>url-connection-client</artifactId>

</dependency>

orApacheHTTP:

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>apache-client</artifactId>

</dependency>

quarkus.ses.sync-client.type=apache

Orasync:

Page 59: Quarkus Cheat-Sheet

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>netty-nio-client</artifactId>

</dependency>

Con�gurationpropertiesare thesameasAmazonDynamoDB butchangingthepre�xfromdynamodb toses .

Jbang

Creatinganinitialscript:

jbangscripting/quarkusapp.java

AddingQuarkusdependenciesinscript:

//DEPSio.quarkus:quarkus-resteasy:{quarkus-version}

PutsomeQuarkusCLIcode:

@Path("/hello")@ApplicationScopedpublicclassquarkusapp{@GETpublicStringsayHello(){return"hello";}

publicstaticvoidmain(String[]args){Quarkus.run(args);

}

}

Torunthescript:

jbangquarkusapp.java

AMavengoalisprovidedtoscaffoldaproject:

mvnio.quarkus:quarkus-maven-plugin:<version>:create-jbang

SpringDI

Quarkus provides a compatibility layer for Spring dependencyinjection.

./mvnwquarkus:add-extension

-Dextensions="quarkus-spring-di"

Some examples ofwhat you can do. Notice that annotations aretheSpringoriginalones.

@Configuration

publicclassAppConfiguration{

@Bean(name="capitalizeFunction")

publicStringFunctioncapitalizer(){

returnString::toUpperCase;

}

}

Orasacomponent:

@Component("noopFunction")publicclassNoOpSingleStringFunctionimplementsStringFunction{}

Also as a service and injection properties fromapplication.properties .

@ServicepublicclassMessageProducer{

@Value("${greeting.message}")Stringmessage;

}

Andyoucaninjectusing Autowired orconstructor inacomponentandinaJAX-RSresourcetoo.

@ComponentpublicclassGreeterBean{

privatefinalMessageProducermessageProducer;

@Autowired@Qualifier("noopFunction")StringFunctionnoopStringFunction;

publicGreeterBean(MessageProducermessageProducer){this.messageProducer=messageProducer;}

}

SpringBootCon�guration

Quarkus provides a compatibility layer for Spring BootConfigurationProperties .

./mvnwquarkus:add-extension

-Dextensions="quarkus-spring-boot-properties"

@ConfigurationProperties("example")publicfinalclassClassProperties{

privateStringvalue;privateAnotherClassanotherClass;

//getters/setters

}

example.value=class-valueexample.anotherClass.value=true

SpringCloudCon�gClient

Quarkus integrates Spring Cloud Con�g Client and MicroPro�leCon�gspec.

./mvnwquarkus:add-extension

-Dextensions="quarkus-spring-cloud-config-client"

Youneedtocon�guretheextension:

quarkus.spring-cloud-config.uri=http://localhost:8089quarkus.spring-cloud-config.username=userquarkus.spring-cloud-config.password=passquarkus.spring-cloud-config.enabled=true

@ConfigProperty(name="greeting.message")Stringgreeting;

Pre�xisquarkus.spring-cloud-config .

uri

Base URI where the Spring Cloud Con�g Server is available.(default:localhost:8888 )

username

Username to be used if the Con�g Server has BASIC Authenabled.

password

Password to be used if the Con�g Server has BASIC Authenabled.

Page 60: Quarkus Cheat-Sheet

enabled

Enables read con�guration from Spring Cloud Con�g Server.(default:false )

fail-fast

True to not start application if cannot access to the server.(default:false )

connection-timeout

The amount of time to wait when initially establishing aconnectionbeforegivingupandtimingout.(default:10S )

read-timeout

The amount of time to wait for a read on a socket before anexceptionisthrown.(default:60S )

label

Thelabeltobeusedtopullremotecon�gurationproperties.

SpringWeb

QuarkusprovidesacompatibilitylayerforSpringWeb.

./mvnwquarkus:add-extension

-Dextensions="quarkus-spring-web"

Speci�cally supports the REST related features. Notice thatinfrastructurethingslikeBeanPostProcessor willnotbeexecuted.

@RestController@RequestMapping("/greeting")publicclassGreetingController{

privatefinalGreetingBeangreetingBean;

publicGreetingController(GreetingBeangreetingBean){this.greetingBean=greetingBean;}

@GetMapping("/{name}")publicGreetinghello(@PathVariable(name="name")Stringname){

returnnewGreeting(greetingBean.greet(name));}

}

Supported annotations are: RestController , RequestMapping ,GetMapping , PostMapping , PutMapping , DeleteMapping , PatchMapping ,RequestParam , RequestHeader , MatrixVariable , PathVariable ,CookieValue , RequestBody , ResponseStatus , ExceptionHandler andRestControllerAdvice .

If you scaffold theprojectwith spring-web extension, thenSpringWeb annotations are sed in the generated project.mvnio.quarkus:quarkus-maven-plugin:1.13.0.Final:create…-

Dextensions="spring-web" .

The next return types are supported:org.springframework.http.ResponseEntity andjava.util.Map .

The next parameter types are supported: An Exception argumentand ServletRequest/HttpServletRequest (adding quarkus-undertow

dependency).

SpringDataJPA

While users are encouraged to useHibernate ORMwith Panachefor Relational Database access, Quarkus provides a compatibilitylayerforSpringDataJPArepositories.

./mvnwquarkus:add-extension

-Dextensions="quarkus-spring-data-jpa"

INFO:OfcourseyoustillneedtoaddtheJDBCdriver,andcon�gureitinapplication.properties .

publicinterfaceFruitRepositoryextendsCrudRepository<Fruit,Long>{List<Fruit>findByColor(Stringcolor);}

AndthenyoucaninjectiteitherasshowninSpringDIorinSpringWeb.

Interfacessupported:

org.springframework.data.repository.Repository

org.springframework.data.repository.CrudRepository

org.springframework.data.repository.PagingAndSortingReposito

ry

org.springframework.data.jpa.repository.JpaRepository .

INFO: Generated repositories are automatically annotated with@Transactional .

Repositoryfragmentsisalsosupported:

publicinterfacePersonRepositoryextendsJpaRepository<Person,Long>,PersonFragment{

voidmakeNameUpperCase(Personperson);}

Userde�nedqueries:

@Query("selectmfromMoviemwherem.rating=?1")Iterator<Movie>findByRating(Stringrating);

@Modifying@Query("deletefromMoviewhererating=:rating")voiddeleteByRating(@Param("rating")Stringrating);

@Query(value="SELECTCOUNT(*),publicationYearFROMBookGROUPBYpublicationYear")

List<BookCountByYear>findAllByPublicationYear2();

interfaceBookCountByYear{intgetPublicationYear();

LonggetCount();}

Whatiscurrentlyunsupported:

Methods oforg.springframework.data.repository.query.QueryByExampleExec

utor

QueryDSLsupport

Customizingthebaserepository

java.util.concurrent.Future asreturntype

Nativeandnamedquerieswhenusing@Query

SpringDataRest

WhileusersareencouragedtouseRESTDatawithPanachefortheREST data access endpoints generation, Quarkus provides acompatibility layerforSpringDataRESTintheformofthe spring-data-rest extension.

./mvnwquarkus:add-extension

-Dextensions="spring-data-rest"

importjava.util.Optional;importorg.springframework.data.repository.CrudRepository;import org.springframework.data.rest.core.annotation.Reposi

toryRestResource;

import org.springframework.data.rest.core.annotation.RestRe

source;

@RepositoryRestResource(exported=false,path="/my-fruits")

publicinterfaceFruitsRepositoryextendsCrudRepository<Fruit,Long>{@RestResource(exported=true)Optional<Fruit>findById(Longid);@RestResource(exported=true)Iterable<Fruit>findAll();}

Page 61: Quarkus Cheat-Sheet

The spring-data-jpa extensionwillgenerateanimplementationforthisrepository.Thenthe spring-data-rest extensionwillgenerateaRESTCRUDresourceforit.

Thefollowinginterfacesaresupported:

org.springframework.data.repository.CrudRepository

org.springframework.data.repository.PagingAndSortingReposito

ry

org.springframework.data.jpa.repository.JpaRepository

SpringSecurity

QuarkusprovidesacompatibilitylayerforSpringSecurity.

./mvnwquarkus:add-extension

-Dextensions="spring-security"

You need to choose a security extension to de�ne user, roles, …such as openid-connect , oauth2 , properties-file or security-jdbcasseenatRBAC.

Then you can use Spring Security annotations to protect themethods:

@Secured("admin")@GetMappingpublicStringhello(){return"hello";}

Quarkus provides support for someof themost used features ofSpringSecurity’s@PreAuthorize annotation.

Someexamples:

hasRole

@PreAuthorize("hasRole('admin')")

@PreAuthorize("hasRole(@roles.USER)") where roles is a beande�nedwith @Component annotation and USER is a public �eldoftheclass.

hasAnyRole

@PreAuthorize("hasAnyRole(@roles.USER,'view')")

PermitandDenyAll

@PreAuthorize("permitAll()")

@PreAuthorize("denyAll()")

AnonymousandAuthenticated

@PreAuthorize("isAnonymous()")

@PreAuthorize("isAuthenticated()")

Checks if the current logged in user is the same as theusernamemethodparameter:

@PreAuthorize("#person.name == authentication.principal.username")

publicvoiddoSomethingElse(Personperson){}

Checksifcallingamethodifusercanaccess:

@PreAuthorize("@personChecker.check(#person, authenticatio

n.principal.username)")

publicvoiddoSomething(Personperson){}

@ComponentpublicclassPersonChecker{publicbooleancheck(Personperson,Stringusername){returnperson.getName().equals(username);}

}

Combiningexpressions:

@PreAuthorize("hasAnyRole('user','admin')AND#user==principal.username")

publicvoidallowedForUser(Stringuser){}

SpringCache

Quarkus provides a compatibility layer for Spring dependencyinjection.

./mvnwquarkus:add-extension

-Dextensions="spring-cache"

@org.springframework.cache.annotation.Cacheable("someCache")

publicGreetinggreet(Stringname){}

Quarkus provides compatibility with the following Spring Cacheannotations:

@Cacheable

@CachePut

@CacheEvict

SpringSchedule

Quarkus provides a compatibility layer for Spring Scheduledannotation.

./mvnwquarkus:add-extension

-Dextensions="spring-scheduled"

@org.springframework.scheduling.annotation.Scheduled(cron="*/5****?")

voidcronJob(){System.out.println("Cronexpressionhardcoded");

}

@Scheduled(fixedRate=1000)@Scheduled(cron="{cron.expr}")

Page 62: Quarkus Cheat-Sheet

Resources

https://quarkus.io/guides/

https://www.youtube.com/user/lordofthejars

Authors:

@alexsotobJavaChampionandDirectorofDevExpatRedHat

1.13.0.Final