diff --git a/core/deployment/src/main/java/io/quarkus/deployment/console/AeshConsole.java b/core/deployment/src/main/java/io/quarkus/deployment/console/AeshConsole.java index 3eb446e39c04c..b7e144bbbdd4f 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/console/AeshConsole.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/console/AeshConsole.java @@ -86,6 +86,7 @@ public void run() { } }, "Console Shutdown Hook")); prompt = registerStatusLine(0); + } private void updatePromptOnChange(StringBuilder buffer, int newLines) { @@ -222,6 +223,26 @@ public void run() { }); // Keyboard handling conn.setStdinHandler(keys -> { + + QuarkusConsole.StateChangeInputStream redirectIn = QuarkusConsole.REDIRECT_IN; + //see if the users application wants to read the keystrokes: + int pos = 0; + while (pos < keys.length) { + if (!redirectIn.acceptInput(keys[pos])) { + break; + } + ++pos; + } + if (pos > 0) { + if (pos == keys.length) { + return; + } + //the app only consumed some keys + //stick the rest in a new array + int[] newKeys = new int[keys.length - pos]; + System.arraycopy(keys, pos, newKeys, 0, newKeys.length); + keys = newKeys; + } try { if (delegateConnection != null) { //console mode diff --git a/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleHelper.java b/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleHelper.java index b9710dc97a47a..06c2e5746427b 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleHelper.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleHelper.java @@ -47,8 +47,11 @@ public void accept(Connection connection) { connection.setStdinHandler(new Consumer() { @Override public void accept(int[] ints) { + QuarkusConsole.StateChangeInputStream redirectIn = QuarkusConsole.REDIRECT_IN; for (int i : ints) { - queue.add(i); + if (redirectIn != null && !redirectIn.acceptInput(i)) { + queue.add(i); + } } } }); diff --git a/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java b/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java index bc6b3766e88e5..faca9f2dc0e8c 100644 --- a/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java +++ b/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java @@ -1,9 +1,13 @@ package io.quarkus.dev.console; +import java.io.IOException; +import java.io.InputStream; +import java.io.InterruptedIOException; import java.io.PrintStream; import java.util.List; import java.util.Locale; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.LinkedBlockingDeque; import java.util.function.BiPredicate; import java.util.function.Consumer; @@ -52,9 +56,12 @@ public abstract class QuarkusConsole { public final static PrintStream ORIGINAL_OUT = System.out; public final static PrintStream ORIGINAL_ERR = System.err; + public final static InputStream ORIGINAL_IN = System.in; public static PrintStream REDIRECT_OUT = null; public static PrintStream REDIRECT_ERR = null; + public static StateChangeInputStream REDIRECT_IN; + protected volatile boolean userReadInProgress; public synchronized static void installRedirects() { if (redirectsInstalled) { @@ -67,8 +74,10 @@ public synchronized static void installRedirects() { QuarkusConsole.INSTANCE.isInputSupported(); REDIRECT_OUT = new RedirectPrintStream(false); REDIRECT_ERR = new RedirectPrintStream(true); + REDIRECT_IN = new StateChangeInputStream(); System.setOut(REDIRECT_OUT); System.setErr(REDIRECT_ERR); + System.setIn(REDIRECT_IN); } public synchronized static void uninstallRedirects() { @@ -86,8 +95,10 @@ public synchronized static void uninstallRedirects() { REDIRECT_ERR.close(); REDIRECT_ERR = null; } + REDIRECT_IN = null; System.setOut(ORIGINAL_OUT); System.setErr(ORIGINAL_ERR); + System.setIn(ORIGINAL_IN); redirectsInstalled = false; } @@ -176,4 +187,69 @@ public boolean isAnsiSupported() { return false; } + protected void userReadStart() { + + } + + protected void userReadStop() { + + } + + public static class StateChangeInputStream extends InputStream { + + private final LinkedBlockingDeque queue = new LinkedBlockingDeque<>(); + + private volatile boolean reading; + + public synchronized boolean acceptInput(int input) { + if (reading) { + queue.add(input); + notifyAll(); + return true; + } + return false; + } + + @Override + public synchronized int read() throws IOException { + reading = true; + try { + while (queue.isEmpty()) { + try { + wait(); + } catch (InterruptedException e) { + throw new InterruptedIOException(); + } + } + return queue.pollFirst(); + } finally { + reading = false; + } + } + + @Override + public synchronized int read(byte[] b, int off, int len) throws IOException { + reading = true; + int read = 0; + try { + while (read < len) { + while (queue.isEmpty()) { + try { + wait(); + } catch (InterruptedException e) { + throw new InterruptedIOException(); + } + } + byte byteValue = queue.poll().byteValue(); + b[read++] = byteValue; + if (byteValue == '\n' || byteValue == '\r') { + return read; + } + } + return read; + } finally { + reading = false; + } + } + } } diff --git a/docs/src/main/asciidoc/container-image.adoc b/docs/src/main/asciidoc/container-image.adoc index 2aea44b2e6930..99c3c8b002fc0 100644 --- a/docs/src/main/asciidoc/container-image.adoc +++ b/docs/src/main/asciidoc/container-image.adoc @@ -111,7 +111,7 @@ or for native: [source,properties] ---- -quarkus.buildpack.jvm-builder-image= +quarkus.buildpack.native-builder-image= ---- To use this feature, add the following extension to your project. diff --git a/docs/src/main/asciidoc/includes/devtools/prerequisites.adoc b/docs/src/main/asciidoc/includes/devtools/prerequisites.adoc index b6e8cff43f708..c64c71b5f951d 100644 --- a/docs/src/main/asciidoc/includes/devtools/prerequisites.adoc +++ b/docs/src/main/asciidoc/includes/devtools/prerequisites.adoc @@ -9,14 +9,18 @@ endif::[] * An IDE ifdef::prerequisites-ide[{prerequisites-ide}] * JDK 11+ installed with `JAVA_HOME` configured appropriately +ifndef::prerequisites-no-maven[] * Apache Maven {maven-version} +endif::[] ifdef::prerequisites-docker[] * A working container runtime (Docker or Podman) endif::[] ifdef::prerequisites-docker-compose[] * Docker and Docker Compose endif::[] +ifndef::prerequisites-no-cli[] * Optionally the xref:cli-tooling.adoc[Quarkus CLI] if you want to use it +endif::[] ifndef::prerequisites-no-graalvm[] ifndef::prerequisites-graalvm-mandatory[] * Optionally Mandrel or GraalVM installed and xref:building-native-image.adoc#configuring-graalvm[configured appropriately] if you want to build a native executable (or Docker if you use a native container build) diff --git a/docs/src/main/asciidoc/opentelemetry.adoc b/docs/src/main/asciidoc/opentelemetry.adoc index cbaa0d1c81bad..3f65c18542be5 100644 --- a/docs/src/main/asciidoc/opentelemetry.adoc +++ b/docs/src/main/asciidoc/opentelemetry.adoc @@ -12,15 +12,8 @@ distributed tracing for interactive web applications. == Prerequisites -To complete this guide, you need: - -* less than 15 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} -* Docker - - +:prerequisites-docker-compose: +include::includes/devtools/prerequisites.adoc[] == Architecture @@ -39,32 +32,24 @@ The solution is located in the `opentelemetry-quickstart` {quickstarts-tree-url} First, we need a new project. Create a new project with the following command: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=opentelemetry-quickstart \ - -DclassName="org.acme.opentelemetry.TracedResource" \ - -Dpath="/hello" \ - -Dextensions="resteasy,quarkus-opentelemetry-exporter-otlp" -cd opentelemetry-quickstart ----- +:create-app-artifact-id: opentelemetry-quickstart +:create-app-extensions: resteasy,quarkus-opentelemetry-exporter-otlp +include::includes/devtools/create-app.adoc[] -This command generates the Maven project with a REST endpoint and imports the `quarkus-opentelemetry-exporter-otlp` extension, +This command generates the Maven project and imports the `quarkus-opentelemetry-exporter-otlp` extension, which includes the OpenTelemetry support, and a gRPC span exporter for https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md[OTLP]. If you already have your Quarkus project configured, you can add the `quarkus-opentelemetry-exporter-otlp` extension to your project by running the following command in your project base directory: -[source,bash] ----- -./mvnw quarkus:add-extension -Dextensions="opentelemetry-otlp-exporter" ----- +:add-extension-extensions: opentelemetry-otlp-exporter +include::includes/devtools/extension-add.adoc[] -This will add the following to your `pom.xml`: +This will add the following to your build file: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -72,9 +57,15 @@ This will add the following to your `pom.xml`: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-opentelemetry-exporter-otlp") +---- + === Examine the JAX-RS resource -Open the `src/main/java/org/acme/opentelemetry/TracedResource.java` file and see the following content: +Create a `src/main/java/org/acme/opentelemetry/TracedResource.java` file with the following content: [source,java] ---- @@ -194,17 +185,13 @@ services: Now we are ready to run our application. If using `application.properties` to configure the tracer: -[source,bash] ----- -./mvnw compile quarkus:dev ----- +include::includes/devtools/dev.adoc[] or if configuring the OTLP gRPC endpoint via JVM arguments: -[source,bash] ----- -./mvnw compile quarkus:dev -Djvm.args="-Dquarkus.opentelemetry.tracer.exporter.otlp.endpoint=http://localhost:55680" ----- +:dev-additional-parameters: -Djvm.args="-Dquarkus.opentelemetry.tracer.exporter.otlp.endpoint=http://localhost:55680" +include::includes/devtools/dev.adoc[] +:!dev-additional-parameters: With the OpenTelemetry Collector, Jaeger system and application running, you can make a request to the provided endpoint: @@ -255,7 +242,8 @@ propagators, you can however choose any of the supported OpenTelemetry propagato The `b3`, `b3multi`, `jaeger` and `ottrace` propagators will need the https://github.com/open-telemetry/opentelemetry-java/tree/main/extensions/trace-propagators[trace-propagators] extension to be added as a dependency to your project. -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.opentelemetry @@ -263,14 +251,28 @@ extension to be added as a dependency to your project. ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.opentelemetry:opentelemetry-extension-trace-propagators") +---- + The `xray` propagator will need the https://github.com/open-telemetry/opentelemetry-java/tree/main/extensions/aws[aws] extension to be added as a dependency to your project. -[source,xml] + +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.opentelemetry opentelemetry-extension-aws ---- + +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.opentelemetry:opentelemetry-extension-aws") +---- ==== === Resource diff --git a/docs/src/main/asciidoc/opentracing.adoc b/docs/src/main/asciidoc/opentracing.adoc index fea0e7e4496dd..96c05d906f480 100644 --- a/docs/src/main/asciidoc/opentracing.adoc +++ b/docs/src/main/asciidoc/opentracing.adoc @@ -12,15 +12,8 @@ interactive web applications. == Prerequisites -To complete this guide, you need: - -* less than 15 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} -* Docker - - +:prerequisites-docker: +include::includes/devtools/prerequisites.adoc[] == Architecture @@ -39,31 +32,23 @@ The solution is located in the `opentracing-quickstart` {quickstarts-tree-url}/o First, we need a new project. Create a new project with the following command: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=opentracing-quickstart \ - -DclassName="org.acme.opentracing.TracedResource" \ - -Dpath="/hello" \ - -Dextensions="resteasy,quarkus-smallrye-opentracing" -cd opentracing-quickstart ----- +:create-app-artifact-id: opentracing-quickstart +:create-app-extensions: resteasy,quarkus-smallrye-opentracing +include::includes/devtools/create-app.adoc[] -This command generates the Maven project with a REST endpoint and imports the `smallrye-opentracing` extension, which +This command generates the Maven project and imports the `smallrye-opentracing` extension, which includes the OpenTracing support and the default https://www.jaegertracing.io/[Jaeger] tracer. If you already have your Quarkus project configured, you can add the `smallrye-opentracing` extension to your project by running the following command in your project base directory: -[source,bash] ----- -./mvnw quarkus:add-extension -Dextensions="smallrye-opentracing" ----- +:add-extension-extensions: smallrye-opentracing +include::includes/devtools/extension-add.adoc[] -This will add the following to your `pom.xml`: +This will add the following to your build file: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -71,9 +56,15 @@ This will add the following to your `pom.xml`: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-smallrye-opentracing") +---- + === Examine the JAX-RS resource -Open the `src/main/java/org/acme/opentracing/TracedResource.java` file and see the following content: +Create the `src/main/java/org/acme/opentracing/TracedResource.java` file with the following content: [source,java] ---- @@ -138,17 +129,13 @@ docker run -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16 Now we are ready to run our application. If using `application.properties` to configure the tracer: -[source,bash] ----- -./mvnw compile quarkus:dev ----- +include::includes/devtools/dev.adoc[] or if configuring the tracer via environment variables: -[source,bash] ----- -./mvnw compile quarkus:dev -Djvm.args="-DJAEGER_SERVICE_NAME=myservice -DJAEGER_SAMPLER_TYPE=const -DJAEGER_SAMPLER_PARAM=1" ----- +:dev-additional-parameters: -Djvm.args="-DJAEGER_SERVICE_NAME=myservice -DJAEGER_SAMPLER_TYPE=const -DJAEGER_SAMPLER_PARAM=1" +include::includes/devtools/dev.adoc[] +:!dev-additional-parameters: Once both the application and tracing system are started, you can make a request to the provided endpoint: @@ -204,9 +191,10 @@ The instrumentation documented in this section has been tested with Quarkus and === JDBC -The https://github.com/opentracing-contrib/java-jdbc[JDBC instrumentation] will add a span for each JDBC queries done by your application, to enable it, add the following dependency to your pom.xml: +The https://github.com/opentracing-contrib/java-jdbc[JDBC instrumentation] will add a span for each JDBC queries done by your application, to enable it, add the following dependency to your build file: -[source, xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.opentracing.contrib @@ -214,6 +202,12 @@ The https://github.com/opentracing-contrib/java-jdbc[JDBC instrumentation] will ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.opentracing.contrib:opentracing-jdbc") +---- + As it uses a dedicated JDBC driver, you must configure your datasource and Hibernate to use it. [source, properties] @@ -230,9 +224,10 @@ quarkus.hibernate-orm.dialect=org.hibernate.dialect.PostgreSQLDialect === Kafka -The https://github.com/opentracing-contrib/java-kafka-client[Kafka instrumentation] will add a span for each message sent to or received from a Kafka topic. To enable it, add the following dependency to your pom.xml: +The https://github.com/opentracing-contrib/java-kafka-client[Kafka instrumentation] will add a span for each message sent to or received from a Kafka topic. To enable it, add the following dependency to your build file: -[source, xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.opentracing.contrib @@ -240,6 +235,12 @@ The https://github.com/opentracing-contrib/java-kafka-client[Kafka instrumentati ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.opentracing.contrib:opentracing-kafka-client") +---- + It contains OpenTracing interceptors that must be registered on Kafka producers and consumers. If you followed the xref:kafka.adoc[Kafka guide], the interceptors can be added on the `generated-price` and the `prices` channels as follows: @@ -263,9 +264,10 @@ NOTE: `interceptor.classes` accept a list of classes separated by a comma. === MongoDB client -The https://github.com/opentracing-contrib/java-mongo-driver[Mongo Driver instrumentation] will add a span for each command executed by your application. To enable it, add the following dependency to your pom.xml: +The https://github.com/opentracing-contrib/java-mongo-driver[Mongo Driver instrumentation] will add a span for each command executed by your application. To enable it, add the following dependency to your build file: -[source, xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.opentracing.contrib @@ -273,6 +275,12 @@ The https://github.com/opentracing-contrib/java-mongo-driver[Mongo Driver instru ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.opentracing.contrib:opentracing-mongo-common") +---- + It contains the OpenTracing CommandListener that will be registered on the configuration of the mongo client. Following the xref:mongodb.adoc[MongoDB guide], the command listener will be registered defining the config property as follows: @@ -284,9 +292,10 @@ quarkus.mongodb.tracing.enabled=true === Zipkin compatibility mode -To enable it, add the following dependency to your pom.xml: +To enable it, add the following dependency to your build file: -[source, xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.jaegertracing @@ -294,6 +303,12 @@ To enable it, add the following dependency to your pom.xml: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.jaegertracing:jaeger-zipkin") +---- + It contains the dependencies to convert the request to zipkin format. The zipkin compatibility mode will be activated after defining the config property as follows: diff --git a/docs/src/main/asciidoc/optaplanner.adoc b/docs/src/main/asciidoc/optaplanner.adoc index b667f7e3d65f3..5fb26b1228cdf 100644 --- a/docs/src/main/asciidoc/optaplanner.adoc +++ b/docs/src/main/asciidoc/optaplanner.adoc @@ -46,12 +46,9 @@ The solution is located in {quickstarts-tree-url}/optaplanner-quickstart[the `op == Prerequisites -To complete this guide, you need: - -* about 30 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} or Gradle 4+ +:prerequisites-time: 30 minutes +:prerequisites-no-graalvm: +include::includes/devtools/prerequisites.adoc[] == The build file and the dependencies @@ -63,81 +60,75 @@ with the following extensions, for Maven or Gradle: * OptaPlanner (`optaplanner-quarkus`) * OptaPlanner Jackson (`optaplanner-quarkus-jackson`) -Alternatively, generate it from the command line with Maven: +Alternatively, generate it from the command line: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=optaplanner-quickstart \ - -Dextensions="resteasy,resteasy-jackson,optaplanner-quarkus,optaplanner-quarkus-jackson" \ - -DnoExamples -cd optaplanner-quickstart ----- +:create-app-artifact-id: optaplanner-quickstart +:create-app-extensions: resteasy,resteasy-jackson,optaplanner-quarkus,optaplanner-quarkus-jackson +include::includes/devtools/create-app.adoc[] -In Maven, your `pom.xml` file contains these dependencies: +This will include the following dependencies in your build file: -[source,xml,subs=attributes+] +[source,xml,subs=attributes+,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- - + - - io.quarkus.platform - quarkus-bom - {quarkus-version} - pom - import - - - io.quarkus.platform - quarkus-optaplanner-bom - {quarkus-version} - pom - import - + + io.quarkus.platform + quarkus-bom + {quarkus-version} + pom + import + + + io.quarkus.platform + quarkus-optaplanner-bom + {quarkus-version} + pom + import + - - + + - io.quarkus - quarkus-resteasy + io.quarkus + quarkus-resteasy - io.quarkus - quarkus-resteasy-jackson + io.quarkus + quarkus-resteasy-jackson - org.optaplanner - optaplanner-quarkus + org.optaplanner + optaplanner-quarkus - org.optaplanner - optaplanner-quarkus-jackson + org.optaplanner + optaplanner-quarkus-jackson - io.quarkus - quarkus-junit5 - test + io.quarkus + quarkus-junit5 + test - + ---- -//On the other hand, in Gradle, your `build.gradle` file contains these dependencies: -// -//[source,groovy,subs=attributes+] -//---- -//dependencies { -// implementation enforcedPlatform("io.quarkus.platform:quarkus-bom:{quarkus-version}") -// implementation enforcedPlatform("io.quarkus.platform:quarkus-optaplanner-bom:{quarkus-version}") -// implementation 'io.quarkus:quarkus-resteasy' -// implementation 'io.quarkus:quarkus-resteasy-jackson' -// implementation 'org.optaplanner:optaplanner-quarkus' -// implementation 'org.optaplanner:optaplanner-quarkus-jackson' -// -// testImplementation 'io.quarkus:quarkus-junit5' -//} -//---- +[source,gradle,subs=attributes+,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +dependencies { + implementation enforcedPlatform("io.quarkus.platform:quarkus-bom:{quarkus-version}") + implementation enforcedPlatform("io.quarkus.platform:quarkus-optaplanner-bom:{quarkus-version}") + implementation 'io.quarkus:quarkus-resteasy' + implementation 'io.quarkus:quarkus-resteasy-jackson' + implementation 'org.optaplanner:optaplanner-quarkus' + implementation 'org.optaplanner:optaplanner-quarkus-jackson' + + testImplementation 'io.quarkus:quarkus-junit5' +} +---- == Model the domain objects @@ -680,10 +671,7 @@ quarkus.optaplanner.solver.termination.spent-limit=5s First start the application: -[source,shell] ----- -$ ./mvnw compile quarkus:dev ----- +include::includes/devtools/dev.adoc[] === Try the application @@ -732,14 +720,22 @@ To test each constraint in isolation, use a `ConstraintVerifier` in unit tests. It tests each constraint's corner cases in isolation from the other tests, which lowers maintenance when adding a new constraint with proper test coverage. -Add a `optaplanner-test` dependency in your `pom.xml`: -[source,xml] +Add a `optaplanner-test` dependency in your build file: + +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- - - org.optaplanner - optaplanner-test - test - + + org.optaplanner + optaplanner-test + test + +---- + +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +testImplementation("org.optaplanner:optaplanner-test") ---- Create the `src/test/java/org/acme/optaplanner/solver/TimeTableConstraintProviderTest.java` class: diff --git a/docs/src/main/asciidoc/quartz.adoc b/docs/src/main/asciidoc/quartz.adoc index 35acd9d04782f..13f85c9be91e6 100644 --- a/docs/src/main/asciidoc/quartz.adoc +++ b/docs/src/main/asciidoc/quartz.adoc @@ -17,13 +17,8 @@ TIP: If you only need to run in-memory scheduler use the xref:scheduler.adoc[Sch == Prerequisites -To complete this guide, you need: - -* less than 10 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} -* Docker and Docker Compose installed on your machine +:prerequisites-docker-compose: +include::includes/devtools/prerequisites.adoc[] == Architecture @@ -42,16 +37,9 @@ The solution is located in the `quartz-quickstart` {quickstarts-tree-url}/quartz First, we need a new project. Create a new project with the following command: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=quartz-quickstart \ - -DclassName="org.acme.quartz.TaskResource" \ - -Dpath="/tasks" \ - -Dextensions="resteasy,quartz,hibernate-orm-panache,flyway,resteasy-jackson,jdbc-postgresql" -cd quartz-quickstart ----- +:create-app-artifact-id: quartz-quickstart +:create-app-extensions: resteasy,quartz,hibernate-orm-panache,flyway,resteasy-jackson,jdbc-postgresql +include::includes/devtools/create-app.adoc[] It generates: @@ -59,22 +47,19 @@ It generates: * a landing page accessible on `http://localhost:8080` * example `Dockerfile` files for both `native` and `jvm` modes * the application configuration file -* an `org.acme.quartz.TaskResource` resource -* an associated test The Maven project also imports the Quarkus Quartz extension. If you already have your Quarkus project configured, you can add the `quartz` extension to your project by running the following command in your project base directory: -[source,bash] ----- -./mvnw quarkus:add-extension -Dextensions="quartz" ----- +:add-extension-extensions: quartz +include::includes/devtools/extension-add.adoc[] -This will add the following to your `pom.xml`: +This will add the following to your build file: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -82,6 +67,12 @@ This will add the following to your `pom.xml`: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-quartz") +---- + [TIP] ==== To use a JDBC store, the `quarkus-agroal` extension, which provides the datasource support, is also required. @@ -234,9 +225,9 @@ quarkus.flyway.baseline-description=Quartz 1. Indicate that the scheduler will be run in clustered mode 2. Use the database store to persist job related information so that they can be shared between nodes -== Updating the resource and the test +== Creating a REST resource and a test -Edit the `TaskResource` class, and update the content to: +Create the `org.acme.quartz.TaskResource` class with the following content: [source,java] ---- @@ -260,7 +251,7 @@ public class TaskResource { ---- 1. Retrieve the list of created tasks from the database -We also need to update the tests. Edit the `TaskResourceTest` class to match: +You also have the option to create a `org.acme.quartz.TaskResourceTest` test with the following content: [source,java] ---- @@ -386,15 +377,29 @@ docker-compose up postgres <1> == Run the application in Dev Mode -Run the application with: `./mvnw quarkus:dev`. +Run the application with: + +include::includes/devtools/dev.adoc[] + After a few seconds, open another terminal and run `curl localhost:8080/tasks` to verify that we have at least one task created. -As usual, the application can be packaged using `./mvnw clean package` and executed using the `target/quarkus-app/quarkus-run.jar` file. -You can also generate the native executable with `./mvnw clean package -Pnative`. +As usual, the application can be packaged using: + +include::includes/devtools/build.adoc[] + +and executed with `java -jar target/quarkus-app/quarkus-run.jar`. + +You can also generate the native executable with: + +include::includes/devtools/build-native.adoc[] == Packaging the application and run several instances -The application can be packaged using `./mvnw clean package`. Once the build is successful, run the below command: +The application can be packaged using: + +include::includes/devtools/build.adoc[] + +Once the build is successful, run the below command: [source,bash] ---- @@ -405,7 +410,9 @@ docker-compose up --scale tasks=2 --scale nginx=1 <1> After a few seconds, in another terminal, run `curl localhost:8080/tasks` to verify that tasks were only created at different instants and in an interval of 10 seconds. -You can also generate the native executable with `./mvnw clean package -Pnative`. +You can also generate the native executable with: + +include::includes/devtools/build-native.adoc[] WARNING: It's the reponsibility of the deployer to clear/remove the previous state, i.e. stale jobs and triggers. Moreover, the applications that form the "Quartz cluster" should be identical, otherwise an unpredictable result may occur. diff --git a/docs/src/main/asciidoc/qute.adoc b/docs/src/main/asciidoc/qute.adoc index a30dbc21eaa62..6d9a8e2fa83ca 100644 --- a/docs/src/main/asciidoc/qute.adoc +++ b/docs/src/main/asciidoc/qute.adoc @@ -25,16 +25,41 @@ The solution is located in the `qute-quickstart` {quickstarts-tree-url}/qute-qui == Hello World with JAX-RS -If you want to use Qute in your JAX-RS application, you need to add the `quarkus-resteasy-qute` extension first. -In your `pom.xml` file, add: +If you want to use Qute in your JAX-RS application, you need to add an extension first: -[source,xml] +* either `quarkus-resteasy-qute` if you are using RESTEasy Classic: ++ +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus quarkus-resteasy-qute ---- ++ +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-resteasy-qute") +---- + +* or `quarkus-resteasy-reactive-qute` if you are using RESTEasy Reactive: ++ +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml +---- + + io.quarkus + quarkus-resteasy-reactive-qute + +---- ++ +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-resteasy-reactive-qute") +---- We'll start with a very simple template: diff --git a/docs/src/main/asciidoc/rabbitmq.adoc b/docs/src/main/asciidoc/rabbitmq.adoc index 47e265f842bbd..a83753c5566ce 100644 --- a/docs/src/main/asciidoc/rabbitmq.adoc +++ b/docs/src/main/asciidoc/rabbitmq.adoc @@ -13,14 +13,8 @@ include::./status-include.adoc[] == Prerequisites -To complete this guide, you need: - -* less than 15 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} -* docker and docker-compose -* GraalVM installed if you want to run in native mode. +:prerequisites-docker-compose: +include::includes/devtools/prerequisites.adoc[] == Architecture @@ -56,14 +50,10 @@ First, we need to create two projects: the _producer_ and the _processor_. To create the _producer_ project, in a terminal run: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=rabbitmq-quickstart-producer \ - -DnoCode=true \ - -Dextensions=smallrye-reactive-messaging-rabbitmq,resteasy-reactive-jackson ----- +:create-app-artifact-id: rabbitmq-quickstart-producer +:create-app-extensions: smallrye-reactive-messaging-rabbitmq,resteasy-reactive-jackson +:create-app-post-command: +include::includes/devtools/create-app.adoc[] This command creates the project structure and select the two Quarkus extensions we will be using: @@ -72,14 +62,10 @@ This command creates the project structure and select the two Quarkus extensions To create the _processor_ project, from the same directory, run: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=rabbitmq-quickstart-processor \ - -DnoCode=true \ - -Dextensions=smallrye-reactive-messaging-rabbitmq ----- +:create-app-artifact-id: rabbitmq-quickstart-processor +:create-app-extensions: smallrye-reactive-messaging-rabbitmq +:create-app-post-command: +include::includes/devtools/create-app.adoc[] At that point you should have the following structure: diff --git a/docs/src/main/asciidoc/reactive-event-bus.adoc b/docs/src/main/asciidoc/reactive-event-bus.adoc index 1f37c3fa50244..af98ddbca6866 100644 --- a/docs/src/main/asciidoc/reactive-event-bus.adoc +++ b/docs/src/main/asciidoc/reactive-event-bus.adoc @@ -25,27 +25,20 @@ However, it is limited to single-event behavior (no stream) and to local message This mechanism uses the Vert.x EventBus, so you need to enable the `vertx` extension to use this feature. If you are creating a new project, set the `extensions` parameter are follows: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=vertx-quickstart \ - -Dextensions="vertx,resteasy-mutiny" \ - -DnoExamples -cd vertx-quickstart ----- +:create-app-artifact-id: vertx-quickstart +:create-app-extensions: vertx,resteasy-mutiny +include::includes/devtools/create-app.adoc[] If you have an already created project, the `vertx` extension can be added to an existing Quarkus project with the `add-extension` command: -[source,bash] ----- -./mvnw quarkus:add-extension -Dextensions="vertx,resteasy-mutiny" ----- +:add-extension-extensions: vertx +include::includes/devtools/extension-add.adoc[] -Otherwise, you can manually add this to the dependencies section of your `pom.xml` file: +Otherwise, you can manually add this to the dependencies section of your build file: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -53,6 +46,12 @@ Otherwise, you can manually add this to the dependencies section of your `pom.xm ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-vertx") +---- + == Consuming events To consume events, use the `io.quarkus.vertx.ConsumeEvent` annotation: @@ -291,17 +290,13 @@ This message is consumed by another bean and the response is sent using the _rep First create a new project using: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=vertx-http-quickstart \ - -Dextensions="vertx" \ - -DnoExamples -cd vertx-http-quickstart ----- +:create-app-artifact-id: vertx-http-quickstart +:create-app-extensions: vertx,resteasy-mutiny +include::includes/devtools/create-app.adoc[] -You can already start the application in _dev mode_ using `./mvnw compile quarkus:dev`. +You can already start the application in _dev mode_ using: + +include::includes/devtools/dev.adoc[] Then, creates a new JAX-RS resource with the following content: @@ -381,17 +376,11 @@ To better understand, let's detail how the HTTP request/response has been handle This application can be packaged using: -[source,bash] ----- -./mvnw clean package ----- +include::includes/devtools/build.adoc[] You can also compile it as a native executable with: -[source,bash] ----- -./mvnw clean package -Pnative ----- +include::includes/devtools/build-native.adoc[] == Using codecs diff --git a/docs/src/main/asciidoc/reactive-routes.adoc b/docs/src/main/asciidoc/reactive-routes.adoc index e1838b543f68a..3ae2b1450b9b6 100644 --- a/docs/src/main/asciidoc/reactive-routes.adoc +++ b/docs/src/main/asciidoc/reactive-routes.adoc @@ -36,9 +36,10 @@ See the xref:quarkus-reactive-architecture.adoc[Quarkus Reactive Architecture do The first way to use reactive routes is to use the `@Route` annotation. To have access to this annotation, you need to add the `quarkus-reactive-routes` extension: -In your `pom.xml` file, add: +In your build file, add: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -46,6 +47,12 @@ In your `pom.xml` file, add: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-reactive-routes") +---- + Then in a _bean_, you can use the `@Route` annotation as follows: [source,java] @@ -681,14 +688,13 @@ You can add support for link:https://www.openapis.org/[OpenAPI] and link:https:/ Add the extension by running this command: -[source,bash] ----- -./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-smallrye-openapi" ----- +:add-extension-extensions: quarkus-smallrye-openapi +include::includes/devtools/extension-add.adoc[] -This will add the following to your `pom.xml`: +This will add the following to your build file: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -696,6 +702,12 @@ This will add the following to your `pom.xml`: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-smallrye-openapi") +---- + This is enough to generate a basic OpenAPI schema document from your Vert.x Routes: [source,bash] diff --git a/docs/src/main/asciidoc/redis.adoc b/docs/src/main/asciidoc/redis.adoc index c8bb68f66095d..7eb7dbf6afd62 100644 --- a/docs/src/main/asciidoc/redis.adoc +++ b/docs/src/main/asciidoc/redis.adoc @@ -13,14 +13,8 @@ include::./status-include.adoc[] == Prerequisites -To complete this guide, you need: - -* less than 15 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} +include::includes/devtools/prerequisites.adoc[] * A running Redis server, or Docker Compose to start one -* GraalVM installed if you want to run in native mode. == Architecture @@ -43,30 +37,23 @@ The solution is located in the `redis-quickstart` {quickstarts-tree-url}/redis-q First, we need a new project. Create a new project with the following command: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=redis-quickstart \ - -Dextensions="redis-client,resteasy-jackson,resteasy-mutiny" \ - -DnoExamples -cd redis-quickstart ----- +:create-app-artifact-id: redis-quickstart +:create-app-extensions: redis-client,resteasy-jackson,resteasy-mutiny +include::includes/devtools/create-app.adoc[] -This command generates a Maven project, importing the Redis extension. +This command generates a new project, importing the Redis extension. If you already have your Quarkus project configured, you can add the `redis-client` extension to your project by running the following command in your project base directory: -[source,bash] ----- -./mvnw quarkus:add-extension -Dextensions="redis-client" ----- +:add-extension-extensions: redis-client +include::includes/devtools/extension-add.adoc[] -This will add the following to your `pom.xml`: +This will add the following to your build file: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -74,6 +61,11 @@ This will add the following to your `pom.xml`: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-redis-client") +---- == Starting the Redis server @@ -256,9 +248,9 @@ public class IncrementResource { } ---- -== Modifying the test class +== Creating the test class -Edit the `src/test/java/org/acme/redis/IncrementResourceTest.java` file to the following content: +Create the `src/test/java/org/acme/redis/IncrementResourceTest.java` file with the following content: [source, java] ---- @@ -401,10 +393,7 @@ public class IncrementResourceTest { If you followed the instructions, you should have the Redis server running. Then, you just need to run the application using: -[source,bash] ----- -./mvnw quarkus:dev ----- +include::includes/devtools/dev.adoc[] Open another terminal and run the `curl http://localhost:8080/increments` command. @@ -505,10 +494,7 @@ You can run the application as a conventional jar file. First, we will need to package it: -[source,bash] ----- -./mvnw package ----- +include::includes/devtools/build.adoc[] NOTE: This command will start a Redis instance to execute the tests. Thus your Redis containers need to be stopped. @@ -530,10 +516,7 @@ Compiling a native executable takes a bit longer, as GraalVM performs additional steps to remove unnecessary codepaths. Use the `native` profile to compile a native executable: -[source,bash] ----- -./mvnw package -Pnative ----- +include::includes/devtools/build-native.adoc[] Once the build is finished, you can run the executable with: diff --git a/docs/src/main/asciidoc/rest-client-multipart.adoc b/docs/src/main/asciidoc/rest-client-multipart.adoc index 56966a8695b46..a6319e784d95b 100644 --- a/docs/src/main/asciidoc/rest-client-multipart.adoc +++ b/docs/src/main/asciidoc/rest-client-multipart.adoc @@ -15,12 +15,7 @@ requiring `multipart/form-data` content-type with very little effort. == Prerequisites -To complete this guide, you need: - -* less than 15 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} +include::includes/devtools/prerequisites.adoc[] == Solution @@ -35,16 +30,11 @@ The solution is located in the `rest-client-multipart-quickstart` {quickstarts-t First, we need a new project. Create a new project with the following command: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=rest-client-multipart-quickstart \ - -DclassName="org.acme.rest.client.multipart.MultipartClientResource" \ - -Dpath="/client" \ - -Dextensions="rest-client, resteasy, resteasy-multipart" -cd rest-client-multipart-quickstart ----- + + +:create-app-artifact-id: rest-client-multipart-quickstart +:create-app-extensions: rest-client,resteasy,resteasy-multipart +include::includes/devtools/create-app.adoc[] This command generates the Maven project with a REST endpoint and imports the `rest-client` and `resteasy` extensions. It also adds the `resteasy-multipart` extension to support `multipart/form-data` requests. @@ -157,9 +147,9 @@ Having this configuration means that all requests performed using `org.acme.rest Note that `org.acme.rest.client.multipart.MultipartService` _must_ match the fully qualified name of the `MultipartService` interface we created in the previous section. -== Update the JAX-RS resource +== Create the JAX-RS resource -Open the `src/main/java/org/acme/rest/client/multipart/MultipartClientResource.java` file and update it with the following content: +Create the `src/main/java/org/acme/rest/client/multipart/MultipartClientResource.java` file with the following content: [source,java] ---- @@ -273,8 +263,11 @@ quarkus.rest-client."org.acme.rest.client.multipart.MultipartService".url=http:/ == Package and run the application -* Run the application with: `./mvnw compile quarkus:dev`. -* In a terminal, run `curl -X POST http://localhost:8080/client/multipart` +Run the application with: + +include::includes/devtools/dev.adoc[] + +In a terminal, run `curl -X POST http://localhost:8080/client/multipart` You should see an output similar to: @@ -293,8 +286,15 @@ HELLO WORLD --89d288bd-960f-460c-b266-64c5b4d170fa-- ---- -As usual, the application can be packaged using `./mvnw clean package` and executed using the `target/quarkus-app/quarkus-run.jar` file. -You can also generate the native executable with `./mvnw clean package -Pnative`. +As usual, the application can be packaged using: + +include::includes/devtools/build.adoc[] + +And executed with `java -jar target/quarkus-app/quarkus-run.jar`. + +You can also generate the native executable with: + +include::includes/devtools/build-native.adoc[] == Further reading diff --git a/docs/src/main/asciidoc/rest-client-reactive.adoc b/docs/src/main/asciidoc/rest-client-reactive.adoc index f8dcbc26d97bb..29359c9df1e13 100644 --- a/docs/src/main/asciidoc/rest-client-reactive.adoc +++ b/docs/src/main/asciidoc/rest-client-reactive.adoc @@ -15,12 +15,7 @@ for the server part. == Prerequisites -To complete this guide, you need: - -* less than 15 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} +include::includes/devtools/prerequisites.adoc[] == Solution @@ -35,16 +30,9 @@ The solution is located in the `rest-client-reactive-quickstart` {quickstarts-tr First, we need a new project. Create a new project with the following command: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=rest-client-reactive-quickstart \ - -DclassName="org.acme.rest.client.ExtensionsResource" \ - -Dpath="/extension" \ - -Dextensions="resteasy-reactive-jackson,rest-client-reactive-jackson" -cd rest-client-reactive-quickstart ----- +:create-app-artifact-id: rest-client-reactive-quickstart +:create-app-extensions: resteasy-reactive-jackson,rest-client-reactive-jackson +include::includes/devtools/create-app.adoc[] This command generates the Maven project with a REST endpoint and imports: @@ -54,14 +42,13 @@ This command generates the Maven project with a REST endpoint and imports: If you already have your Quarkus project configured, you can add the `rest-client-reactive-jackson` extension to your project by running the following command in your project base directory: -[source,bash] ----- -./mvnw quarkus:add-extension -Dextensions="rest-client-reactive-jackson" ----- +:add-extension-extensions: rest-client-reactive-jackson +include::includes/devtools/extension-add.adoc[] -This will add the following to your `pom.xml`: +This will add the following to your build file: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -69,6 +56,12 @@ This will add the following to your `pom.xml`: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-rest-client-reactive-jackson") +---- + == Setting up the model In this guide we will be demonstrating how to consume part of the REST API supplied by the link:https://stage.code.quarkus.io[stage.code.quarkus.io] service. @@ -203,9 +196,9 @@ quarkus.rest-client.extensions-api.url=https://stage.code.quarkus.io/api quarkus.rest-client.extensions-api.scope=javax.inject.Singleton ---- -== Update the JAX-RS resource +== Create the JAX-RS resource -Open the `src/main/java/org/acme/rest/client/ExtensionsResource.java` file and update it with the following content: +Create the `src/main/java/org/acme/rest/client/ExtensionsResource.java` file with the following content: [source,java] @@ -829,13 +822,23 @@ NOTE: MicroProfile REST Client specification does not allow setting proxy creden == Package and run the application -Run the application with: `./mvnw compile quarkus:dev`. +Run the application with: + +include::includes/devtools/dev.adoc[] + Open your browser to http://localhost:8080/extension/id/io.quarkus:quarkus-rest-client-reactive. You should see a JSON object containing some basic information about this extension. -As usual, the application can be packaged using `./mvnw clean package` and executed using the `target/quarkus-app/quarkus-run.jar` file. -You can also generate the native executable with `./mvnw clean package -Pnative`. +As usual, the application can be packaged using: + +include::includes/devtools/build.adoc[] + +And executed with `java -jar target/quarkus-app/quarkus-run.jar`. + +You can also generate the native executable with: + +include::includes/devtools/build-native.adoc[] == Logging traffic REST Client Reactive can log the requests it sends and the responses it receives. @@ -890,7 +893,9 @@ public interface Client { The simplest approach to mock a client for tests is to use Mockito and `@InjectMock`. First, add the following dependency to your application: -[source,xml] + +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -899,6 +904,12 @@ First, add the following dependency to your application: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +testImplementation("io.quarkus:quarkus-junit5-mockito") +---- + Then, in your test you can simply use `@InjectMock` to create and inject a mock: [source,java] diff --git a/docs/src/main/asciidoc/rest-client.adoc b/docs/src/main/asciidoc/rest-client.adoc index 36c985748000d..e121d4626433c 100644 --- a/docs/src/main/asciidoc/rest-client.adoc +++ b/docs/src/main/asciidoc/rest-client.adoc @@ -14,12 +14,7 @@ TIP: there is another guide if you need to write server xref:rest-json.adoc[JSON == Prerequisites -To complete this guide, you need: - -* less than 15 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} +include::includes/devtools/prerequisites.adoc[] == Solution @@ -34,16 +29,9 @@ The solution is located in the `rest-client-quickstart` {quickstarts-tree-url}/r First, we need a new project. Create a new project with the following command: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=rest-client-quickstart \ - -DclassName="org.acme.rest.client.ExtensionsResource" \ - -Dpath="/extension" \ - -Dextensions="resteasy,resteasy-jackson,rest-client,rest-client-jackson" -cd rest-client-quickstart ----- +:create-app-artifact-id: rest-client-quickstart +:create-app-extensions: resteasy,resteasy-jackson,rest-client,rest-client-jackson +include::includes/devtools/create-app.adoc[] This command generates the Maven project with a REST endpoint and imports: @@ -53,14 +41,13 @@ This command generates the Maven project with a REST endpoint and imports: If you already have your Quarkus project configured, you can add the `rest-client` and the `rest-client-jackson` extensions to your project by running the following command in your project base directory: -[source,bash] ----- -./mvnw quarkus:add-extension -Dextensions="rest-client,rest-client-jackson" ----- +:add-extension-extensions: rest-client,rest-client-jackson +include::includes/devtools/extension-add.adoc[] This will add the following to your `pom.xml`: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -72,6 +59,13 @@ This will add the following to your `pom.xml`: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-rest-client") +implementation("io.quarkus:quarkus-rest-client-jackson") +---- + == Setting up the model In this guide we will be demonstrating how to consume part of the REST API supplied by the link:https://stage.code.quarkus.io[stage.code.quarkus.io] service. @@ -243,9 +237,9 @@ quarkus.tls.trust-all=true This setting should not be used in production as it will disable any kind of SSL verification. ==== -== Update the JAX-RS resource +== Create the JAX-RS resource -Open the `src/main/java/org/acme/rest/client/ExtensionsResource.java` file and update it with the following content: +Create the `src/main/java/org/acme/rest/client/ExtensionsResource.java` file with the following content: [source,java] ---- @@ -591,13 +585,23 @@ org.eclipse.microprofile.rest.client.propagateHeaders=Authorization,Proxy-Author == Package and run the application -Run the application with: `./mvnw compile quarkus:dev`. +Run the application with: + +include::includes/devtools/dev.adoc[] + Open your browser to http://localhost:8080/extension/id/io.quarkus:quarkus-rest-client. You should see a JSON object containing some basic information about the REST Client extension. -As usual, the application can be packaged using `./mvnw clean package` and executed using the `target/quarkus-app/quarkus-run.jar` file. -You can also generate the native executable with `./mvnw clean package -Pnative`. +As usual, the application can be packaged using: + +include::includes/devtools/build.adoc[] + +And executed with `java -jar target/quarkus-app/quarkus-run.jar`. + +You can also generate the native executable with: + +include::includes/devtools/build-native.adoc[] == REST Client and RESTEasy interactions @@ -631,6 +635,23 @@ First of all, Wiremock needs to be added as a test dependency. For a Maven proje ---- +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml +---- + + com.github.tomakehurst + wiremock-jre8 + test + ${wiremock.version} <1> + +---- + +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +testImplementation("com.github.tomakehurst:wiremock-jre8:$wiremockVersion") +---- + <1> Use a proper Wiremock version. All available versions can be found link:https://search.maven.org/artifact/com.github.tomakehurst/wiremock-jre8[here]. In Quarkus tests when some service needs to be started before the Quarkus tests are ran, we utilize the `@io.quarkus.test.common.QuarkusTestResource` @@ -658,34 +679,34 @@ import static com.github.tomakehurst.wiremock.client.WireMock.*; // <1> public class WireMockExtensions implements QuarkusTestResourceLifecycleManager { // <2> - private WireMockServer wireMockServer; - - @Override - public Map start() { - wireMockServer = new WireMockServer(); - wireMockServer.start(); // <3> - - stubFor(get(urlEqualTo("/extensions?id=io.quarkus:quarkus-rest-client")) // <4> - .willReturn(aResponse() - .withHeader("Content-Type", "application/json") - .withBody( - "[{" + - "\"id\": \"io.quarkus:quarkus-rest-client\"," + - "\"name\": \"REST Client\"" + - "}]" - ))); - - stubFor(get(urlMatching(".*")).atPriority(10).willReturn(aResponse().proxiedFrom("https://stage.code.quarkus.io/api"))); // <5> - - return Collections.singletonMap("quarkus.rest-client.\"org.acme.rest.client.ExtensionsService\".url", wireMockServer.baseUrl()); // <6> - } - - @Override - public void stop() { - if (null != wireMockServer) { - wireMockServer.stop(); // <7> - } - } + private WireMockServer wireMockServer; + + @Override + public Map start() { + wireMockServer = new WireMockServer(); + wireMockServer.start(); // <3> + + stubFor(get(urlEqualTo("/extensions?id=io.quarkus:quarkus-rest-client")) // <4> + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody( + "[{" + + "\"id\": \"io.quarkus:quarkus-rest-client\"," + + "\"name\": \"REST Client\"" + + "}]" + ))); + + stubFor(get(urlMatching(".*")).atPriority(10).willReturn(aResponse().proxiedFrom("https://stage.code.quarkus.io/api"))); // <5> + + return Collections.singletonMap("quarkus.rest-client.\"org.acme.rest.client.ExtensionsService\".url", wireMockServer.baseUrl()); // <6> + } + + @Override + public void stop() { + if (null != wireMockServer) { + wireMockServer.stop(); // <7> + } + } } ---- diff --git a/docs/src/main/asciidoc/rest-data-panache.adoc b/docs/src/main/asciidoc/rest-data-panache.adoc index 13ef27cb6a99e..ab3fb3216d6ba 100644 --- a/docs/src/main/asciidoc/rest-data-panache.adoc +++ b/docs/src/main/asciidoc/rest-data-panache.adoc @@ -20,35 +20,49 @@ include::./status-include.adoc[] === Hibernate ORM -* Add the required dependencies to your `pom.xml` +* Add the required dependencies to your build file ** Hibernate ORM REST Data with Panache extension (`quarkus-hibernate-orm-rest-data-panache`) ** A JDBC driver extension (`quarkus-jdbc-postgresql`, `quarkus-jdbc-h2`, `quarkus-jdbc-mariadb`, ...) ** One of the RESTEasy JSON serialization extensions (the extension supports both RESTEasy Classic and RESTEasy Reactive) -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- - - - io.quarkus - quarkus-hibernate-orm-rest-data-panache - - - io.quarkus - quarkus-jdbc-postgresql - - - - io.quarkus - quarkus-resteasy-reactive-jackson - - - - + + io.quarkus + quarkus-hibernate-orm-rest-data-panache + + + io.quarkus + quarkus-jdbc-postgresql + + + + + io.quarkus + quarkus-resteasy-reactive-jackson + + + + +---- + +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-hibernate-orm-rest-data-panache") +implementation("io.quarkus:quarkus-jdbc-postgresql") + +// Use this if you are using RESTEasy Reactive +implementation("io.quarkus:quarkus-resteasy-reactive-jackson") + +// Use this if you are going to use RESTEasy Classic +// implementation("io.quarkus:quarkus-resteasy-jackson") ---- * Implement the Panache entities and/or repositories as explained in the xref:hibernate-orm-panache.adoc[Hibernate ORM with Panache guide]. @@ -56,38 +70,53 @@ include::./status-include.adoc[] === MongoDB -* Add the required dependencies to your `pom.xml` +* Add the required dependencies to your build file ** MongoDB REST Data with Panache extension (`quarkus-mongodb-rest-data-panache`) ** One of the RESTEasy JSON serialization extensions (`quarkus-resteasy-reactive-jackson` or `quarkus-resteasy-reactive-jsonb`) -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- - - - io.quarkus - quarkus-mongodb-rest-data-panache - - - - io.quarkus - quarkus-resteasy-reactive-jackson - - - io.quarkus - quarkus-resteasy-reactive-links - - - - + + io.quarkus + quarkus-mongodb-rest-data-panache + + + + + io.quarkus + quarkus-resteasy-reactive-jackson + + + io.quarkus + quarkus-resteasy-reactive-links + + + + +---- + +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-mongodb-rest-data-panache") + +// Use these if you are using RESTEasy Reactive +implementation("io.quarkus:quarkus-resteasy-reactive-jackson") +implementation("io.quarkus:quarkus-resteasy-reactive-links") + +// Use these if you are going to use RESTEasy Classic +// implementation("io.quarkus:quarkus-resteasy-jackson") +// implementation("io.quarkus:resteasy-links") ---- * Implement the Panache entities and/or repositories as explained in the xref:mongodb-panache.adoc[MongoDB with Panache guide]. diff --git a/docs/src/main/asciidoc/rest-json.adoc b/docs/src/main/asciidoc/rest-json.adoc index 345f37feec84e..c78d04665b539 100644 --- a/docs/src/main/asciidoc/rest-json.adoc +++ b/docs/src/main/asciidoc/rest-json.adoc @@ -15,12 +15,7 @@ TIP: there is another guide if you need a xref:rest-client.adoc[REST client] (in == Prerequisites -To complete this guide, you need: - -* less than 15 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} +include::includes/devtools/prerequisites.adoc[] == Architecture @@ -41,21 +36,15 @@ The solution is located in the `rest-json-quickstart` {quickstarts-tree-url}/res First, we need a new project. Create a new project with the following command: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=rest-json-quickstart \ - -DclassName="org.acme.rest.json.FruitResource" \ - -Dpath="/fruits" \ - -Dextensions="resteasy-jackson" -cd rest-json-quickstart ----- +:create-app-artifact-id: rest-json-quickstart +:create-app-extensions: resteasy-jackson +include::includes/devtools/create-app.adoc[] -This command generates a Maven structure importing the RESTEasy/JAX-RS and https://github.com/FasterXML/jackson[Jackson] extensions, +This command generates a new project importing the RESTEasy/JAX-RS and https://github.com/FasterXML/jackson[Jackson] extensions, and in particular adds the following dependency: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -63,6 +52,12 @@ and in particular adds the following dependency: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-resteasy-jackson") +---- + [NOTE] ==== To improve user experience, Quarkus registers the three Jackson https://github.com/FasterXML/jackson-modules-java8[Java 8 modules] so you don't need to do it manually. @@ -70,21 +65,15 @@ To improve user experience, Quarkus registers the three Jackson https://github.c Quarkus also supports https://eclipse-ee4j.github.io/jsonb-api/[JSON-B] so, if you prefer JSON-B over Jackson, you can create a project relying on the RESTEasy JSON-B extension instead: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=rest-json-quickstart \ - -DclassName="org.acme.rest.json.FruitResource" \ - -Dpath="/fruits" \ - -Dextensions="resteasy-jsonb" -cd rest-json-quickstart ----- +:create-app-artifact-id: rest-json-quickstart +:create-app-extensions: resteasy-jsonb +include::includes/devtools/create-app.adoc[] -This command generates a Maven structure importing the RESTEasy/JAX-RS and https://eclipse-ee4j.github.io/jsonb-api/[JSON-B] extensions, +This command generates a new project importing the RESTEasy/JAX-RS and https://eclipse-ee4j.github.io/jsonb-api/[JSON-B] extensions, and in particular adds the following dependency: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -92,6 +81,12 @@ and in particular adds the following dependency: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-resteasy-jsonb") +---- + == Creating your first JSON REST service In this example, we will create an application to manage a list of fruits. @@ -119,7 +114,7 @@ public class Fruit { Nothing fancy. One important thing to note is that having a default constructor is required by the JSON serialization layer. -Now, edit the `org.acme.rest.json.FruitResource` class as follows: +Now, create the `org.acme.rest.json.FruitResource` class as follows: [source,java] ---- @@ -312,13 +307,21 @@ In the `src/main/resources/META-INF/resources` directory, add a `fruits.html` fi You can now interact with your REST service: - * start Quarkus with `./mvnw compile quarkus:dev` +:devtools-wrapped: + + * start Quarkus with: ++ +include::includes/devtools/dev.adoc[] * open a browser to `http://localhost:8080/fruits.html` * add new fruits to the list via the form +:!devtools-wrapped: + == Building a native executable -You can build a native executable with the usual command `./mvnw package -Pnative`. +You can build a native executable with the usual command: + +include::includes/devtools/build-native.adoc[] Running it is as simple as executing `./target/rest-json-quickstart-1.0.0-SNAPSHOT-runner`. @@ -436,10 +439,16 @@ Open a browser to http://localhost:8080/legumes.html and you will see our list o The interesting part starts when running the application as a native executable: - * create the native executable with `./mvnw package -Pnative`. +:devtools-wrapped: + + * create the native executable with: ++ +include::includes/devtools/build-native.adoc[] * execute it with `./target/rest-json-quickstart-1.0.0-SNAPSHOT-runner` * open a browser and go to http://localhost:8080/legumes.html +:!devtools-wrapped: + No legumes there. As mentioned above, the issue is that Quarkus was not able to determine the `Legume` class will require some reflection by analyzing the REST endpoints. @@ -468,11 +477,17 @@ TIP: The `@RegisterForReflection` annotation instructs Quarkus to keep the class Let's do that and follow the same steps as before: +:devtools-wrapped: + * hit `Ctrl+C` to stop the application - * create the native executable with `./mvnw package -Pnative`. + * create the native executable with: ++ +include::includes/devtools/build-native.adoc[] * execute it with `./target/rest-json-quickstart-1.0.0-SNAPSHOT-runner` * open a browser and go to http://localhost:8080/legumes.html +:!devtools-wrapped: + This time, you can see our list of legumes. [[reactive]] @@ -483,14 +498,21 @@ Quarkus recommends the usage of https://smallrye.io/smallrye-mutiny[Mutiny] to w To integrate Mutiny and RESTEasy, you need to add the `quarkus-resteasy-mutiny` dependency to your project: -[source, xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- - io.quarkus - quarkus-resteasy-mutiny + io.quarkus + quarkus-resteasy-mutiny ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-resteasy-mutiny") +---- + Then, your endpoint can return `Uni` or `Multi` instances: [source,java] diff --git a/docs/src/main/asciidoc/resteasy-reactive.adoc b/docs/src/main/asciidoc/resteasy-reactive.adoc index f1c60c4e0de71..6288698e08bd4 100644 --- a/docs/src/main/asciidoc/resteasy-reactive.adoc +++ b/docs/src/main/asciidoc/resteasy-reactive.adoc @@ -33,9 +33,10 @@ of what JAX-RS provides. === Getting started -Add the following import to your `pom.xml` file: +Add the following import to your build file: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -43,6 +44,12 @@ Add the following import to your `pom.xml` file: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-resteasy-reactive") +---- + You can now write your first endpoint in the `org.acme.rest.Endpoint` class: [source,java] @@ -913,7 +920,7 @@ Instead of importing `io.quarkus:quarkus-resteasy-reactive`, you can import eith |https://github.com/FasterXML/jackson[Jackson support] |`io.quarkus:quarkus-resteasy-reactive-jsonb` -|https://eclipse-ee4j.github.io/jsonb-api/[JSONB support] +|https://eclipse-ee4j.github.io/jsonb-api/[JSON-B support] |=== @@ -2105,8 +2112,9 @@ Please note that if a JAX-RS Application has been detected and the method `getCl == RESTEasy Reactive client + In addition to the Server side, RESTEasy Reactive comes with a new MicroProfile Rest Client implementation that is non-blocking at its core. -Please note that the `quarkus-rest-client` extension may not work properly with RESTEasy Reactive. +Please note that the `quarkus-rest-client` extension may not be used with RESTEasy Reactive, use `quarkus-rest-client-reactive` instead. -See xref:rest-client-reactive.adoc[REST Client Reactive Guide] for more information about the reactive client. +See the xref:rest-client-reactive.adoc[REST Client Reactive Guide] for more information about the reactive REST client. diff --git a/docs/src/main/asciidoc/scheduler.adoc b/docs/src/main/asciidoc/scheduler.adoc index b9224ae315bf9..e053bc2cdd13d 100644 --- a/docs/src/main/asciidoc/scheduler.adoc +++ b/docs/src/main/asciidoc/scheduler.adoc @@ -14,19 +14,14 @@ TIP: If you need a clustered scheduler use the xref:quartz.adoc[Quartz extension == Prerequisites -To complete this guide, you need: - -* less than 10 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} +include::includes/devtools/prerequisites.adoc[] == Architecture In this guide, we create a straightforward application accessible using HTTP to get the current value of a counter. This counter is periodically (every 10 seconds) incremented. -image:scheduling-task-architecture.png[alt=Architecture] +image::scheduling-task-architecture.png[alt=Architecture] == Solution @@ -41,39 +36,28 @@ The solution is located in the `scheduler-quickstart` {quickstarts-tree-url}/sch First, we need a new project. Create a new project with the following command: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=scheduler-quickstart \ - -DclassName="org.acme.scheduler.CountResource" \ - -Dpath="/count" \ - -Dextensions="scheduler" -cd scheduler-quickstart ----- +:create-app-artifact-id: scheduler-quickstart +:create-app-extensions: resteasy,scheduler +include::includes/devtools/create-app.adoc[] -It generates: +It generates a new project including: -* the Maven structure * a landing page accessible on `http://localhost:8080` * example `Dockerfile` files for both `native` and `jvm` modes * the application configuration file -* an `org.acme.scheduler.CountResource` resource -* an associated test -The Maven project also imports the Quarkus scheduler extension. +The project also imports the RESTEasy and scheduler extensions. If you already have your Quarkus project configured, you can add the `scheduler` extension to your project by running the following command in your project base directory: -[source,bash] ----- -./mvnw quarkus:add-extension -Dextensions="scheduler" ----- +:add-extension-extensions: scheduler +include::includes/devtools/extension-add.adoc[] -This will add the following to your `pom.xml`: +This will add the following to your build file: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -81,6 +65,12 @@ This will add the following to your `pom.xml`: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-scheduler") +---- + [#standard-scheduling] == Creating a scheduled job @@ -142,9 +132,9 @@ Edit the `application.properties` file and add the `cron.expr` configuration: cron.expr=*/5 * * * * ? ---- -== Updating the resource and the test +== Creating the REST resource -Edit the `CountResource` class, and update the content to: +Create the `CountResource` class as follows: [source,java] ---- @@ -173,45 +163,27 @@ public class CountResource { 1. Inject the `CounterBean` 2. Send back the current counter value -We also need to update the tests. Edit the `CountResourceTest` class to match: - -[source, java] ----- -package org.acme.scheduler; - -import io.quarkus.test.junit.QuarkusTest; -import org.junit.jupiter.api.Test; - -import static io.restassured.RestAssured.given; -import static org.hamcrest.CoreMatchers.containsString; - -@QuarkusTest -public class CountResourceTest { - - @Test - public void testHelloEndpoint() { - given() - .when().get("/count") - .then() - .statusCode(200) - .body(containsString("count")); // <1> - } +== Package and run the application -} ----- -1. Ensure that the response contains `count` +Run the application with: -== Package and run the application +include::includes/devtools/dev.adoc[] -Run the application with: `./mvnw compile quarkus:dev`. In another terminal, run `curl localhost:8080/count` to check the counter value. After a few seconds, re-run `curl localhost:8080/count` to verify the counter has been incremented. Observe the console to verify that the message `Cron expression configured in application.properties` has been displayed indicating that the cron job using an expression configured in `application.properties` has been triggered. -As usual, the application can be packaged using `./mvnw clean package` and executed using the `target/quarkus-app/quarkus-run.jar` file. -You can also generate the native executable with `./mvnw clean package -Pnative`. +As usual, the application can be packaged using: + +include::includes/devtools/build.adoc[] + +And executed with `java -jar target/quarkus-app/quarkus-run.jar`. + +You can also generate the native executable with: + +include::includes/devtools/build-native.adoc[] [[scheduler-configuration-reference]] == Scheduler Configuration Reference diff --git a/docs/src/main/asciidoc/scripting.adoc b/docs/src/main/asciidoc/scripting.adoc index 74ed3cd14a687..930b056a45086 100644 --- a/docs/src/main/asciidoc/scripting.adoc +++ b/docs/src/main/asciidoc/scripting.adoc @@ -15,12 +15,11 @@ include::./status-include.adoc[] == Prerequisites -To complete this guide, you need: - -* less than 5 minutes -* https://jbang.dev/download[jbang v0.40.3+] -* an IDE -* GraalVM installed if you want to run in native mode +:prerequisites-time: 5 minutes +:prerequisites-no-maven: +:prerequisites-no-cli: +include::includes/devtools/prerequisites.adoc[] +* https://jbang.dev/download[JBang] == Solution @@ -84,7 +83,7 @@ image::getting-started-architecture.png[alt=Architecture, align=center] == Creating the initial file -First, we need a Java file. jbang lets you create an initial version using: +First, we need a Java file. JBang lets you create an initial version using: [source,bash,subs=attributes+] ---- @@ -96,7 +95,7 @@ This command generates a .java file that you can directly run on Linux and macOS This initial version will print `Hello World` when run. -Once generated, look at the `quarkusapp.java`. +Once generated, look at the `quarkusapp.java` file. You will find at the top a line looking like this: @@ -114,7 +113,7 @@ The next line // //DEPS ---- -Is illustrating how you add dependencies to this script. This is a feature of `jbang`. +Is illustrating how you add dependencies to this script. This is a feature of JBang. Go ahead and update this line to include the `quarkus-resteasy` dependency like so: @@ -123,7 +122,7 @@ Go ahead and update this line to include the `quarkus-resteasy` dependency like //DEPS io.quarkus:quarkus-resteasy:{quarkus-version} ---- -Now, run `jbang quarkusapp.java` and you will see `jbang` resolving this dependency and building the jar with help from Quarkus' jbang integration. +Now, run `jbang quarkusapp.java` and you will see JBang resolving this dependency and building the jar with help from Quarkus' JBang integration. [source,shell,subs=attributes+] ---- @@ -151,7 +150,7 @@ To work around that you can run `jbang edit quarkusapp.java`, this will print ou On Linux/macOS you can run ` `jbang edit quarkusapp.java``. -If you add dependencies while editing you can get jbang to automatically refresh +If you add dependencies while editing, you can get JBang to automatically refresh the IDE project using `jbang edit --live= quarkusapp.java`. ==== @@ -187,7 +186,7 @@ It's a very simple class with a main method that starts Quarkus with a REST endp [TIP] .Why is the `main` method there? ==== -A `main` method is currently needed for the `jbang` integration to work - we might remove this requirement in the future. +A `main` method is currently needed for the JBang integration to work - we might remove this requirement in the future. ==== == Running the application @@ -234,7 +233,7 @@ We are using `curl -w "\n"` in this example to avoid your terminal printing a '% [TIP] .Why is `quarkus-resteasy` not resolved? ==== -In this second run you should not see a line saying it is resolving `quarkus-resteasy` as jbang caches the dependency resolution between runs. +In this second run you should not see a line saying it is resolving `quarkus-resteasy` as JBang caches the dependency resolution between runs. If you want to clear the caches to force resolution use `jbang cache clear`. ==== @@ -269,7 +268,7 @@ static public class GreetingService { ==== We are using a nested static public class instead of a top level class for two reasons: -. jbang currently does not support multiple source files. +. JBang currently does not support multiple source files. . All Java frameworks relying on introspection have challenges using top level classes as they are not as visible as public classes; and in Java there can only be one top level public class in a file. ==== @@ -355,11 +354,11 @@ hello quarkus To debug the application you use `jbang --debug quarkusapp.java` and you can use your IDE to connect on port 4004; if you want to use the more traditional Quarkus debug port you can use `jbang --debug=5005 quarkusapp.java`. -Note: `jbang` debugging always suspends thus you need to connect the debugger to have the application run. +Note: JBang debugging always suspends thus you need to connect the debugger to have the application run. == Logging -To use logging in Quarkus scripting with jbang you do as usual, with configuring a logger, i.e. +To use logging in Quarkus scripting with JBang you do as usual, with configuring a logger, i.e. [source,java] ---- @@ -422,7 +421,7 @@ __ ____ __ _____ ___ __ ____ ______ 2020-08-30 06:22:32,013 INFO [io.quarkus] (main) Installed features: [cdi, resteasy] ---- -This native build will take some time on first run but any subsequent runs (without changing `quarkusapp.java`) will be close to instant thanks to jbang cache: +This native build will take some time on first run but any subsequent runs (without changing `quarkusapp.java`) will be close to instant thanks to JBang cache: [source,shell,subs=attributes+] ---- @@ -438,4 +437,4 @@ __ ____ __ _____ ___ __ ____ ______ === Conclusion -If you want to get started with Quarkus or write something quickly, Quarkus Scripting with jbang lets you do that. No Maven, no Gradle - just a Java file. In this guide we outlined the very basics on using Quarkus with jbang; if you want to learn more about what jbang can do, go see https://jbang.dev. +If you want to get started with Quarkus or write something quickly, Quarkus Scripting with jbang lets you do that. No Maven, no Gradle - just a Java file. In this guide we outlined the very basics on using Quarkus with JBang; if you want to learn more about what JBang can do, go see https://jbang.dev. diff --git a/docs/src/main/asciidoc/security-customization.adoc b/docs/src/main/asciidoc/security-customization.adoc index cc9a55cc7f9eb..2bfc46bdea595 100644 --- a/docs/src/main/asciidoc/security-customization.adoc +++ b/docs/src/main/asciidoc/security-customization.adoc @@ -11,17 +11,24 @@ include::./attributes.adoc[] `io.quarkus:quarkus-security` module contains the core Quarkus security classes. -In most cases it does not have to be added directly to your project's `pom.xml` as it is already provided by all of the security extensions. -However if you need to write your own custom security code (for example, register a <>) or use <> libraries, then please make sure it is included: +In most cases, it does not have to be added directly to your project's build file as it is already provided by all of the security extensions. +However, if you need to write your own custom security code (for example, register a <>) or use <> libraries, then please make sure it is included: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- - io.quarkus - quarkus-security + io.quarkus + quarkus-security ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-security") +---- + == HttpAuthenticationMechanism Customization One can customize `HttpAuthenticationMechanism` by registering a CDI implementation bean. @@ -266,14 +273,21 @@ quarkus.security.security-providers=BC and add the BouncyCastle provider dependency: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- - org.bouncycastle - bcprov-jdk15on + org.bouncycastle + bcprov-jdk15on ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("org.bouncycastle:bcprov-jdk15on") +---- + [[bouncy-castle-jsse]] === BouncyCastle JSSE @@ -294,14 +308,21 @@ quarkus.http.ssl.certificate.trust-store-password=password and add the BouncyCastle TLS dependency: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- - org.bouncycastle - bctls-jdk15on + org.bouncycastle + bctls-jdk15on ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("org.bouncycastle:bctls-jdk15on") +---- + [[bouncy-castle-fips]] === BouncyCastle FIPS @@ -315,14 +336,21 @@ quarkus.security.security-providers=BCFIPS and add the BouncyCastle FIPS provider dependency: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- - org.bouncycastle - bc-fips + org.bouncycastle + bc-fips ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("org.bouncycastle:bc-fips") +---- + [NOTE] ==== `BCFIPS` provider option is supported in native image but the algorithm self-tests which rely on `java.security.SecureRandom` to verify the generated keys have been removed for these tests to pass. The following classes have been affected: @@ -359,7 +387,8 @@ quarkus.http.ssl.certificate.trust-store-provider=BCFIPS and the BouncyCastle TLS dependency optimized for using the BouncyCastle FIPS provider: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- org.bouncycastle @@ -367,11 +396,18 @@ and the BouncyCastle TLS dependency optimized for using the BouncyCastle FIPS pr - org.bouncycastle - bc-fips + org.bouncycastle + bc-fips ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("org.bouncycastle:bctls-fips") +implementation("org.bouncycastle:bc-fips") +---- + Note that the keystore and truststore type and provider are set to `BCFKS` and `BCFIPS`. One can generate a keystore with this type and provider like this: @@ -389,14 +425,21 @@ keytool -genkey -alias server -keyalg RSA -keystore server-keystore.jks -keysize If you are going to use security in a reactive environment, you will likely need SmallRye Context Propagation: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- - io.quarkus - quarkus-smallrye-context-propagation + io.quarkus + quarkus-smallrye-context-propagation ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-smallrye-context-propagation") +---- + This will allow you to propagate the identity throughout the reactive callbacks. You also need to make sure you are using an executor that is capable of propagating the identity (e.g. no `CompletableFuture.supplyAsync`), to make sure that Quarkus can propagate it. For more information see the diff --git a/docs/src/main/asciidoc/security-jdbc.adoc b/docs/src/main/asciidoc/security-jdbc.adoc index f54ab3e0125b3..a8b7056d7addd 100644 --- a/docs/src/main/asciidoc/security-jdbc.adoc +++ b/docs/src/main/asciidoc/security-jdbc.adoc @@ -12,12 +12,7 @@ This guide demonstrates how your Quarkus application can use a database to store == Prerequisites -To complete this guide, you need: - -* less than 15 minutes -* an IDE -* JDK 11+ installed with `JAVA_HOME` configured appropriately -* Apache Maven {maven-version} +include::includes/devtools/prerequisites.adoc[] == Architecture @@ -44,35 +39,28 @@ The solution is located in the `security-jdbc-quickstart` {quickstarts-tree-url} First, we need a new project. Create a new project with the following command: -[source,bash,subs=attributes+] ----- -mvn io.quarkus.platform:quarkus-maven-plugin:{quarkus-version}:create \ - -DprojectGroupId=org.acme \ - -DprojectArtifactId=security-jdbc-quickstart \ - -Dextensions="elytron-security-jdbc,jdbc-postgresql,resteasy" \ - -DnoExamples -cd security-jdbc-quickstart ----- +:create-app-artifact-id: security-jdbc-quickstart +:create-app-extensions: elytron-security-jdbc,jdbc-postgresql,resteasy +include::includes/devtools/create-app.adoc[] [NOTE] ==== Don't forget to add the database connector library of choice. Here we are using PostgreSQL as identity store. ==== -This command generates a Maven project, importing the `elytron-security-jdbc` extension +This command generates a new project, importing the `elytron-security-jdbc` extension which is an https://docs.wildfly.org/17/WildFly_Elytron_Security.html#jdbc-security-realm[`wildfly-elytron-realm-jdbc`] adapter for Quarkus applications. If you already have your Quarkus project configured, you can add the `elytron-security-jdbc` extension to your project by running the following command in your project base directory: -[source,bash] ----- -./mvnw quarkus:add-extension -Dextensions="elytron-security-jdbc" ----- +:add-extension-extensions: elytron-security-jdbc +include::includes/devtools/extension-add.adoc[] -This will add the following to your `pom.xml`: +This will add the following to your build file: -[source,xml] +[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"] +.pom.xml ---- io.quarkus @@ -80,6 +68,12 @@ This will add the following to your `pom.xml`: ---- +[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] +.build.gradle +---- +implementation("io.quarkus:quarkus-elytron-security-jdbc") +---- + == Writing the application Let's start by implementing the `/api/public` endpoint. As you can see from the source code below, it is just a regular JAX-RS resource: