From ed5c2c2a7c5c164daf3eb785a82b9145e45bfbb4 Mon Sep 17 00:00:00 2001 From: xstefank Date: Tue, 17 Sep 2024 15:24:21 +0200 Subject: [PATCH 01/16] Fix gRPC DevUI testing console (cherry picked from commit a6768b62a4448a38761e89d2f495c7bf131eec2d) --- .../resources/dev-ui/qwc-grpc-services.js | 75 ++++++++++++++----- .../runtime/devui/GrpcJsonRPCService.java | 65 ++++++++++++---- 2 files changed, 105 insertions(+), 35 deletions(-) diff --git a/extensions/grpc/deployment/src/main/resources/dev-ui/qwc-grpc-services.js b/extensions/grpc/deployment/src/main/resources/dev-ui/qwc-grpc-services.js index 26caaee30abe7..1675b06f73056 100644 --- a/extensions/grpc/deployment/src/main/resources/dev-ui/qwc-grpc-services.js +++ b/extensions/grpc/deployment/src/main/resources/dev-ui/qwc-grpc-services.js @@ -233,20 +233,22 @@ export class QwcGrpcServices extends observeState(QwcHotReloadElement) { _renderCommandButtons(service, method){ if(this._streamsMap.size >=0){ - if(method.type == 'UNARY'){ - return html` this._clear(service.name, method)} @mouseup=${() => this._default(service.name, method)}>Reset + if(method.type == 'UNARY' || method.type == 'SERVER_STREAMING'){ + return html` this._default(service.name, method)}>Reset this._test(service, method)}>Send`; }else if(this._isRunning(service.name, method)){ - return html`
this._test(service, method)}>Cancel stream -
`; + return html` this._default(service.name, method)}>Reset + this._test(service, method)}>Send + this._disconnect(service, method)}>Disconnect + `; }else { - return html` this._test(service, method)}>Start stream`; + return html` this._test(service, method)}>Send`; } } } _keypress(e, service, method){ - if(method.type == 'UNARY' || !this._isRunning(service.name, method)){ + if(method.type == 'UNARY' || method.type == 'SERVER_STREAMING' || !this._isRunning(service.name, method)){ if ((e.keyCode == 10 || e.keyCode == 13) && e.ctrlKey){ // ctlr-enter this._test(service, method); } @@ -268,46 +270,75 @@ export class QwcGrpcServices extends observeState(QwcHotReloadElement) { } _default(serviceName, method){ + let requestTextArea = this._requestTextArea(serviceName, method); + requestTextArea.content = ''; let pv = JSON.parse(method.prototype); - this._requestTextArea(serviceName, method).populatePrettyJson(JSON.stringify(pv)); + let prettyJson = JSON.stringify(pv, null, 2); + requestTextArea.populatePrettyJson(prettyJson); } _test(service, method){ - let textArea = this._requestTextArea(service.name, method); - let content = textArea.getAttribute('value'); + let requestTextArea = this._requestTextArea(service.name, method); + let content = requestTextArea.getAttribute('value'); + let id = this._id(service.name, method); + let responseTextArea = this._responseTextArea(service.name, method); if(method.type == 'UNARY'){ this.jsonRpc.testService({ + id: id, serviceName: service.name, methodName: method.bareMethodName, methodType: method.type, content: content }).then(jsonRpcResponse => { - const jsonObject = JSON.parse(jsonRpcResponse.result); - const prettyJson = JSON.stringify(jsonObject, null, 2); - this._responseTextArea(service.name, method).populatePrettyJson(prettyJson); + this._responseTextArea(service.name, method).populatePrettyJson(this._prettyJson(jsonRpcResponse.result)); }); }else{ - let id = this._id(service.name, method); if(this._isRunning(service.name, method)){ - this._streamsMap.get(id).cancel(); - this._streamsMap.delete(id); - this._clear(service.name, method); - this._default(service.name, method); + this.jsonRpc.streamService({ + id: id, + serviceName: service.name, + methodName: method.bareMethodName, + isRunning: true, + content: content + }); + // this._streamsMap.get(id).cancel(); + // this._streamsMap.delete(id); + // this._clear(service.name, method); + // this._default(service.name, method); }else{ + // starting a new stream, clear the response area + responseTextArea.content = null; let cancelable = this.jsonRpc.streamService({ + id: id, serviceName: service.name, methodName: method.bareMethodName, - methodType: method.type, + isRunning: false, content: content }).onNext(jsonRpcResponse => { - this._responseTextArea(service.name, method).populatePrettyJson(jsonRpcResponse.result); + if (responseTextArea.content == null) { + responseTextArea.populatePrettyJson(this._prettyJson(jsonRpcResponse.result)); + } else { + responseTextArea.populatePrettyJson(responseTextArea.content + '\n' + this._prettyJson(jsonRpcResponse.result)); + } }); - this._streamsMap.set(id, cancelable); + if (method.type == 'BIDI_STREAMING' || method.type == 'CLIENT_STREAMING') { + this._streamsMap.set(id, cancelable); + } } this._testerButtons = this._renderCommandButtons(service, method); this._forceUpdate(); } } + + _disconnect(service, method){ + let id = this._id(service.name, method); + this.jsonRpc.disconnectService({ + id: id, + }); + this._streamsMap.delete(id); + this._testerButtons = this._renderCommandButtons(service, method); + this._forceUpdate(); + } _forceUpdate(){ if(this._detailsOpenedItem.length > 0){ @@ -332,5 +363,9 @@ export class QwcGrpcServices extends observeState(QwcHotReloadElement) { _responseId(serviceName, method){ return serviceName + '/' + method.bareMethodName + '_response'; } + + _prettyJson(content){ + return JSON.stringify(JSON.parse(content), null, 2); + } } customElements.define('qwc-grpc-services', QwcGrpcServices); \ No newline at end of file diff --git a/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/devui/GrpcJsonRPCService.java b/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/devui/GrpcJsonRPCService.java index 78835d4fd51fb..7d367e3d43710 100644 --- a/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/devui/GrpcJsonRPCService.java +++ b/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/devui/GrpcJsonRPCService.java @@ -18,6 +18,7 @@ import com.google.protobuf.util.JsonFormat; import io.grpc.Channel; +import io.grpc.ManagedChannel; import io.grpc.MethodDescriptor; import io.grpc.ServiceDescriptor; import io.grpc.netty.NettyChannelBuilder; @@ -45,6 +46,7 @@ public class GrpcJsonRPCService { private static final Logger LOG = Logger.getLogger(GrpcJsonRPCService.class); private Map grpcServiceClassInfos; + private Map> callsInProgress; @Inject HttpConfiguration httpConfiguration; @@ -72,6 +74,7 @@ public void init() { this.ssl = isTLSConfigured(httpConfiguration.ssl.certificate); } this.grpcServiceClassInfos = getGrpcServiceClassInfos(); + this.callsInProgress = new HashMap<>(); } private boolean isTLSConfigured(CertificateConfig certificate) { @@ -107,25 +110,27 @@ public JsonArray getServices() { return services; } - public Uni testService(String serviceName, String methodName, String methodType, String content) { + public Uni testService(String id, String serviceName, String methodName, String content) { try { - return streamService(serviceName, methodName, methodType, content).toUni(); + return streamService(id, serviceName, methodName, false, content).toUni(); } catch (Throwable t) { return Uni.createFrom().item(error(t.getMessage()).encodePrettily()); } } - public Multi streamService(String serviceName, String methodName, String methodType, String content) + public Multi streamService(String id, String serviceName, String methodName, boolean isRunning, + String content) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidProtocolBufferException { if (content == null) { - return Multi.createFrom().item(error("Invalid messsge").encodePrettily()); + return Multi.createFrom().item(error("Invalid message").encodePrettily()); } BroadcastProcessor streamEvent = BroadcastProcessor.create(); GrpcServiceClassInfo info = this.grpcServiceClassInfos.get(serviceName); - Object grpcStub = createStub(info.grpcServiceClass, host, port); + ManagedChannel channel = getChannel(host, port); + Object grpcStub = createStub(info.grpcServiceClass, channel); ServiceDescriptor serviceDescriptor = info.serviceDescriptor; @@ -134,20 +139,50 @@ public Multi streamService(String serviceName, String methodName, String MethodDescriptor.PrototypeMarshaller protoMarshaller = (MethodDescriptor.PrototypeMarshaller) requestMarshaller; Class requestType = protoMarshaller.getMessagePrototype().getClass(); + Message message = createMessage(content, requestType); + + if (isRunning) { + // we are already connected with this gRPC endpoint, just send the message + callsInProgress.get(id).onNext(message); + } else { + // Invoke the stub method and format the response as JSON + StreamObserver responseObserver = new TestObserver<>(streamEvent); + StreamObserver incomingStream; + + final Method stubMethod = getStubMethod(grpcStub, methodDescriptor.getBareMethodName()); + + if (stubMethod.getParameterCount() == 1 && stubMethod.getReturnType() == StreamObserver.class) { + // returned StreamObserver consumes incoming messages + //noinspection unchecked + incomingStream = (StreamObserver) stubMethod.invoke(grpcStub, responseObserver); + callsInProgress.put(id, incomingStream); + // will be streamed continuously + incomingStream.onNext(message); + } else { + // incoming message should be passed as the first parameter of the invocation + stubMethod.invoke(grpcStub, message, responseObserver); + } + } + + channel.shutdown(); + return streamEvent; + } + + private static Message createMessage(String content, Class requestType) + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InvalidProtocolBufferException { // Create a new builder for the request message, e.g. HelloRequest.newBuilder() Method newBuilderMethod = requestType.getDeclaredMethod("newBuilder"); Message.Builder builder = (Message.Builder) newBuilderMethod.invoke(null); // Use the test data to build the request object JsonFormat.parser().merge(content, builder); - Message message = builder.build(); - - StreamObserver responseObserver = new TestObserver(streamEvent); - - final Method stubMethod = getStubMethod(grpcStub, methodDescriptor.getBareMethodName()); - stubMethod.invoke(grpcStub, message, responseObserver); + return builder.build(); + } - return streamEvent; + public Uni disconnectService(String id) { + callsInProgress.get(id).onCompleted(); + callsInProgress.remove(id); + return Uni.createFrom().voidItem(); } private Map getGrpcServiceClassInfos() { @@ -220,17 +255,17 @@ private MethodDescriptor getMethodDescriptor(ServiceDescriptor serviceDescriptor return null; } - private Object createStub(Class grpcServiceClass, String host, int port) { + private Object createStub(Class grpcServiceClass, Channel channel) { try { Method stubFactoryMethod = grpcServiceClass.getDeclaredMethod("newStub", Channel.class); - return stubFactoryMethod.invoke(null, getChannel(host, port)); + return stubFactoryMethod.invoke(null, channel); } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { LOG.warnf("Could not create stub for %s - " + e.getMessage(), grpcServiceClass); return null; } } - private Channel getChannel(String host, int port) { + private ManagedChannel getChannel(String host, int port) { return NettyChannelBuilder .forAddress(host, port) .usePlaintext() From 3bffbec7ee6ee44b094fc57861b38f9f550a2ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Bresson?= Date: Wed, 18 Sep 2024 21:29:33 +0200 Subject: [PATCH 02/16] Fix example in "Accessing Static Fields and Methods" (cherry picked from commit 913217d839c5ab3022d1efc066de79441564868f) --- docs/src/main/asciidoc/qute-reference.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/qute-reference.adoc b/docs/src/main/asciidoc/qute-reference.adoc index 654b06364b895..ec2baa1116b13 100644 --- a/docs/src/main/asciidoc/qute-reference.adoc +++ b/docs/src/main/asciidoc/qute-reference.adoc @@ -2395,12 +2395,12 @@ public class Statuses { public static final String OFF = "off"; } ---- -<1> A name resolver with the namespace `model_Status` is generated automatically. +<1> A name resolver with the namespace `model_Statuses` is generated automatically. .Template Accessing Class Constants [source,html] ---- -{#if machine.status == model_Status:ON} +{#if machine.status == model_Statuses:ON} The machine is ON! {/if} ---- From b4dda8d359cbe736d83fbd6f08746b66f2febd45 Mon Sep 17 00:00:00 2001 From: Yurii Dubinka Date: Wed, 18 Sep 2024 10:13:26 +0300 Subject: [PATCH 03/16] Remove unnecessary symbols that force you to change lines after copying each time (cherry picked from commit dec1d0b67364d14e73461ae0e61e1bb711e2c81a) --- docs/src/main/asciidoc/rabbitmq.adoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/src/main/asciidoc/rabbitmq.adoc b/docs/src/main/asciidoc/rabbitmq.adoc index 67c23e1502072..09f6ea5cb2e9a 100644 --- a/docs/src/main/asciidoc/rabbitmq.adoc +++ b/docs/src/main/asciidoc/rabbitmq.adoc @@ -398,14 +398,14 @@ You just need to run both applications using: [source,bash] ---- -> mvn -f rabbitmq-quickstart-producer quarkus:dev +mvn -f rabbitmq-quickstart-producer quarkus:dev ---- And, in a separate terminal: [source, bash] ---- -> mvn -f rabbitmq-quickstart-processor quarkus:dev +mvn -f rabbitmq-quickstart-processor quarkus:dev ---- Quarkus starts a RabbitMQ broker automatically, configures the application and shares the broker instance between different applications. @@ -469,8 +469,8 @@ First, make sure you stopped the applications, and build both applications in JV [source, bash] ---- -> mvn -f rabbitmq-quickstart-producer clean package -> mvn -f rabbitmq-quickstart-processor clean package +mvn -f rabbitmq-quickstart-producer clean package +mvn -f rabbitmq-quickstart-processor clean package ---- Once packaged, run `docker compose up --build`. @@ -480,8 +480,8 @@ To run your applications as native, first we need to build the native executable [source, bash] ---- -> mvn -f rabbitmq-quickstart-producer package -Dnative -Dquarkus.native.container-build=true -> mvn -f rabbitmq-quickstart-processor package -Dnative -Dquarkus.native.container-build=true +mvn -f rabbitmq-quickstart-producer package -Dnative -Dquarkus.native.container-build=true +mvn -f rabbitmq-quickstart-processor package -Dnative -Dquarkus.native.container-build=true ---- The `-Dquarkus.native.container-build=true` instructs Quarkus to build Linux 64bits native executables, who can run inside containers. @@ -489,8 +489,8 @@ Then, run the system using: [source, bash] ---- -> export QUARKUS_MODE=native -> docker compose up --build +export QUARKUS_MODE=native +docker compose up --build ---- As before, the UI is exposed on http://localhost:8080/quotes.html From f01c5141bf3ef6f45cbe224098888c1669c2a08a Mon Sep 17 00:00:00 2001 From: Rostislav Svoboda Date: Fri, 20 Sep 2024 12:01:03 +0200 Subject: [PATCH 04/16] Add a note about passing arguments for gradle project (cherry picked from commit 10f54f3dcb921fbe06dc7356d0554f99f969aeaa) --- docs/src/main/asciidoc/picocli.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/picocli.adoc b/docs/src/main/asciidoc/picocli.adoc index 4ec8182a34c41..76dd5fc9d268d 100644 --- a/docs/src/main/asciidoc/picocli.adoc +++ b/docs/src/main/asciidoc/picocli.adoc @@ -297,7 +297,7 @@ annotationProcessor 'info.picocli:picocli-codegen' == Development Mode -In the development mode, i.e. when running `mvn quarkus:dev`, the application is executed and restarted every time the `Space bar` key is pressed. You can also pass arguments to your command line app via the `quarkus.args` system property, e.g. `mvn quarkus:dev -Dquarkus.args='--help'` and `mvn quarkus:dev -Dquarkus.args='-c -w --val 1'`. +In the development mode, i.e. when running `mvn quarkus:dev`, the application is executed and restarted every time the `Space bar` key is pressed. You can also pass arguments to your command line app via the `quarkus.args` system property, e.g. `mvn quarkus:dev -Dquarkus.args='--help'` and `mvn quarkus:dev -Dquarkus.args='-c -w --val 1'`. For gradle project arguments can be passed using `--quarkus-args`. == Kubernetes support From 7ad03f03b47c288ddb8ffb1beec391aca95ac22b Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Fri, 20 Sep 2024 16:50:24 +0200 Subject: [PATCH 05/16] Remove a duplicated line in the TLS registry guide (cherry picked from commit f2a85155ff4feaf1ddc9bfaab833be161e5e27a4) --- docs/src/main/asciidoc/tls-registry-reference.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/main/asciidoc/tls-registry-reference.adoc b/docs/src/main/asciidoc/tls-registry-reference.adoc index 594b699042bbc..2d004c41f0e5b 100644 --- a/docs/src/main/asciidoc/tls-registry-reference.adoc +++ b/docs/src/main/asciidoc/tls-registry-reference.adoc @@ -768,7 +768,6 @@ The generated secret includes the following files: == Working with OpenShift serving certificates -When running your application in OpenShift, you can use the link:https://docs.openshift.com/container-platform/4.16/security/certificates/service-serving-certificate.html[OpenShift serving certificates] to generate and renew TLS certificates automatically. When running your application in OpenShift, you can use the link:https://docs.openshift.com/container-platform/4.16/security/certificates/service-serving-certificate.html[OpenShift serving certificates] to generate and renew TLS certificates automatically. The Quarkus TLS registry can use these certificates and Certificate Authority (CA) files to handle HTTPS traffic and validate certificates securely. From c3174f7cbf9e7126a46b142c0ea408aaf1cde023 Mon Sep 17 00:00:00 2001 From: Matthias Schorsch Date: Sun, 22 Sep 2024 10:55:35 +0200 Subject: [PATCH 06/16] Bump protoc/protobuf-java from 3.25.3 to 3.25.5 (cherry picked from commit ab0e693ce147219bde303192c5078f9f2833f78a) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cd9e468dbd817..9cd2125ab9c66 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ 1.65.1 1.2.2 - 3.25.3 + 3.25.5 ${protoc.version} 2.41.0 From 7ab69dcf6dd35c24f627ae6dea629d7cd307e342 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Thu, 22 Aug 2024 18:05:17 +0100 Subject: [PATCH 07/16] Bump Keycloak version to 25.0.4 (cherry picked from commit a2f5b9055cd338e93c3999555fc8b5ed9003346a) --- bom/application/pom.xml | 2 +- build-parent/pom.xml | 2 +- docs/src/main/asciidoc/security-keycloak-authorization.adoc | 2 +- .../security-oidc-bearer-token-authentication-tutorial.adoc | 2 +- .../security-oidc-code-flow-authentication-tutorial.adoc | 2 +- .../src/main/asciidoc/security-openid-connect-dev-services.adoc | 2 +- .../src/main/asciidoc/security-openid-connect-multitenancy.adoc | 2 +- .../oidc/deployment/devservices/keycloak/DevServicesConfig.java | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 41465791e1006..9550b07de2ab2 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -182,7 +182,7 @@ 5.12.0 5.8.0 2.1.0 - 25.0.2 + 25.0.4 1.15.1 3.46.0 2.30.0 diff --git a/build-parent/pom.xml b/build-parent/pom.xml index 47ac212e90bd7..995b5a311584b 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -95,7 +95,7 @@ - 25.0.2 + 25.0.4 19.0.3 quay.io/keycloak/keycloak:${keycloak.version} quay.io/keycloak/keycloak:${keycloak.wildfly.version}-legacy diff --git a/docs/src/main/asciidoc/security-keycloak-authorization.adoc b/docs/src/main/asciidoc/security-keycloak-authorization.adoc index 4c39f3fc6f18a..622dd26ac9d20 100644 --- a/docs/src/main/asciidoc/security-keycloak-authorization.adoc +++ b/docs/src/main/asciidoc/security-keycloak-authorization.adoc @@ -226,7 +226,7 @@ To start a Keycloak server, use the following Docker command: docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8543:8443 -v "$(pwd)"/config/keycloak-keystore.jks:/etc/keycloak-keystore.jks quay.io/keycloak/keycloak:{keycloak.version} start --hostname-strict=false --https-key-store-file=/etc/keycloak-keystore.jks ---- -where `keycloak.version` must be `25.0.2` or later and the `keycloak-keystore.jks` can be found in https://github.com/quarkusio/quarkus-quickstarts/blob/main/security-keycloak-authorization-quickstart/config/keycloak-keystore.jks[quarkus-quickstarts/security-keycloak-authorization-quickstart/config]. +where `keycloak.version` must be `25.0.4` or later and the `keycloak-keystore.jks` can be found in https://github.com/quarkusio/quarkus-quickstarts/blob/main/security-keycloak-authorization-quickstart/config/keycloak-keystore.jks[quarkus-quickstarts/security-keycloak-authorization-quickstart/config]. Try to access your Keycloak server at https://localhost:8543[localhost:8543]. diff --git a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc index 3ab3219bf63f3..e121297f002e3 100644 --- a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc +++ b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc @@ -217,7 +217,7 @@ For more information, see the <> sectio docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev ---- ==== -* Where the `keycloak.version` is set to version `25.0.2` or later. +* Where the `keycloak.version` is set to version `25.0.4` or later. . You can access your Keycloak server at http://localhost:8180[localhost:8180]. . To access the Keycloak Administration console, log in as the `admin` user by using the following login credentials: diff --git a/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc index 0242b00ecdc7e..ab80868693399 100644 --- a/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc +++ b/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc @@ -201,7 +201,7 @@ To start a Keycloak server, use Docker and run the following command: docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev ---- -where `keycloak.version` is set to `25.0.2` or later. +where `keycloak.version` is set to `25.0.4` or later. You can access your Keycloak Server at http://localhost:8180[localhost:8180]. diff --git a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc index 0b335a70fafa1..06fbd85904a66 100644 --- a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc @@ -258,7 +258,7 @@ For more information, see xref:security-oidc-bearer-token-authentication.adoc#be [[keycloak-initialization]] === Keycloak initialization -The `quay.io/keycloak/keycloak:25.0.2` image which contains a Keycloak distribution powered by Quarkus is used to start a container by default. +The `quay.io/keycloak/keycloak:25.0.4` image which contains a Keycloak distribution powered by Quarkus is used to start a container by default. `quarkus.keycloak.devservices.image-name` can be used to change the Keycloak image name. For example, set it to `quay.io/keycloak/keycloak:19.0.3-legacy` to use a Keycloak distribution powered by WildFly. Be aware that a Quarkus-based Keycloak distribution is only available starting from Keycloak `20.0.0`. diff --git a/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc b/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc index 342643b9dcc1c..0928eb5ff50b6 100644 --- a/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc @@ -356,7 +356,7 @@ To start a Keycloak server, you can use Docker and run the following command: docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev ---- -where `keycloak.version` is set to `25.0.2` or higher. +where `keycloak.version` is set to `25.0.4` or higher. Access your Keycloak server at http://localhost:8180[localhost:8180]. diff --git a/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java b/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java index f039fd0b8bdf9..c08bf4986472d 100644 --- a/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java +++ b/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java @@ -34,7 +34,7 @@ public class DevServicesConfig { * ends with `-legacy`. * Override with `quarkus.keycloak.devservices.keycloak-x-image`. */ - @ConfigItem(defaultValue = "quay.io/keycloak/keycloak:25.0.2") + @ConfigItem(defaultValue = "quay.io/keycloak/keycloak:25.0.4") public String imageName; /** From 42fe3d8184774e713af8260889704b5af313668e Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Mon, 16 Sep 2024 11:26:19 +0300 Subject: [PATCH 08/16] Fix REST Client proxy configuration when multiple clients exist (cherry picked from commit 2fd56d524dfdbcaaf249d325b5310609bbf47a99) --- .../DevServicesRestClientHttpProxyProcessor.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/devservices/DevServicesRestClientHttpProxyProcessor.java b/extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/devservices/DevServicesRestClientHttpProxyProcessor.java index 9a68ff95ae88d..9817fa8148b93 100644 --- a/extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/devservices/DevServicesRestClientHttpProxyProcessor.java +++ b/extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/devservices/DevServicesRestClientHttpProxyProcessor.java @@ -68,7 +68,7 @@ public void determineRequiredProxies(RestClientsBuildTimeConfig restClientsBuild for (var configEntry : configs.entrySet()) { if (!configEntry.getValue().enableLocalProxy()) { log.trace("Ignoring config key: '" + configEntry.getKey() + "' because enableLocalProxy is false"); - break; + continue; } String configKey = configEntry.getKey(); @@ -91,7 +91,7 @@ public void determineRequiredProxies(RestClientsBuildTimeConfig restClientsBuild if (baseUri.isEmpty()) { log.debug("Unable to determine uri or url for config key '" + configKey + "'"); - break; + continue; } producer.produce(new RestClientHttpProxyBuildItem(matchingBI.getClassInfo().name().toString(), baseUri.get(), configEntry.getValue().localProxyProvider())); @@ -101,14 +101,14 @@ public void determineRequiredProxies(RestClientsBuildTimeConfig restClientsBuild if (classInfo == null) { log.debug( "Key '" + configKey + "' could not be matched to either a class name or a REST Client's configKey"); - break; + continue; } Optional baseUri = oneOf( Optional.ofNullable(restClientValues.get("uri")), Optional.ofNullable(restClientValues.get("url"))); if (baseUri.isEmpty()) { log.debug("Unable to determine uri or url for config key '" + configKey + "'"); - break; + continue; } producer.produce(new RestClientHttpProxyBuildItem(classInfo.name().toString(), baseUri.get(), configEntry.getValue().localProxyProvider())); From 96e2ad00b13728b32084d5582b51fad9d7dd311b Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Mon, 16 Sep 2024 11:41:05 +0300 Subject: [PATCH 09/16] Use proper config key for REST Client override URI (cherry picked from commit f2f4a2febc0f8861c7567b02d60cbfaa467f3317) --- .../rest/client/reactive/runtime/RestClientBuilderImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientBuilderImpl.java b/extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientBuilderImpl.java index 828034de5c9be..ceddd80f6ec89 100644 --- a/extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientBuilderImpl.java +++ b/extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientBuilderImpl.java @@ -399,7 +399,8 @@ public T build(Class aClass) throws IllegalStateException, RestClientDefi RestClientsConfig restClients = config.getConfigMapping(RestClientsConfig.class); // support overriding the URI from the override-uri property - Optional maybeOverrideUri = restClients.getClient(aClass).overrideUri(); + var overrideUrlKeyName = String.format("quarkus.rest-client.\"%s\".override-uri", aClass.getName()); + Optional maybeOverrideUri = config.getOptionalValue(overrideUrlKeyName, String.class); if (maybeOverrideUri.isPresent()) { uri = URI.create(maybeOverrideUri.get()); } From d4577d9ee506d9330b0bb1606c4911391434fde6 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Fri, 20 Sep 2024 21:50:39 +0100 Subject: [PATCH 10/16] Bump Keycloak version to 25.0.6 (cherry picked from commit 42f5df8fc45423af67f1c4319b5d1049941af5fe) --- bom/application/pom.xml | 2 +- build-parent/pom.xml | 2 +- docs/src/main/asciidoc/security-keycloak-authorization.adoc | 2 +- .../security-oidc-bearer-token-authentication-tutorial.adoc | 2 +- .../security-oidc-code-flow-authentication-tutorial.adoc | 2 +- docs/src/main/asciidoc/security-openid-connect-client.adoc | 2 +- .../src/main/asciidoc/security-openid-connect-dev-services.adoc | 2 +- .../src/main/asciidoc/security-openid-connect-multitenancy.adoc | 2 +- .../oidc/deployment/devservices/keycloak/DevServicesConfig.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 9550b07de2ab2..230430cd23c2f 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -182,7 +182,7 @@ 5.12.0 5.8.0 2.1.0 - 25.0.4 + 25.0.6 1.15.1 3.46.0 2.30.0 diff --git a/build-parent/pom.xml b/build-parent/pom.xml index 995b5a311584b..d903e480e1091 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -95,7 +95,7 @@ - 25.0.4 + 25.0.6 19.0.3 quay.io/keycloak/keycloak:${keycloak.version} quay.io/keycloak/keycloak:${keycloak.wildfly.version}-legacy diff --git a/docs/src/main/asciidoc/security-keycloak-authorization.adoc b/docs/src/main/asciidoc/security-keycloak-authorization.adoc index 622dd26ac9d20..f6bd96305e109 100644 --- a/docs/src/main/asciidoc/security-keycloak-authorization.adoc +++ b/docs/src/main/asciidoc/security-keycloak-authorization.adoc @@ -226,7 +226,7 @@ To start a Keycloak server, use the following Docker command: docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8543:8443 -v "$(pwd)"/config/keycloak-keystore.jks:/etc/keycloak-keystore.jks quay.io/keycloak/keycloak:{keycloak.version} start --hostname-strict=false --https-key-store-file=/etc/keycloak-keystore.jks ---- -where `keycloak.version` must be `25.0.4` or later and the `keycloak-keystore.jks` can be found in https://github.com/quarkusio/quarkus-quickstarts/blob/main/security-keycloak-authorization-quickstart/config/keycloak-keystore.jks[quarkus-quickstarts/security-keycloak-authorization-quickstart/config]. +where `keycloak.version` must be `25.0.6` or later and the `keycloak-keystore.jks` can be found in https://github.com/quarkusio/quarkus-quickstarts/blob/main/security-keycloak-authorization-quickstart/config/keycloak-keystore.jks[quarkus-quickstarts/security-keycloak-authorization-quickstart/config]. Try to access your Keycloak server at https://localhost:8543[localhost:8543]. diff --git a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc index e121297f002e3..398beed5c8bcb 100644 --- a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc +++ b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc @@ -217,7 +217,7 @@ For more information, see the <> sectio docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev ---- ==== -* Where the `keycloak.version` is set to version `25.0.4` or later. +* Where the `keycloak.version` is set to version `25.0.6` or later. . You can access your Keycloak server at http://localhost:8180[localhost:8180]. . To access the Keycloak Administration console, log in as the `admin` user by using the following login credentials: diff --git a/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc index ab80868693399..c54a5d7eea5e6 100644 --- a/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc +++ b/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc @@ -201,7 +201,7 @@ To start a Keycloak server, use Docker and run the following command: docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev ---- -where `keycloak.version` is set to `25.0.4` or later. +where `keycloak.version` is set to `25.0.6` or later. You can access your Keycloak Server at http://localhost:8180[localhost:8180]. diff --git a/docs/src/main/asciidoc/security-openid-connect-client.adoc b/docs/src/main/asciidoc/security-openid-connect-client.adoc index 89420725660f8..5e6686a5c389f 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client.adoc @@ -507,7 +507,7 @@ To start a Keycloak Server, you can use Docker and just run the following comman docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev ---- -Set `{keycloak.version}` to `25.0.2` or later. +Set `{keycloak.version}` to `25.0.6` or later. You can access your Keycloak Server at http://localhost:8180[localhost:8180]. diff --git a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc index 06fbd85904a66..b29e619011004 100644 --- a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc @@ -258,7 +258,7 @@ For more information, see xref:security-oidc-bearer-token-authentication.adoc#be [[keycloak-initialization]] === Keycloak initialization -The `quay.io/keycloak/keycloak:25.0.4` image which contains a Keycloak distribution powered by Quarkus is used to start a container by default. +The `quay.io/keycloak/keycloak:25.0.6` image which contains a Keycloak distribution powered by Quarkus is used to start a container by default. `quarkus.keycloak.devservices.image-name` can be used to change the Keycloak image name. For example, set it to `quay.io/keycloak/keycloak:19.0.3-legacy` to use a Keycloak distribution powered by WildFly. Be aware that a Quarkus-based Keycloak distribution is only available starting from Keycloak `20.0.0`. diff --git a/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc b/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc index 0928eb5ff50b6..69e7453e96989 100644 --- a/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc @@ -356,7 +356,7 @@ To start a Keycloak server, you can use Docker and run the following command: docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev ---- -where `keycloak.version` is set to `25.0.4` or higher. +where `keycloak.version` is set to `25.0.6` or higher. Access your Keycloak server at http://localhost:8180[localhost:8180]. diff --git a/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java b/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java index c08bf4986472d..ab18a1cad3c45 100644 --- a/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java +++ b/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java @@ -34,7 +34,7 @@ public class DevServicesConfig { * ends with `-legacy`. * Override with `quarkus.keycloak.devservices.keycloak-x-image`. */ - @ConfigItem(defaultValue = "quay.io/keycloak/keycloak:25.0.4") + @ConfigItem(defaultValue = "quay.io/keycloak/keycloak:25.0.6") public String imageName; /** From 1afb9057350eb1eee95dd9ad3326161cadec0703 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Fri, 20 Sep 2024 10:58:39 +0300 Subject: [PATCH 11/16] Fix classloading in AzureFunctionsProcessor#findFunctions Closes: #38531 (cherry picked from commit 4fdc574c5c5fd615eb153f34a13b923e0c0a71aa) --- .../azure/functions/deployment/AzureFunctionsProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/azure-functions/deployment/src/main/java/io/quarkus/azure/functions/deployment/AzureFunctionsProcessor.java b/extensions/azure-functions/deployment/src/main/java/io/quarkus/azure/functions/deployment/AzureFunctionsProcessor.java index 0a4bb08f97ef7..bf5e89055a670 100644 --- a/extensions/azure-functions/deployment/src/main/java/io/quarkus/azure/functions/deployment/AzureFunctionsProcessor.java +++ b/extensions/azure-functions/deployment/src/main/java/io/quarkus/azure/functions/deployment/AzureFunctionsProcessor.java @@ -213,7 +213,7 @@ public void findFunctions(CombinedIndexBuildItem combined, Class declaring = loader.loadClass(ci.name().toString()); Class[] params = methodInfo.parameters().stream().map(methodParameterInfo -> { try { - return loader.loadClass(methodParameterInfo.type().name().toString()); + return Class.forName(methodParameterInfo.type().name().toString(), false, loader); } catch (ClassNotFoundException e) { throw new DeploymentException(e); } From 515e7737c73d923cf815ec84395cc372d26f1e0b Mon Sep 17 00:00:00 2001 From: Rolfe Dlugy-Hegwer Date: Mon, 23 Sep 2024 11:40:42 -0400 Subject: [PATCH 12/16] Update step headings to prevent confusing numbering (cherry picked from commit 8492f46394ce9b113cbd049f70c21cb7df92e650) --- .../asciidoc/security-openid-connect-multitenancy.adoc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc b/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc index 69e7453e96989..02ccf45bee913 100644 --- a/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc @@ -894,19 +894,21 @@ quarkus.oidc.tenant-b.credentials.secret=${tenant-b-client-secret} Tenant resolution for the OIDC `web-app` applications must be done at least 3 times during an authorization code flow, when the OIDC tenant-specific configuration affects how each of the following steps is run. -==== Step 1: Unauthenticated user accesses an endpoint and is redirected to OIDC provider +.Step 1: Unauthenticated user accesses an endpoint and is redirected to OIDC provider When an unauthenticated user accesses a secured path, the user is redirected to the OIDC provider to authenticate and the tenant configuration is used to build the redirect URI. All the static and dynamic tenant resolution options listed in the <> and <> sections can be used to resolve a tenant. -==== Step 2: The user is redirected back to the endpoint +.Step 2: The user is redirected back to the endpoint After the provider authentication, the user is redirected back to the Quarkus endpoint and the tenant configuration is used to complete the authorization code flow. All the static and dynamic tenant resolution options listed in the <> and <> sections can be used to resolve a tenant. Before the tenant resolution begins, the authorization code flow `state cookie` is used to set the already resolved tenant configuration id as a RoutingContext `tenant-id` attribute: both custom dynamic `TenantConfigResolver` and static `TenantResolver` tenant resolvers can check it. -==== Step 3: Authenticated user accesses the secured path using the session cookie: the tenant configuration determines how the session cookie is verified and refreshed. Before the tenant resolution begins, the authorization code flow `session cookie` is used to set the already resolved tenant configuration id as a RoutingContext `tenant-id` attribute: both custom dynamic `TenantConfigResolver` and static `TenantResolver` tenant resolvers can check it. +.Step 3: Authenticated user accesses the secured path using the session cookie + +The tenant configuration determines how the session cookie is verified and refreshed. Before the tenant resolution begins, the authorization code flow `session cookie` is used to set the already resolved tenant configuration id as a RoutingContext `tenant-id` attribute: both custom dynamic `TenantConfigResolver` and static `TenantResolver` tenant resolvers can check it. For example, here is how a custom `TenantConfigResolver` can avoid creating the already resolved tenant configuration, that may otherwise require blocking reads from the database or other remote sources: From 4e32c3d3698464c6f31648d33e2a73ff12fa3187 Mon Sep 17 00:00:00 2001 From: Auri Munoz Date: Mon, 23 Sep 2024 18:59:49 +0200 Subject: [PATCH 13/16] Document newly supported interfaces and update existing examples. Fixes #43391 (cherry picked from commit 859628d32cb57f0567a3aa7247be5503945e31ea) --- docs/src/main/asciidoc/spring-data-jpa.adoc | 2 ++ docs/src/main/asciidoc/spring-data-rest.adoc | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/spring-data-jpa.adoc b/docs/src/main/asciidoc/spring-data-jpa.adoc index 52c20b03c83e4..b04961054c577 100644 --- a/docs/src/main/asciidoc/spring-data-jpa.adoc +++ b/docs/src/main/asciidoc/spring-data-jpa.adoc @@ -416,7 +416,9 @@ Interfaces that extend any of the following Spring Data repositories are automat * `org.springframework.data.repository.Repository` * `org.springframework.data.repository.CrudRepository` +* `org.springframework.data.repository.ListCrudRepository` * `org.springframework.data.repository.PagingAndSortingRepository` +* `org.springframework.data.repository.ListPagingAndSortingRepository` * `org.springframework.data.jpa.repository.JpaRepository` The generated repositories are also registered as beans so they can be injected into any other bean. diff --git a/docs/src/main/asciidoc/spring-data-rest.adoc b/docs/src/main/asciidoc/spring-data-rest.adoc index e3e95121e920e..e83aeb064e2c1 100644 --- a/docs/src/main/asciidoc/spring-data-rest.adoc +++ b/docs/src/main/asciidoc/spring-data-rest.adoc @@ -327,7 +327,7 @@ The former is used by default, but it is highly recommended to specify which one If a database contains many entities, it might not be a great idea to return them all at once. `PagingAndSortingRepository` allows the `spring-data-rest` extension to access data in chunks. -Replace the `CrudRepository` with `PagingAndSortingRepository` in the `FruitsRepository`: +So, you can extend the `PagingAndSortingRepository`: [source,java] ---- @@ -335,7 +335,7 @@ package org.acme.spring.data.rest; import org.springframework.data.repository.PagingAndSortingRepository; -public interface FruitsRepository extends PagingAndSortingRepository { +public interface FruitsRepository extends CrudRepository, PagingAndSortingRepository { } ---- @@ -362,6 +362,19 @@ Now the `GET /fruits` will accept three new query parameters: `sort`, `page` and For paged responses, `spring-data-rest` also returns a set of link headers that can be used to access other pages: first, previous, next and last. +Additionally, rather than extending both `PagingAndSortingRepository` and `CrudRepository`, you can use `JpaRepository`, which is a higher-level abstraction tailored for JPA. Since `JpaRepository` already extends both `PagingAndSortingRepository` and `CrudRepository`, it can replace `CrudRepository` directly. + +[source,java] +---- +package org.acme.spring.data.rest; + +import org.springframework.data.repository.PagingAndSortingRepository; + +public interface FruitsRepository extends JpaRepository { +} +---- + + ==== Fine tuning endpoints generation This allows user to specify which methods should be exposed and what path should be used to access them. From ff2c8683d6159b917a3c568094603d686f408528 Mon Sep 17 00:00:00 2001 From: Jan Martiska Date: Tue, 24 Sep 2024 10:39:54 +0200 Subject: [PATCH 14/16] Remove a superfluous quote in the GraphQL client docs (cherry picked from commit 3b77652dd4d418899a5443ddd26a3d78ee729f2d) --- docs/src/main/asciidoc/smallrye-graphql-client.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/smallrye-graphql-client.adoc b/docs/src/main/asciidoc/smallrye-graphql-client.adoc index 1693ac21b730c..c9928ffdec09e 100644 --- a/docs/src/main/asciidoc/smallrye-graphql-client.adoc +++ b/docs/src/main/asciidoc/smallrye-graphql-client.adoc @@ -287,7 +287,7 @@ to properly qualify the injection point. If you need to add an authorization header, or any other custom HTTP header (in our case it's not required), this can be done by: ---- -quarkus.smallrye-graphql-client.star-wars-dynamic.header.HEADER-KEY=HEADER-VALUE" +quarkus.smallrye-graphql-client.star-wars-dynamic.header.HEADER-KEY=HEADER-VALUE ---- Add this to the `StarWarsResource` created earlier: From 59a7c8d0f7620031973c8921b01a3936ce596563 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 24 Sep 2024 13:51:47 +0200 Subject: [PATCH 15/16] Small followup for Picocli + Gradle improvement Follow up on https://github.com/quarkusio/quarkus/pull/43407 (cherry picked from commit 242bba8798a5f3a7b83b4ef5d6102a3553f0d598) --- docs/src/main/asciidoc/picocli.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/picocli.adoc b/docs/src/main/asciidoc/picocli.adoc index 76dd5fc9d268d..641dfa08312a8 100644 --- a/docs/src/main/asciidoc/picocli.adoc +++ b/docs/src/main/asciidoc/picocli.adoc @@ -297,7 +297,8 @@ annotationProcessor 'info.picocli:picocli-codegen' == Development Mode -In the development mode, i.e. when running `mvn quarkus:dev`, the application is executed and restarted every time the `Space bar` key is pressed. You can also pass arguments to your command line app via the `quarkus.args` system property, e.g. `mvn quarkus:dev -Dquarkus.args='--help'` and `mvn quarkus:dev -Dquarkus.args='-c -w --val 1'`. For gradle project arguments can be passed using `--quarkus-args`. +In the development mode, i.e. when running `mvn quarkus:dev`, the application is executed and restarted every time the `Space bar` key is pressed. You can also pass arguments to your command line app via the `quarkus.args` system property, e.g. `mvn quarkus:dev -Dquarkus.args='--help'` and `mvn quarkus:dev -Dquarkus.args='-c -w --val 1'`. +For Gradle projects, arguments can be passed using `--quarkus-args`. == Kubernetes support From 3cda9d5adaf8c9a46f9be6b0b1c802919ebd8976 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 25 Sep 2024 13:26:05 +0200 Subject: [PATCH 16/16] Config Doc - Bring back the links for config sections and properties Fixes #43310 (cherry picked from commit 330ba22dc1dab8cec0d9295b746f15c153459b23) --- .../src/main/resources/templates/tags/configProperty.qute.adoc | 2 +- .../src/main/resources/templates/tags/configSection.qute.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/devtools/config-doc-maven-plugin/src/main/resources/templates/tags/configProperty.qute.adoc b/devtools/config-doc-maven-plugin/src/main/resources/templates/tags/configProperty.qute.adoc index dd3a23f0d0abc..79072c86ad183 100644 --- a/devtools/config-doc-maven-plugin/src/main/resources/templates/tags/configProperty.qute.adoc +++ b/devtools/config-doc-maven-plugin/src/main/resources/templates/tags/configProperty.qute.adoc @@ -1,4 +1,4 @@ -a|{#if configProperty.phase.fixedAtBuildTime}icon:lock[title=Fixed at build time]{/if} [[{configProperty.toAnchor(extension, additionalAnchorPrefix)}]] [.property-path]##`{configProperty.path}`## +a|{#if configProperty.phase.fixedAtBuildTime}icon:lock[title=Fixed at build time]{/if} [[{configProperty.toAnchor(extension, additionalAnchorPrefix)}]] [.property-path]##link:#{configProperty.toAnchor(extension, additionalAnchorPrefix)}[`{configProperty.path}`]## {#for additionalPath in configProperty.additionalPaths} `{additionalPath}` diff --git a/devtools/config-doc-maven-plugin/src/main/resources/templates/tags/configSection.qute.adoc b/devtools/config-doc-maven-plugin/src/main/resources/templates/tags/configSection.qute.adoc index d8673758bdd46..bdc9d412458f8 100644 --- a/devtools/config-doc-maven-plugin/src/main/resources/templates/tags/configSection.qute.adoc +++ b/devtools/config-doc-maven-plugin/src/main/resources/templates/tags/configSection.qute.adoc @@ -1,4 +1,4 @@ -h|[[{configSection.toAnchor(extension, additionalAnchorPrefix)}]] [.section-name.section-level{configSection.level}]##{configSection.formatTitle.escapeCellContent}## +h|[[{configSection.toAnchor(extension, additionalAnchorPrefix)}]] [.section-name.section-level{configSection.level}]##link:#{configSection.toAnchor(extension, additionalAnchorPrefix)}[{configSection.formatTitle.escapeCellContent}]## h|Type h|Default