Download - Quarkus Cheat-Sheet

Transcript
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