This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new c1dc4f3be68e CAMEL-23806: Split and condense user manual docs
c1dc4f3be68e is described below

commit c1dc4f3be68e4cb8a60ea1495dbd3514fe9351e8
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Jun 20 19:21:04 2026 +0200

    CAMEL-23806: Split and condense user manual docs
    
    Split and condense overly long user manual documentation pages:
    
    - Property Placeholders: Extract functions reference (vault syntax, 
Kubernetes, custom functions) into a focused sub-page, reducing 
using-propertyplaceholder.adoc from ~1,480 to ~747 lines
    - Route Templates: Extract bean binding (advanced) section into a focused 
sub-page, reducing route-template.adoc from ~1,390 to ~759 lines
    - Security: Condense vault configuration sections by factoring out repeated 
Java/XML/YAML tab blocks into a single "Vault Usage Syntax" reference with a 
provider prefix table, reducing security.adoc by ~60% (~1,225 lines removed)
    
    Co-Authored-By: Claude <[email protected]>
---
 docs/user-manual/modules/ROOT/nav.adoc             |    2 +
 .../ROOT/pages/property-placeholder-functions.adoc |  743 ++++++++++
 .../ROOT/pages/route-template-bean-binding.adoc    |  641 ++++++++
 .../modules/ROOT/pages/route-template.adoc         |  639 +-------
 docs/user-manual/modules/ROOT/pages/security.adoc  | 1557 +++-----------------
 .../ROOT/pages/using-propertyplaceholder.adoc      |  741 +---------
 6 files changed, 1560 insertions(+), 2763 deletions(-)

diff --git a/docs/user-manual/modules/ROOT/nav.adoc 
b/docs/user-manual/modules/ROOT/nav.adoc
index 76239ecd48a6..b3d74e9d0d06 100644
--- a/docs/user-manual/modules/ROOT/nav.adoc
+++ b/docs/user-manual/modules/ROOT/nav.adoc
@@ -27,6 +27,7 @@
 ** xref:error-handler.adoc[Error handler]
 ** xref:error-registry.adoc[Error Registry]
 ** xref:using-propertyplaceholder.adoc[How to use Camel property placeholders]
+*** xref:property-placeholder-functions.adoc[Property Placeholder Functions]
 ** xref:variables.adoc[How to use Variables]
 ** xref:testing.adoc[Testing]
 *** xref:test-infra.adoc[Test Infra]
@@ -97,6 +98,7 @@
 ** xref:route-reload.adoc[RouteReload]
 ** xref:route-diagram.adoc[Visual Route Diagrams]
 ** xref:route-template.adoc[RouteTemplate]
+*** xref:route-template-bean-binding.adoc[Bean Binding]
 ** xref:routes.adoc[Routes]
 ** xref:startup-condition.adoc[Startup Condition]
 ** xref:stream-caching.adoc[Stream caching]
diff --git 
a/docs/user-manual/modules/ROOT/pages/property-placeholder-functions.adoc 
b/docs/user-manual/modules/ROOT/pages/property-placeholder-functions.adoc
new file mode 100644
index 000000000000..14c4c05fe2d1
--- /dev/null
+++ b/docs/user-manual/modules/ROOT/pages/property-placeholder-functions.adoc
@@ -0,0 +1,743 @@
+= Property Placeholder Functions
+:tabs-sync-option:
+
+xref:using-propertyplaceholder.adoc[Back to Property Placeholders]
+
+The xref:components::properties-component.adoc[Properties] component includes 
the following functions out of the box:
+
+* `env` - A function to lookup the property from OS environment variables
+* `sys` - A function to lookup the property from Java JVM system properties
+* `bean` - A function to lookup the property from the return value of bean's 
method (requires `camel-bean` JAR)
+* `boolean` - A function to evaluate if a property key matches a condition and 
returns either `true` or `false`
+* `service` - A function to lookup the property from OS environment variables 
using the service naming idiom
+* `service.name` - A function to lookup the property from OS environment 
variables using the service naming idiom returning the hostname part only
+* `service.port` - A function to lookup the property from OS environment 
variables using the service naming idiom returning the port part only
+
+These functions are intended to make it easy to lookup values from the 
environment, as shown in the example below:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+  .to("{{env:SOMENAME}}")
+  .to("{{sys:MyJvmPropertyName}}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+    <from uri="direct:start"/>
+    <to uri="{{env:SOMENAME}}"/>
+    <to uri="{{sys:MyJvmPropertyName}}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - to:
+            uri: "{{env:SOMENAME}}"
+        - to:
+            uri: "{{sys:MyJvmPropertyName}}"
+----
+====
+
+You can use default values as well, so if the property does not exist, you can 
define a default value as shown below, where the default value is a `log:foo` 
and `log:bar` value.
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+  .to("{{env:SOMENAME:log:foo}}")
+  .to("{{sys:MyJvmPropertyName:log:bar}}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+    <from uri="direct:start"/>
+    <to uri="{{env:SOMENAME:log:foo}}"/>
+    <to uri="{{sys:MyJvmPropertyName:log:bar}}"/>
+</route>
+----
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - to:
+            uri: "{{env:SOMENAME:log:foo}}"
+        - to:
+            uri: "{{sys:MyJvmPropertyName:log:bar}}"
+----
+====
+
+The boolean function is intended for more flexibility when enabling or 
disabling EIP options.
+
+For example given we have a property with key `region` that has the value 
`EMEA`:
+
+[source,properties]
+----
+region = EMEA
+----
+
+We can then configure EIPs whether they are disabled based on this condition 
as follows:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .choice().disabled("{{boolean:region == 'EMEA'}}")
+        .when(simple("${header.RetryAttempts} == null"))
+            .setProperty("HttpMessageMethod", constant("SET"))
+            .process("SetOriginalMessageProcessor")
+        .end();
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+    <from uri="direct:start"/>
+    <choice disabled="{{boolean:region == 'EMEA'}}">
+        <when>
+            <simple>${header.RetryAttempts} == null</simple>
+            <setProperty name="HttpMessageMethod">
+                <constant>SET</constant>
+            </setProperty>
+            <process ref="SetOriginalMessageProcessor"/>
+        </when>
+    </choice>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - choice:
+            disabled: "{{boolean:region == 'EMEA'}}"
+            when:
+            - expression:
+                simple:
+                  expression: "${header.RetryAttempts} == null"
+              steps:
+              - setProperty:
+                  name: "HttpMessageMethod"
+                  expression:
+                    constant: "SET"
+              - process:
+                  ref: "SetOriginalMessageProcessor"
+----
+====
+
+[NOTE]
+====
+Property placeholders can also be used in `application.properties` files, also 
with the functions such as ENV as shown:
+
+[source,properties]
+----
+# server name read from ENV and fallback to use localhost as default value
+myserver = {{env:MY_SERVER_NAME:localhost}}
+----
+====
+
+TIP: The boolean function uses the 
xref:components:languages:simple-language.adoc[Simple] language which has many 
functions and operators to build the condition.
+
+The service function is for looking up a service which is defined using OS 
environment variables using the service naming idiom, to refer to a service 
location using `hostname : port`
+
+* __NAME__**_SERVICE_HOST**
+* __NAME__**_SERVICE_PORT**
+
+in other words the service uses `_SERVICE_HOST` and `_SERVICE_PORT` as prefix.
+So if the service is named FOO, then the OS environment variables should be 
set as
+
+[source,bash]
+----
+export $FOO_SERVICE_HOST=myserver
+export $FOO_SERVICE_PORT=8888
+----
+
+For example if the FOO service a remote HTTP service, then we can refer to the 
service in the Camel endpoint uri, and use the HTTP component to make the HTTP 
call:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+  .to("http://{{service:FOO}}/myapp";);
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+    <from uri="direct:start"/>
+    <to uri="http://{{service:FOO}}/myapp"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - to:
+            uri: "http://{{service:FOO}}/myapp";
+----
+====
+
+And we can use default values if the service has not been defined, for example 
to call a service on localhost, maybe for unit testing.
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+  .to("http://{{service:FOO:localhost:8080}}/myapp";);
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+    <from uri="direct:start"/>
+    <to uri="http://{{service:FOO:localhost:8080}}/myapp"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - to:
+            uri: "http://{{service:FOO:localhost:8080}}/myapp";
+----
+====
+
+The bean function (you need to have `camel-bean` JAR on classpath) is for 
looking up the property from the return value of bean's method.
+
+Assuming we have registered a bean named 'foo' that has a method called 'bar' 
that returns a directory name, then we can refer to the bean's method in the 
camel endpoint url, and use the file component to poll a directory:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("file:{{bean:foo.bar}}")
+  .to("direct:result");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+    <from uri="file:{{bean:foo.bar}}"/>
+    <to uri="direct:result"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: file:{{bean:foo.bar}}
+      steps:
+        - to:
+            uri: "direct:result"
+----
+====
+
+IMPORTANT: The method must be a public no-arg method (i.e. no parameters) and 
return a value such as a String, boolean, int.
+
+== Using Kubernetes property placeholder functions
+
+The `camel-kubernetes` component include the following functions:
+
+* `configmap` - A function to lookup the string property from Kubernetes 
ConfigMaps.
+* `configmap-binary` - A function to lookup the binary property from 
Kubernetes ConfigMaps.
+* `secret` - A function to lookup the string property from Kubernetes Secrets.
+* `secret-binary` - A function to lookup the binary property from Kubernetes 
Secrets.
+
+The syntax for both functions are:
+
+[source,text]
+----
+configmap:name/key[:defaultValue]
+----
+
+Where the default value is optional, for example the following will lookup 
`myKey`,
+and fail if there is no such configmap.
+
+[source,text]
+----
+configmap:mymap/mykey
+----
+
+In this example then it would not fail as a default value is provided:
+
+[source,text]
+----
+configmap:mymap/mykey:123
+----
+
+If the value stored in the configmap is in binary format, so it is stored as 
`Binary Data`, it will be downloaded in a file, and it returns the absolute 
path of the file
+
+[source,text]
+----
+configmap-binary:mymap/mybinkey
+----
+
+it returns a path like `/tmp/camel11787545916150467474/mybinkey`
+
+Before the Kubernetes property placeholder functions can be used they need to 
be configured with either (or both)
+
+- path - A _mount path_ that must be mounted to the running pod, to load the 
configmaps or secrets from local disk.
+- kubernetes client - *Autowired* An 
`io.fabric8.kubernetes.client.KubernetesClient` instance to use for connecting 
to the Kubernetes API server.
+
+Camel will first use _mount paths_ (if configured) to lookup, and then 
fallback to use the `KubernetesClient`.
+
+=== Configuring mount paths for ConfigMaps and Secrets
+
+The configuration of the _mount path_ are used by the given order:
+
+1. Reading configuration property with keys 
`camel.kubernetes-config.mount-path-configmaps` and 
`camel.kubernetes-config.mount-path-secrets`.
+2. Use JVM system property with key `camel.k.mount-path.configmaps` and 
`camel.k.mount-path.secrets` (Camel K compatible).
+3. Use OS ENV variable with key `CAMEL_K_MOUNT_PATH_CONFIGMAPS` and 
`CAMEL_K_MOUNT_PATH_SECRETS` (Camel K compatible).
+
+For example to use `/etc/camel/resources/` as mount path, you can configure 
this in the `application.properties`:
+
+[source,properties]
+----
+camel.kubernetes-config.mount-path-configmaps = /etc/camel/myconfig/
+camel.kubernetes-config.mount-path-secrets = /etc/camel/mysecrets/
+----
+
+=== Configuring Kubernetes Client
+
+Camel will autowire the `KubernetesClient` if a single instance of the client 
exists in the running application (lookup via the xref:registry.adoc[Registry]).
+Otherwise, a new `KubernetesClient` is created. The client can be configured 
from either
+
+- Using `camel.kubernetes-config.client.` properties (see below for example)
+- Attempt to auto-configure itself by a combination of OS Environment 
variables, reading from `~./kube/config` configuration,
+and service account token file. For more details see the 
https://github.com/fabric8io/kubernetes-client documentation.
+
+You most likely only need to explicit configure the `KubernetesClient` when 
you want to connect
+from a local computer to a remote Kubernetes cluster, where you can specify 
various options,
+such as the masterUrl and oauthToken as shown:
+
+[source,properties]
+----
+camel.kubernetes-config.client.masterUrl = https://127.0.0.1:50179/
+camel.kubernetes-config.client.oauthToken = eyJhbGciOiJSUzI1NiIsImtpZCI...
+----
+
+TIP: The `KubernetesClient` has many options, see the 
https://github.com/fabric8io/kubernetes-client[Kubernetes Client] documentation 
for more information for these options.
+
+If you only use _mount paths_, then it is good practice to disable 
`KubernetesClient` which can be done by setting enabled to false as show:
+
+[source,properties]
+----
+camel.kubernetes-config.client-enabled = false
+----
+
+When running your Camel applications inside an existing Kubernetes cluster, 
then you often
+would not need to explicit configure the `KubernetesClient` and can rely on 
default settings.
+
+TIP: If you use Camel Quarkus, then it is recommended to use their 
https://quarkus.io/guides/kubernetes-config
+which automatic pre-configure the `KubernetesClient` which Camel then will 
reuse.
+
+=== Using configmap with Kubernetes
+
+Given a configmap named `myconfig` in Kubernetes that has two entries:
+
+[source,properties]
+----
+drink = beer
+first = Carlsberg
+----
+
+Then these values can be used in your Camel routes such as:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+  .log("What {{configmap:myconfig/drink}} do you want?")
+  .log("I want {{configmap:myconfig/first}}");
+----
+
+XML::
++
+[source,xml]
+----
+  <route>
+    <from uri="direct:start"/>
+    <log message="What {{configmap:myconfig/drink}} do you want?"/>
+    <log message="I want {{configmap:myconfig/first}}"/>
+  </route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - log:
+            message: "What {{configmap:myconfig/drink}} do you want?"
+        - log:
+            message: "I want {{configmap:myconfig/first}}"
+----
+====
+
+You can also provide a default value in case a key does not exist, such as 
`Heiniken` being the default value:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+  .log("What {{configmap:myconfig/drink}} do you want?")
+  .log("I want {{configmap:myconfig/second:Heineken}}");
+----
+
+XML::
++
+[source,xml]
+----
+  <route>
+    <from uri="direct:start"/>
+    <log message="What {{configmap:myconfig/drink}} do you want?"/>
+    <log message="I want {{configmap:myconfig/second:Heineken}}"/>
+  </route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - log:
+            message: "What {{configmap:myconfig/drink}} do you want?"
+        - log:
+            message: "I want {{configmap:myconfig/second:Heineken}}"
+----
+====
+
+=== Using secrets with Kubernetes
+
+Camel reads ConfigMaps from the Kubernetes API Server. And when RBAC is 
enabled on the cluster,
+the ServiceAccount that is used to run the application needs to have the 
proper permissions for such access.
+
+A secret named `mydb` could contain username and passwords to connect to a 
database such as:
+
+[source,properties]
+----
+myhost = killroy
+myport = 5555
+myuser = scott
+mypass = tiger
+----
+
+This can be used in Camel with for example the Postgres Sink Kamelet:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+String sink =
+"""
+ kamelet:postgresql-sink?serverName={{secret:mydb/myhost}}?
+ &serverPort={{secret:mydb/myport}}
+ &username={{secret:mydb/myuser}}
+ &password={{secret:mydb/mypass}}
+ &databaseName=cities
+ &query=INSERT INTO accounts (username,city) VALUES (:#username,:#city)
+""";
+
+from("direct:rome")
+  .setBody(constant("{ \"username\":\"oscerd\", \"city\":\"Rome\"}"))
+  .to(sink);
+----
+
+XML::
++
+[source,xml]
+----
+  <route>
+    <from uri="direct:rome"/>
+    <setBody>
+      <constant>{ "username":"oscerd", "city":"Rome"}</constant>
+    </setBody>
+    <to uri="kamelet:postgresql-sink?serverName={{secret:mydb/myhost}}
+             &amp;serverPort={{secret:mydb/myport}}
+             &amp;username={{secret:mydb/myuser}}
+             &amp;password={{secret:mydb/mypass}}
+             &amp;databaseName=cities
+             &amp;query=INSERT INTO accounts (username,city) VALUES 
(:#username,:#city)"/>
+  </route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct
+      parameters:
+        name: rome
+      steps:
+        - setBody:
+            expression:
+              constant:
+                expression: "{ \"username\":\"oscerd\", \"city\":\"Rome\"}"
+        - to:
+            uri: kamelet
+            parameters:
+              templateId: postgresql-sink
+              serverName: "{{secret:mydb/myhost}}"
+              serverPort: "{{secret:mydb/myport}}"
+              username: "{{secret:mydb/myuser}}"
+              password: "{{secret:mydb/mypass}}"
+              databaseName: 'cities'
+              query: "INSERT INTO accounts (username,city) VALUES 
(:#username,:#city)"
+----
+====
+
+The postgres-sink Kamelet can also be configured in `application.properties` 
which reduces the configuration
+in the route above:
+
+[source,properties]
+----
+camel.component.kamelet.postgresql-sink.databaseName={{secret:mydb/myhost}}
+camel.component.kamelet.postgresql-sink.serverPort={{secret:mydb/myport}}
+camel.component.kamelet.postgresql-sink.username={{secret:mydb/myuser}}
+camel.component.kamelet.postgresql-sink.password={{secret:mydb/mypass}}
+----
+
+Which reduces the route to:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:rome")
+  .setBody(constant("{ \"username\":\"oscerd\", \"city\":\"Rome\"}"))
+  .to("kamelet:postgresql-sink?databaseName=cities&query=INSERT INTO accounts 
(username,city) VALUES (:#username,:#city)");
+----
+
+XML::
++
+[source,xml]
+----
+  <route>
+    <from uri="direct:rome"/>
+    <setBody>
+      <constant>{ "username":"oscerd", "city":"Rome"}</constant>
+    </setBody>
+    <to uri="kamelet:postgresql-sink?databaseName=cities
+             &amp;query=INSERT INTO accounts (username,city) VALUES 
(:#username,:#city)"/>
+  </route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:rome
+      steps:
+        - setBody:
+            expression:
+              constant:
+                expression: "{ \"username\":\"oscerd\", \"city\":\"Rome\"}"
+        - to:
+            uri: kamelet
+            parameters:
+              templateId: postgresql-sink
+              databaseName: cities
+              query: "INSERT INTO accounts (username,city) VALUES 
(:#username,:#city)"
+----
+====
+
+=== Using configmap or secrets in local-mode
+
+During development, you may want to run in _local mode_ where you do not need 
acces to a Kubernetes cluster, to lookup the configmap.
+In the local mode, then Camel will lookup the configmap _keys_ from local 
properties, eg:
+
+For example the example above with the Postgres kamelet, that was configured 
using a secret:
+
+[source,properties]
+----
+camel.component.kamelet.postgresql-sink.databaseName={{secret:mydb/myhost}}
+camel.component.kamelet.postgresql-sink.serverPort={{secret:mydb/myport}}
+camel.component.kamelet.postgresql-sink.username={{secret:mydb/myuser}}
+camel.component.kamelet.postgresql-sink.password={{secret:mydb/mypass}}
+----
+
+Now suppose we have a local Postgres database we want to use, then we can turn 
on _local mode_
+and specify the credentials in the same properties file:
+
+[source,properties]
+----
+camel.kubernetes-config.local-mode = true
+mydb/myhost=localhost
+mydb/myport=1234
+mydb/myuser=scott
+mydb/mypass=tiger
+----
+
+NOTE: Notice how the key is prefixed with the name of the secret and a slash, 
eg `name/key`. This makes it easy to copy/paste
+from the actual use of the configmap/secret and into the 
`application.properties` file.
+
+
+== Using custom property placeholder functions
+
+The xref:components::properties-component.adoc[Properties] component allow to 
plugin 3rd party functions which can be used during parsing of the property 
placeholders.
+These functions are then able to do custom logic to resolve the placeholders, 
such as looking up in databases, do custom computations, or whatnot.
+The name of the function becomes the prefix used in the placeholder.
+
+This is best illustrated in the example route below, where we use `beer` as 
the prefix:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+from("direct:start")
+  .to("{{beer:FOO}}")
+  .to("{{beer:BAR}}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+    <from uri="direct:start"/>
+    <to uri="{{beer:FOO}}"/>
+    <to uri="{{beer:BAR}}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start
+      steps:
+        - to:
+            uri: "{{beer:FOO}}"
+        - to:
+            uri: "{{beer:BAR}}"
+----
+====
+
+The implementation of the function is only two methods as shown below:
+
+[source,java]
+----
[email protected]("beer")
+public class MyBeerFunction implements PropertiesFunction {
+
+    @Override
+    public String getName() {
+        return "beer";
+    }
+
+    @Override
+    public String apply(String remainder) {
+        return "mock:" + remainder.toLowerCase();
+    }
+}
+----
+
+The function must implement the `org.apache.camel.spi.PropertiesFunction` 
interface.
+The method `getName` is the name of the function (beer).
+And the `apply` method is where we implement the custom logic to do.
+As the sample code is from a unit test, it just returns a value to refer to a 
mock endpoint.
+
+You also need to have `camel-component-maven-plugin` Maven plugin as part of 
building the component will
+then ensure that this custom properties function has necessary source code 
generated that makes Camel
+able to automatically discover the function.
+
+NOTE: If the custom properties function need logic to startup and shutdown, 
then the function can extend `ServiceSupport`
+and have this logic in `doStart` and `doStop` methods.
+
+TIP: For an example see the `camel-base64` component.
+
+
diff --git 
a/docs/user-manual/modules/ROOT/pages/route-template-bean-binding.adoc 
b/docs/user-manual/modules/ROOT/pages/route-template-bean-binding.adoc
new file mode 100644
index 000000000000..bee62f0330af
--- /dev/null
+++ b/docs/user-manual/modules/ROOT/pages/route-template-bean-binding.adoc
@@ -0,0 +1,641 @@
+= Route Template Bean Binding
+:tabs-sync-option:
+
+xref:route-template.adoc[Back to Route Templates]
+
+The route template allows binding beans that are locally scoped and only used 
as part of creating routes from the template.
+This allows using the same template to create multiple routes, where beans are 
local (private) for each created route.
+
+For example, given the following route template where we use `templateBean` to 
set up the local bean as shown:
+
+._Java-only: templateBean with lambda supplier_
+[source,java]
+----
+routeTemplate("s3template")
+    .templateParameter("region")
+    .templateParameter("bucket")
+    .templateBean("myClient", S3Client.class, rtc ->
+            S3Client.builder().region(rtc.getProperty("region", 
Region.class)).build();
+    )
+    .from("direct:s3-store")
+     // must refer to the bean with {{myClient}}
+    .to("aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}")
+----
+
+The template has two parameters to specify the AWS region and the S3 bucket. 
To connect to S3
+then a `software.amazon.awssdk.services.s3.S3Client` bean is necessary.
+
+To create this bean, we specify this with the `templateBean` DSL where we 
specify the bean id as `myClient`.
+The type of the bean can be specified (`S3Client.class`), however, it is 
optional, and
+can be used if you need to let beans be discovered by type and not by name.
+
+This ensures that the code creating the bean is executed later (when Camel is 
creating a route from the template),
+then the code must be specified as a _supplier_. Because we want during 
creation of the bean access to template parameters,
+we use a Camel `BeanSupplier` which gives access to `RouteTemplateContext` 
that is the `_rtc_` variable in the code above.
+
+IMPORTANT: The local bean with id `myClient` *must* be referred to using 
Camel's property placeholder syntax, eg `{\{myClient}}`
+in the route template, as shown above with the _to_ endpoint. This is because 
the local
+bean must be made unique and Camel will internally re-assign the bean id to 
use a unique id instead of `myClient`. And this is done with the help
+of the property placeholder functionality.
+
+If multiple routes are created from this template, then each of the created 
routes have their own
+`S3Client` bean created.
+
+== Binding beans to route templates from template builder
+
+The `TemplatedRouteBuilder` also allows to bind local beans (which allows 
specifying those beans) when
+creating routes from existing templates.
+
+Suppose the route template below is defined in XML:
+
+._XML-only: route template without bean binding_
+[source,xml]
+----
+  <routeTemplate id="s3template">
+    <templateParameter name="region"/>
+    <templateParameter name="bucket"/>
+    <route>
+      <from uri="direct:s3-store"/>
+      <to uri="aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}"/>
+    </route>
+  </routeTemplate>
+----
+
+The template has no bean bindings for `#{\{myClient}}` which would be required 
for creating the template.
+
+When creating routes form the template via `TemplatedRouteBuilder` then you 
can provide the bean binding
+if you desire the bean to be locally scoped (not shared with others):
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+TemplatedRouteBuilder.builder(context, "s3template")
+    .parameter("region", "US-EAST-1")
+    .parameter("bucket", "myBucket")
+    .bean("myClient", S3Client.class,
+                S3Client.builder()
+                    .region(rtc.getProperty("region", Region.class))
+                    .build())
+    .routeId("mys3route")
+    .add();
+----
++
+As you can see the binding is similar to when using `templateBean` directly in 
the route template.
+
+Java DSL::
++
+[source,java]
+----
+templatedRoute("s3template")
+        .parameter("region", "US-EAST-1")
+        .parameter("bucket", "myBucket")
+        .bean("myClient", S3Client.class,
+                rtc -> S3Client.builder() // <1>
+                    .region(rtc.getProperty("region", Region.class))
+                    .build())
+        .routeId("mys3route");
+----
+<1> Note that the third parameter of the `bean` method is not directly the 
bean but rather a factory method that will be used to create the bean, here we 
use a lambda expression as factory method.
+
+XML::
++
+[source,xml]
+----
+  <templatedRoute routeTemplateRef="s3template" routeId="mys3route">
+    <parameter name="region" value="US-EAST-1"/>
+    <parameter name="bucket" value="myBucket"/>
+    <bean name="myClient" type="software.amazon.awssdk.services.s3.S3Client"
+          scriptLanguage="groovy"> <!--1-->
+        <script>
+            import software.amazon.awssdk.services.s3.S3Client
+            S3Client.builder()
+                .region(rtc.getProperty("region", Region.class))
+                .build()
+        </script>
+    </bean>
+  </templatedRoute>
+----
+<1> For non-Java DSL, in case of a complex bean factory, you can still rely on 
a language like `groovy` to define your bean factory inside a `script` element.
+
+YAML::
++
+[source,yaml]
+----
+- templatedRoute:
+    routeTemplateRef: "s3template"
+    routeId: "mys3route"
+    parameters:
+      - name: "region"
+        value: "US-EAST-1"
+      - name: "bucket"
+        value: "myBucket"
+    beans:
+      - name: "myClient"
+        type: "software.amazon.awssdk.services.s3.S3Client"
+        scriptLanguage: "groovy"
+        script: | # <1>
+            import software.amazon.awssdk.services.s3.S3Client
+            S3Client.builder()
+                .region(rtc.getProperty("region", Region.class))
+                .build()
+----
+<1> For non-Java DSL, in case of a complex bean factory, you can still rely on 
a language like `groovy` to define your bean factory as value of the `script` 
key.
+====
+
+Instead of binding the beans from the template builder, you could also create 
the bean outside the template,
+and bind it by reference.
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+final S3Client myClient = S3Client.builder().region(Region.US_EAST_1).build();
+
+TemplatedRouteBuilder.builder(context, "s3template")
+    .parameter("region", Region.US_EAST_1)
+    .parameter("bucket", "myBucket")
+    .bean("myClient", myClient)
+    .routeId("mys3route")
+    .add();
+----
+
+Java DSL::
++
+[source,java]
+----
+final S3Client myClient = S3Client.builder().region(Region.US_EAST_1).build();
+
+templatedRoute("s3template")
+        .parameter("region", "US-EAST-1")
+        .parameter("bucket", "myBucket")
+        .bean("myClient", S3Client.class, rtc -> myClient)
+        .routeId("mys3route");
+----
+====
+
+NOTE: You should prefer to create the local beans directly from within the 
template (if possible) because this
+ensures the route template has this out of the box. Otherwise, the bean must 
be created or provided every time
+a new route is created from the route template. However, the latter gives 
freedom to create the bean in any other custom way.
+
+
+== Binding beans to route templates using bean types
+
+You can create a local bean by referring to a fully qualified class name which 
Camel will use to create
+a new local bean instance. When using this, the created bean is created via 
default constructor of the class.
+
+The bean instance can be configured with properties via getter/setter style.
+The previous example with creating the AWS S3Client would not support this 
kind as this uses _fluent builder_ pattern (not getter/setter).
+
+TIP: In *Camel 4.6* onwards, you can also use constructor arguments for beans
+
+So suppose we have a class as follows:
+
+._Java-only: bean class with getter/setter properties_
+[source,java]
+----
+public class MyBar {
+    private String name;
+    private String address;
+
+    // getter/setter omitted
+
+    public String location() {
+        return "The bar " + name + " is located at " + address;
+    }
+}
+----
+
+Then we can use the `MyBar` class as a local bean in a route template as 
follows:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+routeTemplate("barTemplate")
+    .templateParameter("bar")
+    .templateParameter("street")
+    .templateBean("myBar")
+        .typeClass("com.foo.MyBar")
+        .property("name", "{{bar}}")
+        .property("address", "{{street}}")
+    .end()
+    .from("direct:going-out")
+        .to("bean:{{myBar}}");
+----
++
+With Java DSL, you can also refer to the bean class using type safe way in 
`typeClass` by referring to the `.class` as follows:
++
+[source,java]
+----
+routeTemplate("barTemplate")
+    .templateParameter("bar")
+    .templateParameter("street")
+    .templateBean("myBar")
+        .typeClass(MyBar.class)
+        .property("name", "{{bar}}")
+        .property("address", "{{street}}")
+    .end()
+    .from("direct:going-out")
+        .to("bean:{{myBar}}");
+----
+
+XML::
++
+In XML, we specify the class FQN name using `#class:` syntax as shown:
++
+[source,xml]
+----
+<routeTemplate id="myBar">
+    <templateParameter name="bar"/>
+    <templateParameter name="street"/>
+    <templateBean name="myBean" type="#class:com.foo.MyBar">
+        <properties>
+            <property key="name" value="{{bar}}"/>
+            <property key="address" value="{{street}}"/>
+        </properties>
+    </templateBean>
+    <route>
+        <from uri="direct:going-out"/>
+        <to uri="bean:{{myBar}}"/>
+    </route>
+</routeTemplate>
+----
+
+YAML::
++
+In YAML, we specify the class FQN name using `#class:` syntax as shown:
++
+[source,yaml]
+----
+- routeTemplate:
+    id: "myBar"
+    parameters:
+      - name: "bar"
+      - name: "street"
+    beans:
+      - name: "myBean"
+        type: "#class:com.foo.MyBar"
+        properties:
+          name: "{{bar}}"
+          address: "{{street}}"
+    from:
+      uri: direct:going-out
+      steps:
+        - to:
+            uri: "bean:{{myBar}}"
+----
+====
+
+
+== Binding beans to route templates using scripting languages (advanced)
+
+You can use scripting languages like Groovy, Java, to create the bean.
+This allows defining route templates with the scripting language supported by 
Camel such as Groovy.
+
+For example, creating the AWS S3 client can be done as shown in Java (with 
inlined Groovy code):
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+routeTemplate("s3template")
+    .templateParameter("region")
+    .templateParameter("bucket")
+    .templateBean("myClient", "groovy",
+            "software.amazon.awssdk.services.s3.S3Client.S3Client.builder()
+            .region(rtc.getProperty("region", Region.class))
+            .build()"
+    )
+    .from("direct:s3-store")
+     // must refer to the bean with {{myClient}}
+    .to("aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}")
+----
+
+XML::
++
+Notice how the Groovy code can be inlined directly in the route template in 
XML also.
++
+[source,xml]
+----
+  <routeTemplate id="s3template">
+    <templateParameter name="region"/>
+    <templateParameter name="bucket"/>
+    <templateBean name="myClient" scriptLanguage="groovy">
+        <script>
+            import software.amazon.awssdk.services.s3.S3Client
+            S3Client.builder()
+                .region(rtc.getProperty("region", Region.class))
+                .build()
+        </script>
+    </templateBean>
+    <route>
+      <from uri="direct:s3-store"/>
+      <to uri="aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}"/>
+    </route>
+  </routeTemplate>
+----
+
+YAML::
++
+Notice how the Groovy code can be inlined directly in the route template in 
DSL also.
++
+[source,yaml]
+----
+- routeTemplate:
+    id: "s3template"
+    parameters:
+      - name: "region"
+      - name: "bucket"
+    beans:
+      - name: "myClient"
+        scriptLanguage: "groovy"
+        script: |
+            import software.amazon.awssdk.services.s3.S3Client
+            S3Client.builder()
+                .region(rtc.getProperty("region", Region.class))
+                .build()
+    from:
+      uri: direct:s3-store
+      steps:
+        - to:
+            uri: "aws2-s3:{{bucket}}"
+            parameters:
+              amazonS3Client: "#{{myClient}}"
+----
+====
+
+The groovy code can be externalized into a file on the classpath or file 
system, by using `resource:` as prefix, such as:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+routeTemplate("s3template")
+    .templateParameter("region")
+    .templateParameter("bucket")
+    .templateBean("myClient", "groovy", "resource:classpath:s3bean.groovy")
+    .from("direct:s3-store")
+     // must refer to the bean with {{myClient}}
+    .to("aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}")
+----
+
+XML::
++
+Notice how we can tell Camel the type of the bean is 
`software.amazon.awssdk.services.s3.S3Client` which allows
+Camel to better understand, and also makes the bean able for autowiring and 
binding via type. The `type` is optional
+and can be omitted. For example in this example as we inject the bean via its 
bean id `myClient`.
++
+[source,xml]
+----
+  <routeTemplate id="s3template">
+    <templateParameter name="region"/>
+    <templateParameter name="bucket"/>
+    <templateBean name="myClient" scriptLanguage="groovy"
+                  type="software.amazon.awssdk.services.s3.S3Client">
+        <script>resource:classpath:s3bean.groovy</script>
+    </templateBean>
+    <route>
+      <from uri="direct:s3-store"/>
+      <to uri="aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}"/>
+    </route>
+  </routeTemplate>
+----
+
+YAML::
++
+Notice how we can tell Camel the type of the bean is 
`software.amazon.awssdk.services.s3.S3Client` which allows
+Camel to better understand, and also makes the bean able for autowiring and 
binding via type. The `type` is optional
+and can be omitted. For example in this example as we inject the bean via its 
bean id `myClient`.
++
+[source,yaml]
+----
+- routeTemplate:
+    id: "s3template"
+    parameters:
+      - name: "region"
+      - name: "bucket"
+    beans:
+      - name: "myClient"
+        scriptLanguage: "groovy"
+        type: "software.amazon.awssdk.services.s3.S3Client"
+        script: "resource:classpath:s3bean.groovy"
+    from:
+      uri: direct:s3-store
+      steps:
+        - to:
+            uri: "aws2-s3:{{bucket}}"
+            parameters:
+              amazonS3Client: "#{{myClient}}"
+----
+====
+
+Then create the file `s3bean.groovy` in the classpath root:
+
+.s3bean.groovy
+[source,groovy]
+----
+import software.amazon.awssdk.services.s3.S3Client
+
+S3Client.builder()
+    .region(rtc.getProperty("region", Region.class))
+    .build()
+----
+
+The languages supported you can specify as `scriptLanguage` are:
+
+[width="100%",cols="2s,8",options="header"]
+|===
+| Type | Description
+| bean | Calling a method on a Java class to create the bean.
+| groovy | Using a groovy script to create the bean.
+| java | Java code which is runtime compiled (using jOOR library) to create 
the bean.
+| mvel | To use a MVEL template script to create the bean.
+| ognl | To use OGNL template script to create the bean.
+| _name_ | To use a third-party language by the given `_name_` to create the 
bean.
+|===
+
+Camel will bind `RouteTemplateContext` as the root object with name `rtc` when 
evaluating the script.
+This means you can get access to all the information from 
`RouteTemplateContext` and `CamelContext` via `rtc`.
+
+This is what we have done in the scripts in the previous examples where we get 
hold of a template parameter with:
+
+[source,groovy]
+----
+rtc.getProperty('region', String.class)
+----
+
+To get access to `CamelContext` you can do:
+
+[source,groovy]
+----
+var cn = rtc.getCamelContext().getName()
+----
+
+The most powerful languages to use are groovy and java. The other languages 
are limited in flexibility
+as they are not complete programming languages, but are more suited for 
templating needs.
+
+It is recommended to either use groovy or java, if creating the local bean 
requires coding,
+and the route templates are not defined using Java code.
+
+The bean language can be used when creating the local bean from an existing 
Java method (static or not-static method),
+and the route templates are not defined using Java code.
+
+For example suppose there is a class named `com.foo.MyAwsHelper` that has a 
method called `createS3Client`
+then you can call this method from the route template as shown in the 
following:
+
+[tabs]
+====
+
+Java::
++
+[source,java]
+----
+routeTemplate("s3template")
+    .templateParameter("region")
+    .templateParameter("bucket")
+    .templateBean("myClient", "beam", 
"com.foo.MyAwsHelper?method=createS3Client")
+    .from("direct:s3-store")
+     // must refer to the bean with {{myClient}}
+    .to("aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}")
+----
+
+XML::
++
+[source,xml]
+----
+  <routeTemplate id="s3template">
+    <templateParameter name="region"/>
+    <templateParameter name="bucket"/>
+    <templateBean name="myClient" type="bean">
+        <script>com.foo.MyAwsHelper?method=createS3Client</script>
+    </templateBean>
+    <route>
+      <from uri="direct:s3-store"/>
+      <to uri="aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}"/>
+    </route>
+  </routeTemplate>
+----
+
+YAML::
++
+[source,yaml]
+----
+- routeTemplate:
+    id: "s3template"
+    parameters:
+      - name: "region"
+      - name: "bucket"
+    beans:
+      - name: "myClient"
+        scriptLanguage: "bean"
+        script: "com.foo.MyAwsHelper?method=createS3Client"
+    from:
+      uri: direct:s3-store
+      steps:
+        - to:
+            uri: "aws2-s3:{{bucket}}"
+            parameters:
+              amazonS3Client: "#{{myClient}}"
+----
+====
+
+The method signature of `createS3Client` method **MUST** then have one 
parameter for the `RouteTemplateContext` as shown:
+
+._Java-only: bean factory method signature_
+[source,java]
+----
+public static S3Client createS3Client(RouteTemplateContext rtc) {
+    return S3Client.builder()
+        .region(rtc.getProperty("region", Region.class))
+        .build();
+}
+----
+
+If you are using pure Java code (both template and creating local bean),
+then you can create the local bean using Java lambda style as previously 
documented.
+
+
+== Configuring the type of the created bean
+
+The `type` must be set to define what FQN class the created bean.
+
+In the following route template we want to tell Camel that the bean is a 
`software.amazon.awssdk.services.s3.S3Client` type.
+
+
+[tabs]
+====
+
+Java::
++
+In Java DSL you can refer to the type via its class (ie `S3Client.java` which 
is a type safe way:
++
+[source,java]
+----
+routeTemplate("s3template")
+    .templateParameter("region")
+    .templateParameter("bucket")
+    .templateBean("myClient", S3Client.class, "bean", 
"com.foo.MyAwsHelper?method=createS3Client")
+    .from("direct:s3-store")
+     // must refer to the bean with {{myClient}}
+    .to("aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}")
+----
+
+XML::
++
+[source,xml]
+----
+  <routeTemplate id="s3template">
+    <templateParameter name="region"/>
+    <templateParameter name="bucket"/>
+    <templateBean name="myClient" scriptLanguage="bean"
+                  type="software.amazon.awssdk.services.s3.S3Client">
+        <script>com.foo.MyAwsHelper?method=createS3Client</script>
+    </templateBean>
+    <route>
+      <from uri="direct:s3-store"/>
+      <to uri="aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}"/>
+    </route>
+  </routeTemplate>
+----
+
+YAML::
++
+[source,yaml]
+----
+- routeTemplate:
+    id: "s3template"
+    parameters:
+      - name: "region"
+      - name: "bucket"
+    beans:
+      - name: "myClient"
+        scriptLanguage: "bean"
+        type: "software.amazon.awssdk.services.s3.S3Client"
+        script: "com.foo.MyAwsHelper?method=createS3Client"
+    from:
+      uri: direct:s3-store
+      steps:
+        - to:
+            uri: "aws2-s3:{{bucket}}"
+            parameters:
+              amazonS3Client: "#{{myClient}}"
+----
+====
+
+
diff --git a/docs/user-manual/modules/ROOT/pages/route-template.adoc 
b/docs/user-manual/modules/ROOT/pages/route-template.adoc
index 8a6434324929..e06ab30d8d51 100644
--- a/docs/user-manual/modules/ROOT/pages/route-template.adoc
+++ b/docs/user-manual/modules/ROOT/pages/route-template.adoc
@@ -643,643 +643,12 @@ Then we can create a 2nd route with a different 
_prefixId`:
 ----
 ====
 
-== Binding beans to route template (advanced)
+== Binding Beans to Route Templates
 
-The route template allows binding beans that are locally scoped and only used 
as part of creating routes from the template.
-This allows using the same template to create multiple routes, where beans are 
local (private) for each created route.
-
-For example, given the following route template where we use `templateBean` to 
set up the local bean as shown:
-
-._Java-only: templateBean with lambda supplier_
-[source,java]
-----
-routeTemplate("s3template")
-    .templateParameter("region")
-    .templateParameter("bucket")
-    .templateBean("myClient", S3Client.class, rtc ->
-            S3Client.builder().region(rtc.getProperty("region", 
Region.class)).build();
-    )
-    .from("direct:s3-store")
-     // must refer to the bean with {{myClient}}
-    .to("aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}")
-----
-
-The template has two parameters to specify the AWS region and the S3 bucket. 
To connect to S3
-then a `software.amazon.awssdk.services.s3.S3Client` bean is necessary.
-
-To create this bean, we specify this with the `templateBean` DSL where we 
specify the bean id as `myClient`.
-The type of the bean can be specified (`S3Client.class`), however, it is 
optional, and
-can be used if you need to let beans be discovered by type and not by name.
-
-This ensures that the code creating the bean is executed later (when Camel is 
creating a route from the template),
-then the code must be specified as a _supplier_. Because we want during 
creation of the bean access to template parameters,
-we use a Camel `BeanSupplier` which gives access to `RouteTemplateContext` 
that is the `_rtc_` variable in the code above.
-
-IMPORTANT: The local bean with id `myClient` *must* be referred to using 
Camel's property placeholder syntax, eg `{\{myClient}}`
-in the route template, as shown above with the _to_ endpoint. This is because 
the local
-bean must be made unique and Camel will internally re-assign the bean id to 
use a unique id instead of `myClient`. And this is done with the help
-of the property placeholder functionality.
-
-If multiple routes are created from this template, then each of the created 
routes have their own
-`S3Client` bean created.
-
-=== Binding beans to route templates from template builder
-
-The `TemplatedRouteBuilder` also allows to bind local beans (which allows 
specifying those beans) when
-creating routes from existing templates.
-
-Suppose the route template below is defined in XML:
-
-._XML-only: route template without bean binding_
-[source,xml]
-----
-  <routeTemplate id="s3template">
-    <templateParameter name="region"/>
-    <templateParameter name="bucket"/>
-    <route>
-      <from uri="direct:s3-store"/>
-      <to uri="aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}"/>
-    </route>
-  </routeTemplate>
-----
-
-The template has no bean bindings for `#{\{myClient}}` which would be required 
for creating the template.
-
-When creating routes form the template via `TemplatedRouteBuilder` then you 
can provide the bean binding
-if you desire the bean to be locally scoped (not shared with others):
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-TemplatedRouteBuilder.builder(context, "s3template")
-    .parameter("region", "US-EAST-1")
-    .parameter("bucket", "myBucket")
-    .bean("myClient", S3Client.class,
-                S3Client.builder()
-                    .region(rtc.getProperty("region", Region.class))
-                    .build())
-    .routeId("mys3route")
-    .add();
-----
-+
-As you can see the binding is similar to when using `templateBean` directly in 
the route template.
-
-Java DSL::
-+
-[source,java]
-----
-templatedRoute("s3template")
-        .parameter("region", "US-EAST-1")
-        .parameter("bucket", "myBucket")
-        .bean("myClient", S3Client.class,
-                rtc -> S3Client.builder() // <1>
-                    .region(rtc.getProperty("region", Region.class))
-                    .build())
-        .routeId("mys3route");
-----
-<1> Note that the third parameter of the `bean` method is not directly the 
bean but rather a factory method that will be used to create the bean, here we 
use a lambda expression as factory method.
-
-XML::
-+
-[source,xml]
-----
-  <templatedRoute routeTemplateRef="s3template" routeId="mys3route">
-    <parameter name="region" value="US-EAST-1"/>
-    <parameter name="bucket" value="myBucket"/>
-    <bean name="myClient" type="software.amazon.awssdk.services.s3.S3Client"
-          scriptLanguage="groovy"> <!--1-->
-        <script>
-            import software.amazon.awssdk.services.s3.S3Client
-            S3Client.builder()
-                .region(rtc.getProperty("region", Region.class))
-                .build()
-        </script>
-    </bean>
-  </templatedRoute>
-----
-<1> For non-Java DSL, in case of a complex bean factory, you can still rely on 
a language like `groovy` to define your bean factory inside a `script` element.
-
-YAML::
-+
-[source,yaml]
-----
-- templatedRoute:
-    routeTemplateRef: "s3template"
-    routeId: "mys3route"
-    parameters:
-      - name: "region"
-        value: "US-EAST-1"
-      - name: "bucket"
-        value: "myBucket"
-    beans:
-      - name: "myClient"
-        type: "software.amazon.awssdk.services.s3.S3Client"
-        scriptLanguage: "groovy"
-        script: | # <1>
-            import software.amazon.awssdk.services.s3.S3Client
-            S3Client.builder()
-                .region(rtc.getProperty("region", Region.class))
-                .build()
-----
-<1> For non-Java DSL, in case of a complex bean factory, you can still rely on 
a language like `groovy` to define your bean factory as value of the `script` 
key.
-====
-
-Instead of binding the beans from the template builder, you could also create 
the bean outside the template,
-and bind it by reference.
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-final S3Client myClient = S3Client.builder().region(Region.US_EAST_1).build();
-
-TemplatedRouteBuilder.builder(context, "s3template")
-    .parameter("region", Region.US_EAST_1)
-    .parameter("bucket", "myBucket")
-    .bean("myClient", myClient)
-    .routeId("mys3route")
-    .add();
-----
-
-Java DSL::
-+
-[source,java]
-----
-final S3Client myClient = S3Client.builder().region(Region.US_EAST_1).build();
-
-templatedRoute("s3template")
-        .parameter("region", "US-EAST-1")
-        .parameter("bucket", "myBucket")
-        .bean("myClient", S3Client.class, rtc -> myClient)
-        .routeId("mys3route");
-----
-====
-
-NOTE: You should prefer to create the local beans directly from within the 
template (if possible) because this
-ensures the route template has this out of the box. Otherwise, the bean must 
be created or provided every time
-a new route is created from the route template. However, the latter gives 
freedom to create the bean in any other custom way.
-
-
-=== Binding beans to route templates using bean types
-
-You can create a local bean by referring to a fully qualified class name which 
Camel will use to create
-a new local bean instance. When using this, the created bean is created via 
default constructor of the class.
-
-The bean instance can be configured with properties via getter/setter style.
-The previous example with creating the AWS S3Client would not support this 
kind as this uses _fluent builder_ pattern (not getter/setter).
-
-TIP: In *Camel 4.6* onwards, you can also use constructor arguments for beans
-
-So suppose we have a class as follows:
-
-._Java-only: bean class with getter/setter properties_
-[source,java]
-----
-public class MyBar {
-    private String name;
-    private String address;
-
-    // getter/setter omitted
-
-    public String location() {
-        return "The bar " + name + " is located at " + address;
-    }
-}
-----
-
-Then we can use the `MyBar` class as a local bean in a route template as 
follows:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-routeTemplate("barTemplate")
-    .templateParameter("bar")
-    .templateParameter("street")
-    .templateBean("myBar")
-        .typeClass("com.foo.MyBar")
-        .property("name", "{{bar}}")
-        .property("address", "{{street}}")
-    .end()
-    .from("direct:going-out")
-        .to("bean:{{myBar}}");
-----
-+
-With Java DSL, you can also refer to the bean class using type safe way in 
`typeClass` by referring to the `.class` as follows:
-+
-[source,java]
-----
-routeTemplate("barTemplate")
-    .templateParameter("bar")
-    .templateParameter("street")
-    .templateBean("myBar")
-        .typeClass(MyBar.class)
-        .property("name", "{{bar}}")
-        .property("address", "{{street}}")
-    .end()
-    .from("direct:going-out")
-        .to("bean:{{myBar}}");
-----
-
-XML::
-+
-In XML, we specify the class FQN name using `#class:` syntax as shown:
-+
-[source,xml]
-----
-<routeTemplate id="myBar">
-    <templateParameter name="bar"/>
-    <templateParameter name="street"/>
-    <templateBean name="myBean" type="#class:com.foo.MyBar">
-        <properties>
-            <property key="name" value="{{bar}}"/>
-            <property key="address" value="{{street}}"/>
-        </properties>
-    </templateBean>
-    <route>
-        <from uri="direct:going-out"/>
-        <to uri="bean:{{myBar}}"/>
-    </route>
-</routeTemplate>
-----
-
-YAML::
-+
-In YAML, we specify the class FQN name using `#class:` syntax as shown:
-+
-[source,yaml]
-----
-- routeTemplate:
-    id: "myBar"
-    parameters:
-      - name: "bar"
-      - name: "street"
-    beans:
-      - name: "myBean"
-        type: "#class:com.foo.MyBar"
-        properties:
-          name: "{{bar}}"
-          address: "{{street}}"
-    from:
-      uri: direct:going-out
-      steps:
-        - to:
-            uri: "bean:{{myBar}}"
-----
-====
-
-
-=== Binding beans to route templates using scripting languages (advanced)
-
-You can use scripting languages like Groovy, Java, to create the bean.
-This allows defining route templates with the scripting language supported by 
Camel such as Groovy.
-
-For example, creating the AWS S3 client can be done as shown in Java (with 
inlined Groovy code):
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-routeTemplate("s3template")
-    .templateParameter("region")
-    .templateParameter("bucket")
-    .templateBean("myClient", "groovy",
-            "software.amazon.awssdk.services.s3.S3Client.S3Client.builder()
-            .region(rtc.getProperty("region", Region.class))
-            .build()"
-    )
-    .from("direct:s3-store")
-     // must refer to the bean with {{myClient}}
-    .to("aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}")
-----
-
-XML::
-+
-Notice how the Groovy code can be inlined directly in the route template in 
XML also.
-+
-[source,xml]
-----
-  <routeTemplate id="s3template">
-    <templateParameter name="region"/>
-    <templateParameter name="bucket"/>
-    <templateBean name="myClient" scriptLanguage="groovy">
-        <script>
-            import software.amazon.awssdk.services.s3.S3Client
-            S3Client.builder()
-                .region(rtc.getProperty("region", Region.class))
-                .build()
-        </script>
-    </templateBean>
-    <route>
-      <from uri="direct:s3-store"/>
-      <to uri="aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}"/>
-    </route>
-  </routeTemplate>
-----
-
-YAML::
-+
-Notice how the Groovy code can be inlined directly in the route template in 
DSL also.
-+
-[source,yaml]
-----
-- routeTemplate:
-    id: "s3template"
-    parameters:
-      - name: "region"
-      - name: "bucket"
-    beans:
-      - name: "myClient"
-        scriptLanguage: "groovy"
-        script: |
-            import software.amazon.awssdk.services.s3.S3Client
-            S3Client.builder()
-                .region(rtc.getProperty("region", Region.class))
-                .build()
-    from:
-      uri: direct:s3-store
-      steps:
-        - to:
-            uri: "aws2-s3:{{bucket}}"
-            parameters:
-              amazonS3Client: "#{{myClient}}"
-----
-====
-
-The groovy code can be externalized into a file on the classpath or file 
system, by using `resource:` as prefix, such as:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-routeTemplate("s3template")
-    .templateParameter("region")
-    .templateParameter("bucket")
-    .templateBean("myClient", "groovy", "resource:classpath:s3bean.groovy")
-    .from("direct:s3-store")
-     // must refer to the bean with {{myClient}}
-    .to("aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}")
-----
-
-XML::
-+
-Notice how we can tell Camel the type of the bean is 
`software.amazon.awssdk.services.s3.S3Client` which allows
-Camel to better understand, and also makes the bean able for autowiring and 
binding via type. The `type` is optional
-and can be omitted. For example in this example as we inject the bean via its 
bean id `myClient`.
-+
-[source,xml]
-----
-  <routeTemplate id="s3template">
-    <templateParameter name="region"/>
-    <templateParameter name="bucket"/>
-    <templateBean name="myClient" scriptLanguage="groovy"
-                  type="software.amazon.awssdk.services.s3.S3Client">
-        <script>resource:classpath:s3bean.groovy</script>
-    </templateBean>
-    <route>
-      <from uri="direct:s3-store"/>
-      <to uri="aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}"/>
-    </route>
-  </routeTemplate>
-----
-
-YAML::
-+
-Notice how we can tell Camel the type of the bean is 
`software.amazon.awssdk.services.s3.S3Client` which allows
-Camel to better understand, and also makes the bean able for autowiring and 
binding via type. The `type` is optional
-and can be omitted. For example in this example as we inject the bean via its 
bean id `myClient`.
-+
-[source,yaml]
-----
-- routeTemplate:
-    id: "s3template"
-    parameters:
-      - name: "region"
-      - name: "bucket"
-    beans:
-      - name: "myClient"
-        scriptLanguage: "groovy"
-        type: "software.amazon.awssdk.services.s3.S3Client"
-        script: "resource:classpath:s3bean.groovy"
-    from:
-      uri: direct:s3-store
-      steps:
-        - to:
-            uri: "aws2-s3:{{bucket}}"
-            parameters:
-              amazonS3Client: "#{{myClient}}"
-----
-====
-
-Then create the file `s3bean.groovy` in the classpath root:
-
-.s3bean.groovy
-[source,groovy]
-----
-import software.amazon.awssdk.services.s3.S3Client
-
-S3Client.builder()
-    .region(rtc.getProperty("region", Region.class))
-    .build()
-----
-
-The languages supported you can specify as `scriptLanguage` are:
-
-[width="100%",cols="2s,8",options="header"]
-|===
-| Type | Description
-| bean | Calling a method on a Java class to create the bean.
-| groovy | Using a groovy script to create the bean.
-| java | Java code which is runtime compiled (using jOOR library) to create 
the bean.
-| mvel | To use a MVEL template script to create the bean.
-| ognl | To use OGNL template script to create the bean.
-| _name_ | To use a third-party language by the given `_name_` to create the 
bean.
-|===
-
-Camel will bind `RouteTemplateContext` as the root object with name `rtc` when 
evaluating the script.
-This means you can get access to all the information from 
`RouteTemplateContext` and `CamelContext` via `rtc`.
-
-This is what we have done in the scripts in the previous examples where we get 
hold of a template parameter with:
-
-[source,groovy]
-----
-rtc.getProperty('region', String.class)
-----
-
-To get access to `CamelContext` you can do:
-
-[source,groovy]
-----
-var cn = rtc.getCamelContext().getName()
-----
-
-The most powerful languages to use are groovy and java. The other languages 
are limited in flexibility
-as they are not complete programming languages, but are more suited for 
templating needs.
-
-It is recommended to either use groovy or java, if creating the local bean 
requires coding,
-and the route templates are not defined using Java code.
-
-The bean language can be used when creating the local bean from an existing 
Java method (static or not-static method),
-and the route templates are not defined using Java code.
-
-For example suppose there is a class named `com.foo.MyAwsHelper` that has a 
method called `createS3Client`
-then you can call this method from the route template as shown in the 
following:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-routeTemplate("s3template")
-    .templateParameter("region")
-    .templateParameter("bucket")
-    .templateBean("myClient", "beam", 
"com.foo.MyAwsHelper?method=createS3Client")
-    .from("direct:s3-store")
-     // must refer to the bean with {{myClient}}
-    .to("aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}")
-----
-
-XML::
-+
-[source,xml]
-----
-  <routeTemplate id="s3template">
-    <templateParameter name="region"/>
-    <templateParameter name="bucket"/>
-    <templateBean name="myClient" type="bean">
-        <script>com.foo.MyAwsHelper?method=createS3Client</script>
-    </templateBean>
-    <route>
-      <from uri="direct:s3-store"/>
-      <to uri="aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}"/>
-    </route>
-  </routeTemplate>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- routeTemplate:
-    id: "s3template"
-    parameters:
-      - name: "region"
-      - name: "bucket"
-    beans:
-      - name: "myClient"
-        scriptLanguage: "bean"
-        script: "com.foo.MyAwsHelper?method=createS3Client"
-    from:
-      uri: direct:s3-store
-      steps:
-        - to:
-            uri: "aws2-s3:{{bucket}}"
-            parameters:
-              amazonS3Client: "#{{myClient}}"
-----
-====
-
-The method signature of `createS3Client` method **MUST** then have one 
parameter for the `RouteTemplateContext` as shown:
-
-._Java-only: bean factory method signature_
-[source,java]
-----
-public static S3Client createS3Client(RouteTemplateContext rtc) {
-    return S3Client.builder()
-        .region(rtc.getProperty("region", Region.class))
-        .build();
-}
-----
-
-If you are using pure Java code (both template and creating local bean),
-then you can create the local bean using Java lambda style as previously 
documented.
-
-
-==== Configuring the type of the created bean
-
-The `type` must be set to define what FQN class the created bean.
-
-In the following route template we want to tell Camel that the bean is a 
`software.amazon.awssdk.services.s3.S3Client` type.
-
-
-[tabs]
-====
-
-Java::
-+
-In Java DSL you can refer to the type via its class (ie `S3Client.java` which 
is a type safe way:
-+
-[source,java]
-----
-routeTemplate("s3template")
-    .templateParameter("region")
-    .templateParameter("bucket")
-    .templateBean("myClient", S3Client.class, "bean", 
"com.foo.MyAwsHelper?method=createS3Client")
-    .from("direct:s3-store")
-     // must refer to the bean with {{myClient}}
-    .to("aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}")
-----
-
-XML::
-+
-[source,xml]
-----
-  <routeTemplate id="s3template">
-    <templateParameter name="region"/>
-    <templateParameter name="bucket"/>
-    <templateBean name="myClient" scriptLanguage="bean"
-                  type="software.amazon.awssdk.services.s3.S3Client">
-        <script>com.foo.MyAwsHelper?method=createS3Client</script>
-    </templateBean>
-    <route>
-      <from uri="direct:s3-store"/>
-      <to uri="aws2-s3:{{bucket}}?amazonS3Client=#{{myClient}}"/>
-    </route>
-  </routeTemplate>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- routeTemplate:
-    id: "s3template"
-    parameters:
-      - name: "region"
-      - name: "bucket"
-    beans:
-      - name: "myClient"
-        scriptLanguage: "bean"
-        type: "software.amazon.awssdk.services.s3.S3Client"
-        script: "com.foo.MyAwsHelper?method=createS3Client"
-    from:
-      uri: direct:s3-store
-      steps:
-        - to:
-            uri: "aws2-s3:{{bucket}}"
-            parameters:
-              amazonS3Client: "#{{myClient}}"
-----
-====
+Route templates support binding locally-scoped beans that are private to each 
route created from the template.
+This is an advanced feature.
 
+See xref:route-template-bean-binding.adoc[Route Template Bean Binding] for 
details.
 
 == Configuring route templates when creating route (advanced)
 
diff --git a/docs/user-manual/modules/ROOT/pages/security.adoc 
b/docs/user-manual/modules/ROOT/pages/security.adoc
index da6512831e5c..9ea97369884c 100644
--- a/docs/user-manual/modules/ROOT/pages/security.adoc
+++ b/docs/user-manual/modules/ROOT/pages/security.adoc
@@ -100,62 +100,50 @@ The following _Vaults_ are supported by Camel:
 * xref:components::hashicorp-vault-component.adoc[Hashicorp Vault]
 * xref:components::ibm-secrets-manager-component.adoc[IBM Secrets Manager]
 
-==== Using AWS Vault
-
-To use AWS Secrets Manager, you need to provide _accessKey_, _secretKey_ and 
the _region_.
-This can be done using environmental variables before starting the application:
-
-[source,bash]
-----
-export $CAMEL_VAULT_AWS_ACCESS_KEY=accessKey
-export $CAMEL_VAULT_AWS_SECRET_KEY=secretKey
-export $CAMEL_VAULT_AWS_REGION=region
-----
-
-You can also configure the credentials in the `application.properties` file 
such as:
-
-[source,properties]
-----
-camel.vault.aws.accessKey = accessKey
-camel.vault.aws.secretKey = secretKey
-camel.vault.aws.region = region
-----
-
-If you want instead to use the 
https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials.html[AWS
 default credentials provider], you'll need to provide the following env 
variables:
-
-[source,bash]
-----
-export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=true
-export $CAMEL_VAULT_AWS_REGION=region
-----
+==== Vault Usage Syntax
 
-You can also configure the credentials in the `application.properties` file 
such as:
+All vault providers use the same property placeholder syntax. The prefix 
identifies which vault to use:
 
-[source,properties]
-----
-camel.vault.aws.defaultCredentialsProvider = true
-camel.vault.aws.region = region
-----
+[width="100%",cols="2,1,3",options="header"]
+|===
+| Provider | Prefix | Required JAR
+| AWS Secrets Manager | `aws:` | `camel-aws-secrets-manager`
+| Google Secret Manager | `gcp:` | `camel-google-secret-manager`
+| Azure Key Vault | `azure:` | `camel-azure-key-vault`
+| Hashicorp Vault | `hashicorp:` | `camel-hashicorp-vault`
+| IBM Secrets Manager | `ibm:` | `camel-ibm-secrets-manager`
+| CyberArk Conjur | `cyberark:` | `camel-cyberark-vault`
+|===
 
-It is also possible to specify a particular profile name for accessing AWS 
Secrets Manager
+The following syntax forms are supported (replace `<prefix>` with the provider 
prefix from the table above):
 
-[source,bash]
+[source,text]
 ----
-export $CAMEL_VAULT_AWS_USE_PROFILE_CREDENTIALS_PROVIDER=true
-export $CAMEL_VAULT_AWS_PROFILE_NAME=test-account
-export $CAMEL_VAULT_AWS_REGION=region
+{{<prefix>:secretName}}                        <1>
+{{<prefix>:secretName:defaultValue}}           <2>
+{{<prefix>:secretName#fieldName}}              <3>
+{{<prefix>:secretName#fieldName:defaultValue}} <4>
 ----
+<1> Lookup the secret value. Fails if the secret does not exist.
+<2> Lookup the secret value, falling back to `defaultValue` if the secret does 
not exist.
+<3> Lookup a specific field from a JSON-structured secret.
+<4> Lookup a specific field, with a fallback default value.
 
-You can also configure the credentials in the `application.properties` file 
such as:
+For example, if you have a JSON secret named `database`:
 
-[source,properties]
+[source,json]
 ----
-camel.vault.aws.profileCredentialsProvider = true
-camel.vault.aws.profileName = test-account
-camel.vault.aws.region = region
+{
+  "username": "admin",
+  "password": "password123",
+  "engine": "postgres",
+  "host": "127.0.0.1",
+  "port": "3128",
+  "dbname": "db"
+}
 ----
 
-At this point you'll be able to reference a property in the following way by 
using `aws:` as prefix in the `{{ }}` syntax:
+You can access individual fields using the `#` syntax:
 
 [tabs]
 ====
@@ -165,7 +153,8 @@ Java::
 [source,java]
 ----
 from("direct:start")
-  .to("{{aws:route}}");
+  .log("Username is {{aws:database#username}}")
+  .log("Password is {{aws:database#password:secret}}");
 ----
 
 XML::
@@ -174,7 +163,8 @@ XML::
 ----
 <route>
     <from uri="direct:start"/>
-    <to uri="{{aws:route}}"/>
+    <log message="Username is {{aws:database#username}}"/>
+    <log message="Password is {{aws:database#password:secret}}"/>
 </route>
 ----
 
@@ -186,143 +176,90 @@ YAML::
     from:
       uri: direct:start
       steps:
-        - to:
-            uri: "{{aws:route}}"
+        - log:
+            message: "Username is {{aws:database#username}}"
+        - log:
+            message: "Password is {{aws:database#password:secret}}"
 ----
 ====
 
-Where `route` will be the name of the secret stored in the AWS Secrets Manager 
Service.
-
-You could specify a default value (`aws:key:default-value`) in case the secret 
is not present on AWS Secret Manager:
+The examples above use the `aws:` prefix but the same syntax works with any 
provider prefix (`gcp:`, `azure:`, `hashicorp:`, `ibm:`, `cyberark:`).
 
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{aws:route:myDefault}}");
-----
+===== Version Syntax
 
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{aws:route:myDefault}}"/>
-</route>
-----
+Hashicorp Vault, IBM Secrets Manager, and CyberArk Conjur support retrieving a 
specific version of a secret using the `@` suffix:
 
-YAML::
-+
-[source,yaml]
+[source,text]
 ----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{aws:route:myDefault}}"
+{{hashicorp:secret:route@2}}                              <1>
+{{hashicorp:route:defaultValue@2}}                        <2>
+{{hashicorp:secret:database#username:admin@2}}            <3>
+{{ibm:default:route@2}}                                   <4>
+{{cyberark:route@2}}                                      <5>
 ----
-====
+<1> Hashicorp: get secret `route` at version 2 from the `secret` engine.
+<2> Hashicorp: get secret `route` at version 2, with default fallback.
+<3> Hashicorp: get field `username` from secret `database` at version 2.
+<4> IBM: get secret `route` at version 2 from the `default` secret group.
+<5> CyberArk: get secret `route` at version 2.
 
-In this case, if the secret doesn't exist, the property will fallback to 
"myDefault" as value.
+==== Using AWS Vault
 
-Also, you are able to get a particular field of the secret, if you have, for 
example, a secret named database of this form:
+To use AWS Secrets Manager, you need to provide _accessKey_, _secretKey_ and 
the _region_.
+This can be done using environmental variables before starting the application:
 
-[source,json]
+[source,bash]
 ----
-{
-  "username": "admin",
-  "password": "password123",
-  "engine": "postgres",
-  "host": "127.0.0.1",
-  "port": "3128",
-  "dbname": "db"
-}
+export $CAMEL_VAULT_AWS_ACCESS_KEY=accessKey
+export $CAMEL_VAULT_AWS_SECRET_KEY=secretKey
+export $CAMEL_VAULT_AWS_REGION=region
 ----
 
-You're able to do get single secret value in your route, like for example:
-
-[tabs]
-====
+You can also configure the credentials in the `application.properties` file 
such as:
 
-Java::
-+
-[source,java]
+[source,properties]
 ----
-from("direct:start")
-  .log("Username is {{aws:database#username}}");
+camel.vault.aws.accessKey = accessKey
+camel.vault.aws.secretKey = secretKey
+camel.vault.aws.region = region
 ----
 
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{aws:database#username}}"/>
-</route>
-----
+If you want instead to use the 
https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials.html[AWS
 default credentials provider], you'll need to provide the following env 
variables:
 
-YAML::
-+
-[source,yaml]
+[source,bash]
 ----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{aws2:database#username}}"
+export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=true
+export $CAMEL_VAULT_AWS_REGION=region
 ----
-====
-
-Or re-use the property as part of an endpoint.
 
-You could specify a default value in case the particular field of secret is 
not present on AWS Secret Manager:
-
-[tabs]
-====
+You can also configure the credentials in the `application.properties` file 
such as:
 
-Java::
-+
-[source,java]
+[source,properties]
 ----
-from("direct:start")
-  .log("Username is {{aws:database#username:admin}}");
+camel.vault.aws.defaultCredentialsProvider = true
+camel.vault.aws.region = region
 ----
 
+It is also possible to specify a particular profile name for accessing AWS 
Secrets Manager:
 
-XML::
-+
-[source,xml]
+[source,bash]
 ----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{aws:database#username:admin}}"/>
-</route>
+export $CAMEL_VAULT_AWS_USE_PROFILE_CREDENTIALS_PROVIDER=true
+export $CAMEL_VAULT_AWS_PROFILE_NAME=test-account
+export $CAMEL_VAULT_AWS_REGION=region
 ----
 
-YAML::
-+
-[source,yaml]
+You can also configure the credentials in the `application.properties` file 
such as:
+
+[source,properties]
 ----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{aws:database#username:admin}}"
+camel.vault.aws.profileCredentialsProvider = true
+camel.vault.aws.profileName = test-account
+camel.vault.aws.region = region
 ----
-====
 
-In this case, if the secret doesn't exist or the secret exists, but the 
username field is not part of the secret, the property will fall back to 
"admin" as value.
-
-NOTE: For the moment we are not considering the rotation function if any are 
applied, but it is in the work to be done.
+At this point you'll be able to reference a property by using `aws:` as prefix 
in the `{{ }}` syntax.
+See <<Vault Usage Syntax>> for the full syntax reference.
 
 The only requirement is adding `camel-aws-secrets-manager` JAR to your Camel 
application.
 
@@ -358,1019 +295,131 @@ You can also configure the credentials in the 
`application.properties` file such
 [source,properties]
 ----
 camel.vault.gcp.useDefaultInstance = true
-camel.vault.aws.projectId = region
+camel.vault.gcp.projectId = projectId
 ----
 
-At this point you'll be able to reference a property in the following way by 
using `gcp:` as prefix in the `{{ }}` syntax:
+At this point you'll be able to reference a property by using `gcp:` as prefix 
in the `{{ }}` syntax.
+See <<Vault Usage Syntax>> for the full syntax reference.
 
-[tabs]
-====
+There are only two requirements:
+- Adding `camel-google-secret-manager` JAR to your Camel application.
+- Give the service account used permissions to do operation at secret 
management level (for example accessing the secret payload, or being admin of 
secret manager service)
 
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{gcp:route}}");
-----
+==== Using Azure Key Vault
 
-XML::
-+
-[source,xml]
-----
-    <route>
-        <from uri="direct:start"/>
-        <to uri="{{gcp:route}}"/>
-    </route>
-----
+To use this function, you'll need to provide credentials to Azure Key Vault 
Service as environment variables:
 
-YAML::
-+
-[source,yaml]
+[source,bash]
 ----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{gcp:route}}"
+export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId
+export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId
+export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret
+export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
 ----
-====
-
-Where `route` will be the name of the secret stored in the GCP Secret Manager 
Service.
 
-You could specify a default value (`gcp:key:default-value`) in case the secret 
is not present GCP Secret Manager:
-
-[tabs]
-====
+You can also configure the credentials in the `application.properties` file 
such as:
 
-Java::
-+
-[source,java]
+[source,properties]
 ----
-from("direct:start")
-  .to("{{gcp:route:myDefault}}");
+camel.vault.azure.tenantId = accessKey
+camel.vault.azure.clientId = clientId
+camel.vault.azure.clientSecret = clientSecret
+camel.vault.azure.vaultName = vaultName
 ----
 
-XML::
-+
-[source,xml]
+Or you can enable the usage of Azure Identity in the following way:
+
+[source,bash]
 ----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{gcp:route:myDefault}}"/>
-</route>
+export $CAMEL_VAULT_AZURE_IDENTITY_ENABLED=true
+export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
 ----
 
-YAML::
-+
-[source,yaml]
+You can also enable the usage of Azure Identity in the 
`application.properties` file such as:
+
+[source,properties]
 ----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{gcp:route:myDefault}}"
+camel.vault.azure.azureIdentityEnabled = true
+camel.vault.azure.vaultName = vaultName
 ----
-====
 
-In this case, if the secret doesn't exist, the property will fallback to 
"myDefault" as value.
+At this point you'll be able to reference a property by using `azure:` as 
prefix in the `{{ }}` syntax.
+See <<Vault Usage Syntax>> for the full syntax reference.
 
-Also, you are able to get a particular field of the secret, if you have, for 
example, a secret named database of this form:
+The only requirement is adding the `camel-azure-key-vault` JAR to your Camel 
application.
 
-[source,json]
+==== Using Hashicorp Vault
+
+To use this function, you'll need to provide credentials for Hashicorp vault 
as environment variables:
+
+[source,bash]
 ----
-{
-  "username": "admin",
-  "password": "password123",
-  "engine": "postgres",
-  "host": "127.0.0.1",
-  "port": "3128",
-  "dbname": "db"
-}
-----
-
-You're able to do get single secret value in your route, like for example:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{gcp:database#username}}");
-----
-
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{gcp:database#username}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{gcp:database#username}}"
-----
-====
-
-Or re-use the property as part of an endpoint.
-
-You could specify a default value in case the particular field of secret is 
not present on GCP Secret Manager:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{gcp:database#username:admin}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{gcp:database#username:admin}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{gcp:database#username:admin}}"
-----
-====
-
-In this case, if the secret doesn't exist or the secret exists, but the 
username field is not part of the secret, the property will fallback to "admin" 
as value.
-
-NOTE: For the moment we are not considering the rotation function if any are 
applied, but it is in the work to be done.
-
-There are only two requirements: 
-- Adding `camel-google-secret-manager` JAR to your Camel application.
-- Give the service account used permissions to do operation at secret 
management level (for example accessing the secret payload, or being admin of 
secret manager service)
-
-==== Using Azure Key Vault
-
-To use this function, you'll need to provide credentials to Azure Key Vault 
Service as environment variables:
-
-[source,bash]
-----
-export $CAMEL_VAULT_AZURE_TENANT_ID=tenantId
-export $CAMEL_VAULT_AZURE_CLIENT_ID=clientId
-export $CAMEL_VAULT_AZURE_CLIENT_SECRET=clientSecret
-export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
+export $CAMEL_VAULT_HASHICORP_TOKEN=token
+export $CAMEL_VAULT_HASHICORP_HOST=host
+export $CAMEL_VAULT_HASHICORP_PORT=port
+export $CAMEL_VAULT_HASHICORP_SCHEME=http/https
 ----
 
 You can also configure the credentials in the `application.properties` file 
such as:
 
 [source,properties]
 ----
-camel.vault.azure.tenantId = accessKey
-camel.vault.azure.clientId = clientId
-camel.vault.azure.clientSecret = clientSecret
-camel.vault.azure.vaultName = vaultName
+camel.vault.hashicorp.token = token
+camel.vault.hashicorp.host = host
+camel.vault.hashicorp.port = port
+camel.vault.hashicorp.scheme = scheme
 ----
 
-Or you can enable the usage of Azure Identity in the following way:
+If the running Hashicorp Vault instance is on Hashicorp Cloud, two additional 
parameters are required:
 
 [source,bash]
 ----
-export $CAMEL_VAULT_AZURE_IDENTITY_ENABLED=true
-export $CAMEL_VAULT_AZURE_VAULT_NAME=vaultName
+export CAMEL_HASHICORP_VAULT_CLOUD=true
+export CAMEL_HASHICORP_VAULT_NAMESPACE=namespace
 ----
 
-You can also enable the usage of Azure Identity in the 
`application.properties` file such as:
+Or in `application.properties`:
 
 [source,properties]
 ----
-camel.vault.azure.azureIdentityEnabled = true
-camel.vault.azure.vaultName = vaultName
-----
-
-At this point, you'll be able to reference a property in the following way:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{azure:route}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{azure:route}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{azure:route}}"
-----
-====
-
-Where route will be the name of the secret stored in the Azure Key Vault 
Service.
-
-You could specify a default value (`azure:key:default-value`) in case the 
secret is not present on Azure Key Value Service:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{azure:route:myDefault}}");
+camel.vault.hashicorp.cloud = true
+camel.vault.hashicorp.namespace = namespace
 ----
 
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{azure:route:myDefault}}"/>
-</route>
-----
+At this point you'll be able to reference a property by using `hashicorp:` as 
prefix in the `{{ }}` syntax.
+Hashicorp Vault also supports <<Version Syntax,version-specific lookups>> 
using the `@` suffix.
+See <<Vault Usage Syntax>> for the full syntax reference.
 
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{azure:route:myDefault}}"
-----
-====
+The only requirement is adding the `camel-hashicorp-vault` JAR to your Camel 
application.
 
-In this case, if the secret doesn't exist, the property will fallback to 
"myDefault" as value.
+==== Using IBM Secrets Manager Vault
 
-Also you are able to get a particular field of the secret if you have, for 
example, a secret named database of this form:
+To use this function, you'll need to provide credentials for IBM Secrets 
Manager vault as environment variables:
 
 [source,bash]
 ----
-{
-  "username": "admin",
-  "password": "password123",
-  "engine": "postgres",
-  "host": "127.0.0.1",
-  "port": "3128",
-  "dbname": "db"
-}
-----
-
-You're able to do get single secret value in your route, like for example:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{azure:database#username}}");
-----
-
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{azure:database#username}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{azure:database#username}}"
-----
-====
-
-Or re-use the property as part of an endpoint.
-
-You could specify a default value in case the particular field of secret is 
not present on Azure Key Vault:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{azure:database#username:admin}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{azure:database#username:admin}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{azure:database#username:admin}}"
+export CAMEL_VAULT_IBM_TOKEN=token
+export CAMEL_VAULT_IBM_SERVICE_URL=serviceUrl
 ----
-====
-
-In this case, if the secret doesn't exist or the secret exists, but the 
username field is not part of the secret, the property will fallback to "admin" 
as value.
-
-For the moment we are not considering the rotation function if any are 
applied, but it is in the work to be done.
-
-The only requirement is adding the camel-azure-key-vault jar to your Camel 
application.
-
-==== Using Hashicorp Vault
 
-To use this function, you'll need to provide credentials for Hashicorp vault 
as environment variables:
-
-[source,bash]
-----
-export $CAMEL_VAULT_HASHICORP_TOKEN=token
-export $CAMEL_VAULT_HASHICORP_HOST=host
-export $CAMEL_VAULT_HASHICORP_PORT=port
-export $CAMEL_VAULT_HASHICORP_SCHEME=http/https
-----
-
-You can also configure the credentials in the `application.properties` file 
such as:
-
-[source,properties]
-----
-camel.vault.hashicorp.token = token
-camel.vault.hashicorp.host = host
-camel.vault.hashicorp.port = port
-camel.vault.hashicorp.scheme = scheme
-----
-
-In case the running Hashicorp Vault instance you're pointing is running on 
Hashicorp Cloud, the configuration will require two additional parameters:
-
-[source,bash]
-----
-export CAMEL_VAULT_HASHICORP_TOKEN=token
-export CAMEL_VAULT_HASHICORP_HOST=host
-export CAMEL_VAULT_HASHICORP_PORT=port
-export CAMEL_VAULT_HASHICORP_SCHEME=http/https
-export CAMEL_HASHICORP_VAULT_CLOUD=true
-export CAMEL_HASHICORP_VAULT_NAMESPACE=namespace
-----
-
-You can also set the same in the `application.properties` file such as:
-
-[source,properties]
-----
-camel.vault.hashicorp.token = token
-camel.vault.hashicorp.host = host
-camel.vault.hashicorp.port = port
-camel.vault.hashicorp.scheme = scheme
-camel.vault.hashicorp.cloud = true
-camel.vault.hashicorp.namespace = namespace
-----
-
-At this point, you'll be able to reference a property in the following way:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{hashicorp:route}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{hashicorp:route}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{hashicorp:route}}"
-----
-====
-
-Where route will be the name of the secret stored in the Hashicorp Vault 
instance, in the 'secret' engine.
-
-You could specify a default value in case the secret is not present on 
Hashicorp Vault instance:
-
-You could specify a default value (`azure:key:default-value`) in case the 
secret is not present on Azure Key Value Service:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{hashicorp:route:myDefault}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{hashicorp:route:myDefault}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{hashicorp:route:myDefault}}"
-----
-====
-
-In this case, if the secret doesn't exist, the property will fallback to 
"myDefault" as value.
-
-Also, you are able to get a particular field of the secret, if you have, for 
example, a secret named database of this form:
-
-[source,bash]
-----
-{
-  "username": "admin",
-  "password": "password123",
-  "engine": "postgres",
-  "host": "127.0.0.1",
-  "port": "3128",
-  "dbname": "db"
-}
-----
-
-You're able to do get single secret value in your route, in the 'secret' 
engine, like, for example:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{hashicorp:database#username}}");
-----
-
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{hashicorp:database#username}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{hashicorp:database#username}}"
-----
-====
-
-Or re-use the property as part of an endpoint.
-
-You could specify a default value in case the particular field of secret is 
not present on Hashicorp Vault instance, in the 'secret' engine:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{hashicorp:database#username:admin}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{hashicorp:database#username:admin}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{hashicorp:database#username:admin}}"
-----
-====
-
-In this case, if the secret doesn't exist or the secret exists (in the 
'secret' engine) but the username field is not part of the secret, the property 
will fall back to "admin" as value.
-
-There is also the syntax to get a particular version of the secret for both 
the approach, with field/default value specified or only with secret:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{hashicorp:secret:route@2}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{hashicorp:secret:route@2}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{hashicorp:secret:route@2}}"
-----
-====
-
-This approach will return the RAW route secret with version '2', in the 
'secret' engine.
-
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{hashicorp:route:default@2}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{hashicorp:route:default@2}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{hashicorp:route:default@2}}"
-----
-====
-
-
-This approach will return the route secret value with version '2' or default 
value in case the secret doesn't exist or the version doesn't exist (in the 
'secret' engine).
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{hashicorp:secret:database#username:admin@2}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{hashicorp:secret:database#username:admin@2}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is 
{{hashicorp:secret:database#username:admin@2}}"
-----
-====
-
-This approach will return the username field of the database secret with 
version '2' or admin in case the secret doesn't exist or the version doesn't 
exist (in the 'secret' engine).
-
-==== Using IBM Secrets Manager Vault
-
-To use this function, you'll need to provide credentials for IBM Secrets 
Manager vault as environment variables:
-
-[source,bash]
-----
-export CAMEL_VAULT_IBM_TOKEN=token
-export CAMEL_VAULT_IBM_SERVICE_URL=serviceUrl
-----
-
-You can also configure the credentials in the `application.properties` file 
such as:
-
-[source,properties]
-----
-camel.vault.ibm.token = token
-camel.vault.ibm.serviceUrl = serviceUrl
-----
-
-NOTE: if you're running the application on a Kubernetes based cloud platform, 
you can initialize the environment variables from a Secret or Configmap to 
enhance security. You can also enhance security by 
xref:manual::using-propertyplaceholder.adoc#_resolving_property_placeholders_on_cloud[setting
 a Secret property placeholder] which will be initialized at application 
runtime only.
-
-NOTE: `camel.vault.ibm` configuration only applies to the IBM Secrets Manager 
Vault properties function (E.g when resolving properties).
-When using the `operation` option to create, get, list secrets etc., you 
should provide the `token` and `serviceUrl` options.
-
-At this point, you'll be able to reference a property in the following way:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{ibm:route}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{ibm:route}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{ibm:route}}"
-----
-====
-
-Where route will be the name of the secret stored in the IBM Secrets Manager 
Vault instance, in the 'default' secret group.
-
-You could specify a default value in case the secret is not present on IBM 
Secrets Manager Vault instance:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{ibm:default:route:default}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{ibm:default:route:default}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{ibm:default:route:default}}"
-----
-====
-
-In this case, if the secret doesn't exist in the 'default' secret group, the 
property will fall back to "default" as value.
-
-Also, you are able to get a particular field of the secret, if you have, for 
example, a secret named database of this form:
-
-[source,bash]
-----
-{
-  "username": "admin",
-  "password": "password123",
-  "engine": "postgres",
-  "host": "127.0.0.1",
-  "port": "3128",
-  "dbname": "db"
-}
-----
-
-You're able to do get single secret value in your route, in the 'default' 
secret group, like for example:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{ibm:default:database#username}}");
-----
-
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{ibm:default:database#username}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{ibm:default:database#username}}"
-----
-====
-
-Or re-use the property as part of an endpoint.
-
-You could specify a default value in case the particular field of secret is 
not present on IBM Secrets Manager Vault instance, in the 'secret' engine:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{ibm:default:database#username:admin}}");
-----
-
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{ibm:default:database#username:admin}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{ibm:default:database#username:admin}}"
-----
-====
-
-In this case, if the secret doesn't exist or the secret exists (in the 
'default' secret group) but the username field is not part of the secret, the 
property will fall back to "admin" as value.
-
-There is also the syntax to get a particular version of the secret for both 
the approaches, with field/default value specified or only with secret:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{ibm:default:route@2}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{ibm:default:route@2}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{ibm:default:route@2}}"
-----
-====
-
-This approach will return the RAW route secret with version '2', in the 
'default' secret group.
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{ibm:default:route:default@2}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{ibm:default:route:default@2}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{ibm:default:route:default@2}}"
-----
-====
-
-This approach will return the route secret value with version '2' or default 
value in case the secret doesn't exist or the version doesn't exist (in the 
'default' secret group).
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{ibm:default:database#username:admin@2}}");
-----
-
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{ibm:default:database#username:admin@2}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
+You can also configure the credentials in the `application.properties` file 
such as:
+
+[source,properties]
 ----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{ibm:default:database#username:admin@2}}"
+camel.vault.ibm.token = token
+camel.vault.ibm.serviceUrl = serviceUrl
 ----
-====
 
-This approach will return the username field of the database secret with 
version '2' or admin in case the secret doesn't exist or the version doesn't 
exist (in the 'default' secret group).
+NOTE: If you're running the application on a Kubernetes based cloud platform, 
you can initialize the environment variables from a Secret or Configmap to 
enhance security. You can also enhance security by 
xref:manual::using-propertyplaceholder.adoc#_resolving_property_placeholders_on_cloud[setting
 a Secret property placeholder] which will be initialized at application 
runtime only.
+
+NOTE: `camel.vault.ibm` configuration only applies to the IBM Secrets Manager 
Vault properties function (E.g when resolving properties).
+When using the `operation` option to create, get, list secrets etc., you 
should provide the `token` and `serviceUrl` options.
+
+IBM Secrets Manager organizes secrets into _secret groups_. The syntax 
includes the group name (e.g. `default`):
+`{{ibm:default:secretName}}`, `{{ibm:default:secretName:fallback}}`, 
`{{ibm:default:secretName#field}}`,
+`{{ibm:default:secretName#field:fallback}}`.
+IBM also supports <<Version Syntax,version-specific lookups>> using the `@` 
suffix.
+See <<Vault Usage Syntax>> for the full syntax reference.
 
 The only requirement is adding the `camel-ibm-secrets-manager` JAR to your 
Camel application.
 
@@ -1419,286 +468,12 @@ camel.vault.cyberark.password = secretpassword
 
 NOTE: If you're running the application on a Kubernetes based cloud platform, 
you can initialize the environment variables from a Secret or ConfigMap to 
enhance security.
 
-At this point, you'll be able to reference a property in the following way:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{cyberark:route}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{cyberark:route}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{cyberark:route}}"
-----
-====
-
-Where `route` will be the name of the secret (variable) stored in the CyberArk 
Conjur Vault instance.
-
-You could specify a default value in case the secret is not present on 
CyberArk Conjur:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{cyberark:route:default}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{cyberark:route:default}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{cyberark:route:default}}"
-----
-====
-
-In this case, if the secret doesn't exist, the property will fall back to 
"default" as value.
-
-Also, you are able to get a particular field of the secret, if you have, for 
example, a secret named database of this form:
-
-[source,json]
-----
-{
-  "username": "admin",
-  "password": "password123",
-  "engine": "postgres",
-  "host": "127.0.0.1",
-  "port": "3128",
-  "dbname": "db"
-}
-----
-
-You're able to get single secret value in your route, like for example:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{cyberark:database#username}}");
-----
-
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{cyberark:database#username}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{cyberark:database#username}}"
-----
-====
-
-Or re-use the property as part of an endpoint.
-
-You could specify a default value in case the particular field of secret is 
not present on CyberArk Conjur:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{cyberark:database#username:admin}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{cyberark:database#username:admin}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{cyberark:database#username:admin}}"
-----
-====
-
-In this case, if the secret doesn't exist or the secret exists but the 
username field is not part of the secret, the property will fall back to 
"admin" as value.
-
-There is also the syntax to get a particular version of the secret for both 
the approaches, with field/default value specified or only with secret:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{cyberark:route@2}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{cyberark:route@2}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{cyberark:route@2}}"
-----
-====
-
-This approach will return the RAW route secret with version '2'.
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{cyberark:route:default@2}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{cyberark:route:default@2}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{cyberark:route:default@2}}"
-----
-====
-
-This approach will return the route secret value with version '2' or default 
value in case the secret doesn't exist or the version doesn't exist.
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("Username is {{cyberark:database#username:admin@2}}");
-----
-
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <log message="Username is {{cyberark:database#username:admin@2}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "Username is {{cyberark:database#username:admin@2}}"
-----
-====
-
-This approach will return the username field of the database secret with 
version '2' or admin in case the secret doesn't exist or the version doesn't 
exist.
-
 NOTE: CyberArk Conjur requires secrets (variables) to be defined in a policy 
file before they can be set.
 
+At this point you'll be able to reference a property by using `cyberark:` as 
prefix in the `{{ }}` syntax.
+CyberArk also supports <<Version Syntax,version-specific lookups>> using the 
`@` suffix.
+See <<Vault Usage Syntax>> for the full syntax reference.
+
 The only requirement is adding the `camel-cyberark-vault` JAR to your Camel 
application.
 
 
diff --git a/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc 
b/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc
index 28e6aa917433..d48d76caa862 100644
--- a/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc
+++ b/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc
@@ -712,745 +712,12 @@ the `${}` notation. And in the Camel routes we use the 
Camel
 placeholder notation with `{\{key}}`.
 
 
-== Using property placeholder functions
+== Property Placeholder Functions
 
-The xref:components::properties-component.adoc[Properties] component includes 
the following functions out of the box:
-
-* `env` - A function to lookup the property from OS environment variables
-* `sys` - A function to lookup the property from Java JVM system properties
-* `bean` - A function to lookup the property from the return value of bean's 
method (requires `camel-bean` JAR)
-* `boolean` - A function to evaluate if a property key matches a condition and 
returns either `true` or `false`
-* `service` - A function to lookup the property from OS environment variables 
using the service naming idiom
-* `service.name` - A function to lookup the property from OS environment 
variables using the service naming idiom returning the hostname part only
-* `service.port` - A function to lookup the property from OS environment 
variables using the service naming idiom returning the port part only
-
-These functions are intended to make it easy to lookup values from the 
environment, as shown in the example below:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{env:SOMENAME}}")
-  .to("{{sys:MyJvmPropertyName}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{env:SOMENAME}}"/>
-    <to uri="{{sys:MyJvmPropertyName}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{env:SOMENAME}}"
-        - to:
-            uri: "{{sys:MyJvmPropertyName}}"
-----
-====
-
-You can use default values as well, so if the property does not exist, you can 
define a default value as shown below, where the default value is a `log:foo` 
and `log:bar` value.
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{env:SOMENAME:log:foo}}")
-  .to("{{sys:MyJvmPropertyName:log:bar}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{env:SOMENAME:log:foo}}"/>
-    <to uri="{{sys:MyJvmPropertyName:log:bar}}"/>
-</route>
-----
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{env:SOMENAME:log:foo}}"
-        - to:
-            uri: "{{sys:MyJvmPropertyName:log:bar}}"
-----
-====
-
-The boolean function is intended for more flexibility when enabling or 
disabling EIP options.
-
-For example given we have a property with key `region` that has the value 
`EMEA`:
-
-[source,properties]
-----
-region = EMEA
-----
-
-We can then configure EIPs whether they are disabled based on this condition 
as follows:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    .choice().disabled("{{boolean:region == 'EMEA'}}")
-        .when(simple("${header.RetryAttempts} == null"))
-            .setProperty("HttpMessageMethod", constant("SET"))
-            .process("SetOriginalMessageProcessor")
-        .end();
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <choice disabled="{{boolean:region == 'EMEA'}}">
-        <when>
-            <simple>${header.RetryAttempts} == null</simple>
-            <setProperty name="HttpMessageMethod">
-                <constant>SET</constant>
-            </setProperty>
-            <process ref="SetOriginalMessageProcessor"/>
-        </when>
-    </choice>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - choice:
-            disabled: "{{boolean:region == 'EMEA'}}"
-            when:
-            - expression:
-                simple:
-                  expression: "${header.RetryAttempts} == null"
-              steps:
-              - setProperty:
-                  name: "HttpMessageMethod"
-                  expression:
-                    constant: "SET"
-              - process:
-                  ref: "SetOriginalMessageProcessor"
-----
-====
-
-[NOTE]
-====
-Property placeholders can also be used in `application.properties` files, also 
with the functions such as ENV as shown:
-
-[source,properties]
-----
-# server name read from ENV and fallback to use localhost as default value
-myserver = {{env:MY_SERVER_NAME:localhost}}
-----
-====
-
-TIP: The boolean function uses the 
xref:components:languages:simple-language.adoc[Simple] language which has many 
functions and operators to build the condition.
-
-The service function is for looking up a service which is defined using OS 
environment variables using the service naming idiom, to refer to a service 
location using `hostname : port`
-
-* __NAME__**_SERVICE_HOST**
-* __NAME__**_SERVICE_PORT**
-
-in other words the service uses `_SERVICE_HOST` and `_SERVICE_PORT` as prefix.
-So if the service is named FOO, then the OS environment variables should be 
set as
-
-[source,bash]
-----
-export $FOO_SERVICE_HOST=myserver
-export $FOO_SERVICE_PORT=8888
-----
-
-For example if the FOO service a remote HTTP service, then we can refer to the 
service in the Camel endpoint uri, and use the HTTP component to make the HTTP 
call:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("http://{{service:FOO}}/myapp";);
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="http://{{service:FOO}}/myapp"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "http://{{service:FOO}}/myapp";
-----
-====
-
-And we can use default values if the service has not been defined, for example 
to call a service on localhost, maybe for unit testing.
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("http://{{service:FOO:localhost:8080}}/myapp";);
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="http://{{service:FOO:localhost:8080}}/myapp"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "http://{{service:FOO:localhost:8080}}/myapp";
-----
-====
-
-The bean function (you need to have `camel-bean` JAR on classpath) is for 
looking up the property from the return value of bean's method.
-
-Assuming we have registered a bean named 'foo' that has a method called 'bar' 
that returns a directory name, then we can refer to the bean's method in the 
camel endpoint url, and use the file component to poll a directory:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("file:{{bean:foo.bar}}")
-  .to("direct:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="file:{{bean:foo.bar}}"/>
-    <to uri="direct:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: file:{{bean:foo.bar}}
-      steps:
-        - to:
-            uri: "direct:result"
-----
-====
-
-IMPORTANT: The method must be a public no-arg method (i.e. no parameters) and 
return a value such as a String, boolean, int.
-
-=== Using Kubernetes property placeholder functions
-
-The `camel-kubernetes` component include the following functions:
-
-* `configmap` - A function to lookup the string property from Kubernetes 
ConfigMaps.
-* `configmap-binary` - A function to lookup the binary property from 
Kubernetes ConfigMaps.
-* `secret` - A function to lookup the string property from Kubernetes Secrets.
-* `secret-binary` - A function to lookup the binary property from Kubernetes 
Secrets.
-
-The syntax for both functions are:
-
-[source,text]
-----
-configmap:name/key[:defaultValue]
-----
-
-Where the default value is optional, for example the following will lookup 
`myKey`,
-and fail if there is no such configmap.
-
-[source,text]
-----
-configmap:mymap/mykey
-----
-
-In this example then it would not fail as a default value is provided:
-
-[source,text]
-----
-configmap:mymap/mykey:123
-----
-
-If the value stored in the configmap is in binary format, so it is stored as 
`Binary Data`, it will be downloaded in a file, and it returns the absolute 
path of the file
-
-[source,text]
-----
-configmap-binary:mymap/mybinkey
-----
-
-it returns a path like `/tmp/camel11787545916150467474/mybinkey`
-
-Before the Kubernetes property placeholder functions can be used they need to 
be configured with either (or both)
-
-- path - A _mount path_ that must be mounted to the running pod, to load the 
configmaps or secrets from local disk.
-- kubernetes client - *Autowired* An 
`io.fabric8.kubernetes.client.KubernetesClient` instance to use for connecting 
to the Kubernetes API server.
-
-Camel will first use _mount paths_ (if configured) to lookup, and then 
fallback to use the `KubernetesClient`.
-
-==== Configuring mount paths for ConfigMaps and Secrets
-
-The configuration of the _mount path_ are used by the given order:
-
-1. Reading configuration property with keys 
`camel.kubernetes-config.mount-path-configmaps` and 
`camel.kubernetes-config.mount-path-secrets`.
-2. Use JVM system property with key `camel.k.mount-path.configmaps` and 
`camel.k.mount-path.secrets` (Camel K compatible).
-3. Use OS ENV variable with key `CAMEL_K_MOUNT_PATH_CONFIGMAPS` and 
`CAMEL_K_MOUNT_PATH_SECRETS` (Camel K compatible).
-
-For example to use `/etc/camel/resources/` as mount path, you can configure 
this in the `application.properties`:
-
-[source,properties]
-----
-camel.kubernetes-config.mount-path-configmaps = /etc/camel/myconfig/
-camel.kubernetes-config.mount-path-secrets = /etc/camel/mysecrets/
-----
-
-==== Configuring Kubernetes Client
-
-Camel will autowire the `KubernetesClient` if a single instance of the client 
exists in the running application (lookup via the xref:registry.adoc[Registry]).
-Otherwise, a new `KubernetesClient` is created. The client can be configured 
from either
-
-- Using `camel.kubernetes-config.client.` properties (see below for example)
-- Attempt to auto-configure itself by a combination of OS Environment 
variables, reading from `~./kube/config` configuration,
-and service account token file. For more details see the 
https://github.com/fabric8io/kubernetes-client documentation.
-
-You most likely only need to explicit configure the `KubernetesClient` when 
you want to connect
-from a local computer to a remote Kubernetes cluster, where you can specify 
various options,
-such as the masterUrl and oauthToken as shown:
-
-[source,properties]
-----
-camel.kubernetes-config.client.masterUrl = https://127.0.0.1:50179/
-camel.kubernetes-config.client.oauthToken = eyJhbGciOiJSUzI1NiIsImtpZCI...
-----
-
-TIP: The `KubernetesClient` has many options, see the 
https://github.com/fabric8io/kubernetes-client[Kubernetes Client] documentation 
for more information for these options.
-
-If you only use _mount paths_, then it is good practice to disable 
`KubernetesClient` which can be done by setting enabled to false as show:
-
-[source,properties]
-----
-camel.kubernetes-config.client-enabled = false
-----
-
-When running your Camel applications inside an existing Kubernetes cluster, 
then you often
-would not need to explicit configure the `KubernetesClient` and can rely on 
default settings.
-
-TIP: If you use Camel Quarkus, then it is recommended to use their 
https://quarkus.io/guides/kubernetes-config
-which automatic pre-configure the `KubernetesClient` which Camel then will 
reuse.
-
-==== Using configmap with Kubernetes
-
-Given a configmap named `myconfig` in Kubernetes that has two entries:
-
-[source,properties]
-----
-drink = beer
-first = Carlsberg
-----
-
-Then these values can be used in your Camel routes such as:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("What {{configmap:myconfig/drink}} do you want?")
-  .log("I want {{configmap:myconfig/first}}");
-----
-
-XML::
-+
-[source,xml]
-----
-  <route>
-    <from uri="direct:start"/>
-    <log message="What {{configmap:myconfig/drink}} do you want?"/>
-    <log message="I want {{configmap:myconfig/first}}"/>
-  </route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "What {{configmap:myconfig/drink}} do you want?"
-        - log:
-            message: "I want {{configmap:myconfig/first}}"
-----
-====
-
-You can also provide a default value in case a key does not exist, such as 
`Heiniken` being the default value:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .log("What {{configmap:myconfig/drink}} do you want?")
-  .log("I want {{configmap:myconfig/second:Heineken}}");
-----
-
-XML::
-+
-[source,xml]
-----
-  <route>
-    <from uri="direct:start"/>
-    <log message="What {{configmap:myconfig/drink}} do you want?"/>
-    <log message="I want {{configmap:myconfig/second:Heineken}}"/>
-  </route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - log:
-            message: "What {{configmap:myconfig/drink}} do you want?"
-        - log:
-            message: "I want {{configmap:myconfig/second:Heineken}}"
-----
-====
-
-==== Using secrets with Kubernetes
-
-Camel reads ConfigMaps from the Kubernetes API Server. And when RBAC is 
enabled on the cluster,
-the ServiceAccount that is used to run the application needs to have the 
proper permissions for such access.
-
-A secret named `mydb` could contain username and passwords to connect to a 
database such as:
-
-[source,properties]
-----
-myhost = killroy
-myport = 5555
-myuser = scott
-mypass = tiger
-----
-
-This can be used in Camel with for example the Postgres Sink Kamelet:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-String sink =
-"""
- kamelet:postgresql-sink?serverName={{secret:mydb/myhost}}?
- &serverPort={{secret:mydb/myport}}
- &username={{secret:mydb/myuser}}
- &password={{secret:mydb/mypass}}
- &databaseName=cities
- &query=INSERT INTO accounts (username,city) VALUES (:#username,:#city)
-""";
-
-from("direct:rome")
-  .setBody(constant("{ \"username\":\"oscerd\", \"city\":\"Rome\"}"))
-  .to(sink);
-----
-
-XML::
-+
-[source,xml]
-----
-  <route>
-    <from uri="direct:rome"/>
-    <setBody>
-      <constant>{ "username":"oscerd", "city":"Rome"}</constant>
-    </setBody>
-    <to uri="kamelet:postgresql-sink?serverName={{secret:mydb/myhost}}
-             &amp;serverPort={{secret:mydb/myport}}
-             &amp;username={{secret:mydb/myuser}}
-             &amp;password={{secret:mydb/mypass}}
-             &amp;databaseName=cities
-             &amp;query=INSERT INTO accounts (username,city) VALUES 
(:#username,:#city)"/>
-  </route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct
-      parameters:
-        name: rome
-      steps:
-        - setBody:
-            expression:
-              constant:
-                expression: "{ \"username\":\"oscerd\", \"city\":\"Rome\"}"
-        - to:
-            uri: kamelet
-            parameters:
-              templateId: postgresql-sink
-              serverName: "{{secret:mydb/myhost}}"
-              serverPort: "{{secret:mydb/myport}}"
-              username: "{{secret:mydb/myuser}}"
-              password: "{{secret:mydb/mypass}}"
-              databaseName: 'cities'
-              query: "INSERT INTO accounts (username,city) VALUES 
(:#username,:#city)"
-----
-====
-
-The postgres-sink Kamelet can also be configured in `application.properties` 
which reduces the configuration
-in the route above:
-
-[source,properties]
-----
-camel.component.kamelet.postgresql-sink.databaseName={{secret:mydb/myhost}}
-camel.component.kamelet.postgresql-sink.serverPort={{secret:mydb/myport}}
-camel.component.kamelet.postgresql-sink.username={{secret:mydb/myuser}}
-camel.component.kamelet.postgresql-sink.password={{secret:mydb/mypass}}
-----
-
-Which reduces the route to:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:rome")
-  .setBody(constant("{ \"username\":\"oscerd\", \"city\":\"Rome\"}"))
-  .to("kamelet:postgresql-sink?databaseName=cities&query=INSERT INTO accounts 
(username,city) VALUES (:#username,:#city)");
-----
-
-XML::
-+
-[source,xml]
-----
-  <route>
-    <from uri="direct:rome"/>
-    <setBody>
-      <constant>{ "username":"oscerd", "city":"Rome"}</constant>
-    </setBody>
-    <to uri="kamelet:postgresql-sink?databaseName=cities
-             &amp;query=INSERT INTO accounts (username,city) VALUES 
(:#username,:#city)"/>
-  </route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:rome
-      steps:
-        - setBody:
-            expression:
-              constant:
-                expression: "{ \"username\":\"oscerd\", \"city\":\"Rome\"}"
-        - to:
-            uri: kamelet
-            parameters:
-              templateId: postgresql-sink
-              databaseName: cities
-              query: "INSERT INTO accounts (username,city) VALUES 
(:#username,:#city)"
-----
-====
-
-==== Using configmap or secrets in local-mode
-
-During development, you may want to run in _local mode_ where you do not need 
acces to a Kubernetes cluster, to lookup the configmap.
-In the local mode, then Camel will lookup the configmap _keys_ from local 
properties, eg:
-
-For example the example above with the Postgres kamelet, that was configured 
using a secret:
-
-[source,properties]
-----
-camel.component.kamelet.postgresql-sink.databaseName={{secret:mydb/myhost}}
-camel.component.kamelet.postgresql-sink.serverPort={{secret:mydb/myport}}
-camel.component.kamelet.postgresql-sink.username={{secret:mydb/myuser}}
-camel.component.kamelet.postgresql-sink.password={{secret:mydb/mypass}}
-----
-
-Now suppose we have a local Postgres database we want to use, then we can turn 
on _local mode_
-and specify the credentials in the same properties file:
-
-[source,properties]
-----
-camel.kubernetes-config.local-mode = true
-mydb/myhost=localhost
-mydb/myport=1234
-mydb/myuser=scott
-mydb/mypass=tiger
-----
-
-NOTE: Notice how the key is prefixed with the name of the secret and a slash, 
eg `name/key`. This makes it easy to copy/paste
-from the actual use of the configmap/secret and into the 
`application.properties` file.
-
-
-=== Using custom property placeholder functions
-
-The xref:components::properties-component.adoc[Properties] component allow to 
plugin 3rd party functions which can be used during parsing of the property 
placeholders.
-These functions are then able to do custom logic to resolve the placeholders, 
such as looking up in databases, do custom computations, or whatnot.
-The name of the function becomes the prefix used in the placeholder.
-
-This is best illustrated in the example route below, where we use `beer` as 
the prefix:
-
-[tabs]
-====
-
-Java::
-+
-[source,java]
-----
-from("direct:start")
-  .to("{{beer:FOO}}")
-  .to("{{beer:BAR}}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from uri="direct:start"/>
-    <to uri="{{beer:FOO}}"/>
-    <to uri="{{beer:BAR}}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: "{{beer:FOO}}"
-        - to:
-            uri: "{{beer:BAR}}"
-----
-====
-
-The implementation of the function is only two methods as shown below:
-
-[source,java]
-----
[email protected]("beer")
-public class MyBeerFunction implements PropertiesFunction {
-
-    @Override
-    public String getName() {
-        return "beer";
-    }
-
-    @Override
-    public String apply(String remainder) {
-        return "mock:" + remainder.toLowerCase();
-    }
-}
-----
-
-The function must implement the `org.apache.camel.spi.PropertiesFunction` 
interface.
-The method `getName` is the name of the function (beer).
-And the `apply` method is where we implement the custom logic to do.
-As the sample code is from a unit test, it just returns a value to refer to a 
mock endpoint.
-
-You also need to have `camel-component-maven-plugin` Maven plugin as part of 
building the component will
-then ensure that this custom properties function has necessary source code 
generated that makes Camel
-able to automatically discover the function.
-
-NOTE: If the custom properties function need logic to startup and shutdown, 
then the function can extend `ServiceSupport`
-and have this logic in `doStart` and `doStop` methods.
-
-TIP: For an example see the `camel-base64` component.
+Camel supports built-in functions for looking up properties from environment 
variables, system properties,
+Kubernetes, and custom sources.
 
+See xref:property-placeholder-functions.adoc[Property Placeholder Functions] 
for details.
 
 == Using third party property sources
 

Reply via email to