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 d92534888ba4 CAMEL-24720: docs - the six component pages whose
examples never used their own endpoint get one (hashicorp-vault,
aws-secrets-manager, infinispan-embedded, jcache, knative, mapstruct) (#26564)
d92534888ba4 is described below
commit d92534888ba42d1b6dfa92896e2a6e2ac7927b05
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Sep 17 22:53:01 2026 +0200
CAMEL-24720: docs - the six component pages whose examples never used their
own endpoint get one (hashicorp-vault, aws-secrets-manager,
infinispan-embedded, jcache, knative, mapstruct) (#26564)
* CAMEL-24720: camel-hashicorp-vault - the documentation shows the producer
operations (createSecret, getSecret, deleteSecret, listSecrets) next to the
property function
The page had YAML, XML and Java examples of the properties function only,
so the sample tool and the
readers had no example of the component endpoint. The producer section
shows each operation with the
engine as the endpoint path, the host, port, scheme and token options, the
secretPath option and the
CamelHashicorpVaultSecretPath header, and what the body is before and after.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
* CAMEL-24720: camel-aws-secrets-manager - the producer operations section
shows createSecret, getSecret, deleteSecret and listSecrets with the headers
they take
The page had examples of the properties function only; the producer section
listed the operations (two
were missing) without an example. It now says which header names the secret
(SecretName to create, SecretId
for the rest), what the body is before and after, and shows the four common
operations in Java, XML and
YAML with the default credentials provider.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
* CAMEL-24720: camel-infinispan-embedded - the examples use the
infinispan-embedded scheme and a cache name, not the scheme of the remote
component
The page kept the infinispan: URIs of the combined component from before
the 2021 split into
camel-infinispan and camel-infinispan-embedded, one of them with & where ?
belongs, and the custom listener
example had no cache name although cacheName is required.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
* CAMEL-24720: camel-jcache - the documentation shows the producer
operations and the consumer of cache events, not only the JCache policy
The page documented the JCachePolicy only, so it had no example of a
jcache: endpoint. A producer section
lists the operations, says how the action, the key and the body go
together, and shows a PUT with the
action option and a GET with the action header; a consumer section shows
the event headers and the
filteredEvents option.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
* CAMEL-24720: camel-knative - route examples in the three DSLs for
producing and consuming broker events and for bridging channels, taken from the
tests
The page had programmatic Java examples and Kubernetes manifests only, so
it had no route example a reader
or the sample tool could pick up. The producing and consuming examples
mirror the existing Java-only ones as
plain routes (the CloudEvents transform is transformDataType, the EIP the
YAML and XML DSLs know); the
channel example is the one KnativeHttpTest runs.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
* CAMEL-24720: camel-mapstruct - the documentation shows the mapstruct
endpoint next to the type converter, with when to prefer each
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
* Update
components/camel-aws/camel-aws-secrets-manager/src/main/docs/aws-secrets-manager-component.adoc
Co-authored-by: Guillaume Nodet - AI Bot <[email protected]>
* Update
catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws-secrets-manager-component.adoc
Co-authored-by: Guillaume Nodet - AI Bot <[email protected]>
* Update
catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws-secrets-manager-component.adoc
Co-authored-by: Guillaume Nodet - AI Bot <[email protected]>
* CAMEL-24720: camel-jbang - CatalogSamplesTest expects mapstruct and
knative to have an endpoint example now that their pages have one
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---------
Signed-off-by: Claus Ibsen <[email protected]>
Co-authored-by: Claude Fable 5.1 <[email protected]>
Co-authored-by: Guillaume Nodet - AI Bot <[email protected]>
---
.../docs/aws-secrets-manager-component.adoc | 210 ++++++++++++++++++++
.../catalog/docs/hashicorp-vault-component.adoc | 216 +++++++++++++++++++++
.../docs/infinispan-embedded-component.adoc | 12 +-
.../camel/catalog/docs/jcache-component.adoc | 149 ++++++++++++++
.../camel/catalog/docs/knative-component.adoc | 132 +++++++++++++
.../camel/catalog/docs/mapstruct-component.adoc | 43 ++++
.../main/docs/aws-secrets-manager-component.adoc | 210 ++++++++++++++++++++
.../src/main/docs/hashicorp-vault-component.adoc | 216 +++++++++++++++++++++
.../main/docs/infinispan-embedded-component.adoc | 12 +-
.../src/main/docs/jcache-component.adoc | 149 ++++++++++++++
.../src/main/docs/knative-component.adoc | 132 +++++++++++++
.../src/main/docs/mapstruct-component.adoc | 43 ++++
.../jbang/core/commands/ai/CatalogSamplesTest.java | 14 +-
13 files changed, 1520 insertions(+), 18 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws-secrets-manager-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws-secrets-manager-component.adoc
index a0e521f61bdb..75f33128a8e1 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws-secrets-manager-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws-secrets-manager-component.adoc
@@ -526,6 +526,216 @@ Camel-AWS-Secrets-manager component provides the
following operation on the prod
- batchGetSecret
- updateSecret
- replicateSecretToRegions
+- restoreSecret
+- putSecretValue
+
+The `operation` option selects what to do (the
`CamelAwsSecretsManagerOperation` header overrides it per
+message), and the secret to work on comes from a header:
`CamelAwsSecretsManagerSecretName` when creating a
+secret, `CamelAwsSecretsManagerSecretId` (the name or the ARN) for the other
operations. The path of the
+endpoint is a logical name for the client, not a secret. With
`pojoRequest=true` the message body is the AWS
+SDK request object instead.
+
+==== Creating a secret
+
+The message body is the value of the secret, as a string (with
`binaryPayload=true` it is stored as binary):
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:createSecret")
+ .setHeader(SecretsManagerConstants.SECRET_NAME, constant("database"))
+ .setBody(constant("{\"username\":\"camel\",\"password\":\"secret\"}"))
+
.to("aws-secrets-manager:secrets?operation=createSecret®ion=eu-west-1&useDefaultCredentialsProvider=true");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:createSecret"/>
+ <setHeader name="CamelAwsSecretsManagerSecretName">
+ <constant>database</constant>
+ </setHeader>
+ <setBody>
+ <constant>{"username":"camel","password":"secret"}</constant>
+ </setBody>
+ <to
uri="aws-secrets-manager:secrets?operation=createSecret&region=eu-west-1&useDefaultCredentialsProvider=true"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:createSecret
+ steps:
+ - setHeader:
+ name: CamelAwsSecretsManagerSecretName
+ expression:
+ constant:
+ expression: database
+ - setBody:
+ expression:
+ constant:
+ expression: '{"username":"camel","password":"secret"}'
+ - to:
+ uri:
aws-secrets-manager:secrets?operation=createSecret®ion=eu-west-1&useDefaultCredentialsProvider=true
+----
+====
+
+==== Getting a secret
+
+The message body becomes the value of the secret, and the
`CamelAwsSecretsManagerSecretVersionId` response
+header is set to the version id of the retrieved secret:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:getSecret")
+ .setHeader(SecretsManagerConstants.SECRET_ID, constant("database"))
+
.to("aws-secrets-manager:secrets?operation=getSecret®ion=eu-west-1&useDefaultCredentialsProvider=true")
+ .log("The database secret is ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:getSecret"/>
+ <setHeader name="CamelAwsSecretsManagerSecretId">
+ <constant>database</constant>
+ </setHeader>
+ <to
uri="aws-secrets-manager:secrets?operation=getSecret&region=eu-west-1&useDefaultCredentialsProvider=true"/>
+ <log message="The database secret is ${body}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:getSecret
+ steps:
+ - setHeader:
+ name: CamelAwsSecretsManagerSecretId
+ expression:
+ constant:
+ expression: database
+ - to:
+ uri:
aws-secrets-manager:secrets?operation=getSecret®ion=eu-west-1&useDefaultCredentialsProvider=true
+ - log:
+ message: "The database secret is ${body}"
+----
+====
+
+==== Deleting a secret
+
+The secret is scheduled for deletion with the default recovery window; the
`CamelAwsSecretsManagerSecretForceDeletion`
+header set to `true` deletes it without a retention period:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:deleteSecret")
+ .setHeader(SecretsManagerConstants.SECRET_ID, constant("database"))
+
.to("aws-secrets-manager:secrets?operation=deleteSecret®ion=eu-west-1&useDefaultCredentialsProvider=true");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:deleteSecret"/>
+ <setHeader name="CamelAwsSecretsManagerSecretId">
+ <constant>database</constant>
+ </setHeader>
+ <to
uri="aws-secrets-manager:secrets?operation=deleteSecret&region=eu-west-1&useDefaultCredentialsProvider=true"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:deleteSecret
+ steps:
+ - setHeader:
+ name: CamelAwsSecretsManagerSecretId
+ expression:
+ constant:
+ expression: database
+ - to:
+ uri:
aws-secrets-manager:secrets?operation=deleteSecret®ion=eu-west-1&useDefaultCredentialsProvider=true
+----
+====
+
+==== Listing the secrets
+
+The message body becomes the `ListSecretsResponse` of the AWS SDK, with the
list of the secrets in the region;
+the `CamelAwsSecretsManagerMaxResults` header limits how many are returned:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:listSecrets")
+
.to("aws-secrets-manager:secrets?operation=listSecrets®ion=eu-west-1&useDefaultCredentialsProvider=true")
+ .log("The secrets are ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:listSecrets"/>
+ <to
uri="aws-secrets-manager:secrets?operation=listSecrets&region=eu-west-1&useDefaultCredentialsProvider=true"/>
+ <log message="The secrets are ${body}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:listSecrets
+ steps:
+ - to:
+ uri:
aws-secrets-manager:secrets?operation=listSecrets®ion=eu-west-1&useDefaultCredentialsProvider=true
+ - log:
+ message: "The secrets are ${body}"
+----
+====
== Dependencies
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hashicorp-vault-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hashicorp-vault-component.adoc
index 3126e6d75312..8f6f56c53380 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hashicorp-vault-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hashicorp-vault-component.adoc
@@ -55,6 +55,222 @@ When using a HashiCorp Vault Cloud instance, in addition to
the standard paramet
== Examples
+=== Using the producer operations
+
+The producer works on a secrets engine, given as the path of the endpoint
(`secret` is the default key/value
+engine), and connects with the `host`, `port`, `scheme` and `token` endpoint
options. The `operation` option
+selects what to do, and `secretPath` names the secret to work on; the
`CamelHashicorpVaultProducerOperation`
+and `CamelHashicorpVaultSecretPath` headers override them per message.
+
+==== Creating a secret
+
+The message body is the map of key/value pairs to store as the secret:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:createSecret")
+
.to("hashicorp-vault:secret?operation=createSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:createSecret"/>
+ <to
uri="hashicorp-vault:secret?operation=createSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:createSecret
+ steps:
+ - to:
+ uri:
hashicorp-vault:secret?operation=createSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}
+----
+====
+
+==== Getting a secret
+
+The message body becomes the data of the secret; the
`CamelHashicorpVaultSecretVersion` header reads a given
+version instead of the latest:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:getSecret")
+
.to("hashicorp-vault:secret?operation=getSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}")
+ .log("The database secret is ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:getSecret"/>
+ <to
uri="hashicorp-vault:secret?operation=getSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}"/>
+ <log message="The database secret is ${body}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:getSecret
+ steps:
+ - to:
+ uri:
hashicorp-vault:secret?operation=getSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}
+ - log:
+ message: "The database secret is ${body}"
+----
+====
+
+The secret can also be chosen per message with the
`CamelHashicorpVaultSecretPath` header:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:getSecret")
+ .setHeader(HashicorpVaultConstants.SECRET_PATH, constant("database"))
+
.to("hashicorp-vault:secret?operation=getSecret&host=localhost&port=8200&scheme=http&token={{vault.token}}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:getSecret"/>
+ <setHeader name="CamelHashicorpVaultSecretPath">
+ <constant>database</constant>
+ </setHeader>
+ <to
uri="hashicorp-vault:secret?operation=getSecret&host=localhost&port=8200&scheme=http&token={{vault.token}}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:getSecret
+ steps:
+ - setHeader:
+ name: CamelHashicorpVaultSecretPath
+ expression:
+ constant:
+ expression: database
+ - to:
+ uri:
hashicorp-vault:secret?operation=getSecret&host=localhost&port=8200&scheme=http&token={{vault.token}}
+----
+====
+
+==== Deleting a secret
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:deleteSecret")
+
.to("hashicorp-vault:secret?operation=deleteSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:deleteSecret"/>
+ <to
uri="hashicorp-vault:secret?operation=deleteSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:deleteSecret
+ steps:
+ - to:
+ uri:
hashicorp-vault:secret?operation=deleteSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}
+----
+====
+
+==== Listing the secrets
+
+The message body becomes the list of the names of the secrets in the engine:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:listSecrets")
+
.to("hashicorp-vault:secret?operation=listSecrets&host=localhost&port=8200&scheme=http&token={{vault.token}}")
+ .log("The secrets are ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:listSecrets"/>
+ <to
uri="hashicorp-vault:secret?operation=listSecrets&host=localhost&port=8200&scheme=http&token={{vault.token}}"/>
+ <log message="The secrets are ${body}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:listSecrets
+ steps:
+ - to:
+ uri:
hashicorp-vault:secret?operation=listSecrets&host=localhost&port=8200&scheme=http&token={{vault.token}}
+ - log:
+ message: "The secrets are ${body}"
+----
+====
+
=== Using HashiCorp Vault Property Function
To use this function, you'll need to provide credentials for HashiCorp Vault
as environment variables:
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/infinispan-embedded-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/infinispan-embedded-component.adoc
index a7dcd7c17f2b..6be7f5019d0f 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/infinispan-embedded-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/infinispan-embedded-component.adoc
@@ -225,7 +225,7 @@ Write methods like put(key, value) and remove(key) do not
return the previous va
from("direct:start")
.setHeader(InfinispanConstants.OPERATION).constant(InfinispanOperation.PUT) //
<1>
.setHeader(InfinispanConstants.KEY).constant("123") // <2>
- .to("infinispan:myCacheName&cacheContainer=#cacheContainer"); // <3>
+ .to("infinispan-embedded:myCacheName?cacheContainer=#cacheContainer"); //
<3>
----
<1> Set the operation to perform
<2> Set the key used to identify the element in the cache
@@ -243,7 +243,7 @@ from("direct:start")
.setHeader(InfinispanConstants.KEY).constant("123")
.setHeader(InfinispanConstants.LIFESPAN_TIME).constant(100L) // <1>
.setHeader(InfinispanConstants.LIFESPAN_TIME_UNIT).constant(TimeUnit.MILLISECONDS.toString())
// <2>
- .to("infinispan:myCacheName");
+ .to("infinispan-embedded:myCacheName");
----
<1> Set the lifespan of the entry
<2> Set the time unit for the lifespan
@@ -262,7 +262,7 @@ from("direct:start")
return qf.from(User.class).having("name").like("%abc%").build();
}
})
- .to("infinispan:myCacheName?cacheContainer=#cacheManager") ;
+ .to("infinispan-embedded:myCacheName?cacheContainer=#cacheManager") ;
----
+
@@ -274,7 +274,7 @@ Java::
+
[source,java]
----
-from("infinispan://?cacheContainer=#cacheManager&customListener=#myCustomListener")
+from("infinispan-embedded:myCacheName?cacheContainer=#cacheManager&customListener=#myCustomListener")
.to("mock:result");
----
@@ -283,7 +283,7 @@ XML::
[source,xml]
----
<route>
- <from
uri="infinispan://?cacheContainer=#cacheManager&customListener=#myCustomListener"/>
+ <from
uri="infinispan-embedded:myCacheName?cacheContainer=#cacheManager&customListener=#myCustomListener"/>
<to uri="mock:result"/>
</route>
----
@@ -294,7 +294,7 @@ YAML::
----
- route:
from:
- uri: "infinispan://"
+ uri: infinispan-embedded:myCacheName
parameters:
cacheContainer: "#cacheManager"
customListener: "#myCustomListener"
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jcache-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jcache-component.adoc
index a22fcfaed2e5..aba87a4c06b4 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jcache-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jcache-component.adoc
@@ -29,6 +29,155 @@ include::partial$component-endpoint-headers.adoc[]
== Usage
+=== Producer operations
+
+The producer performs one cache operation per message: the `action` option
sets the default, and the
+`CamelJCacheAction` header overrides it per message. The operations are `PUT`,
`PUTALL`, `PUTIFABSENT`, `GET`,
+`GETALL`, `GETANDREMOVE`, `GETANDREPLACE`, `GETANDPUT`, `REPLACE`, `REMOVE`,
`REMOVEALL`, `CLEAR` and `INVOKE`.
+The `CamelJCacheKey` header names the entry (`CamelJCacheKeys`, a set of keys,
for the `ALL` operations), the
+message body is the value to store, and a `GET` puts the value found in the
body.
+
+Storing a value under a key:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:put")
+ .setHeader(JCacheConstants.KEY, constant("123"))
+ .to("jcache:orders?action=PUT");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="direct:put"/>
+ <setHeader name="CamelJCacheKey">
+ <constant>123</constant>
+ </setHeader>
+ <to uri="jcache:orders?action=PUT"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:put
+ steps:
+ - setHeader:
+ name: CamelJCacheKey
+ expression:
+ constant:
+ expression: "123"
+ - to:
+ uri: jcache:orders?action=PUT
+----
+====
+
+Reading a value back, the operation chosen by the header:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:get")
+ .setHeader(JCacheConstants.ACTION, constant("GET"))
+ .setHeader(JCacheConstants.KEY, constant("123"))
+ .to("jcache:orders")
+ .log("Order 123 is ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="direct:get"/>
+ <setHeader name="CamelJCacheAction">
+ <constant>GET</constant>
+ </setHeader>
+ <setHeader name="CamelJCacheKey">
+ <constant>123</constant>
+ </setHeader>
+ <to uri="jcache:orders"/>
+ <log message="Order 123 is ${body}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:get
+ steps:
+ - setHeader:
+ name: CamelJCacheAction
+ expression:
+ constant:
+ expression: GET
+ - setHeader:
+ name: CamelJCacheKey
+ expression:
+ constant:
+ expression: "123"
+ - to:
+ uri: jcache:orders
+ - log:
+ message: "Order 123 is ${body}"
+----
+====
+
+=== Consuming cache events
+
+The consumer receives the events of the cache: the `CamelJCacheEventType`
header is `CREATED`, `UPDATED`,
+`REMOVED` or `EXPIRED`, `CamelJCacheKey` is the key, the body is the value,
and with `oldValueRequired=true`
+the `CamelJCacheOldValue` header is the previous value. The `filteredEvents`
option names the events to leave
+out:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("jcache:orders?filteredEvents=EXPIRED")
+ .log("Order ${header.CamelJCacheKey} was ${header.CamelJCacheEventType}:
${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="jcache:orders?filteredEvents=EXPIRED"/>
+ <log message="Order ${header.CamelJCacheKey} was
${header.CamelJCacheEventType}: ${body}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: jcache:orders?filteredEvents=EXPIRED
+ steps:
+ - log:
+ message: "Order ${header.CamelJCacheKey} was
${header.CamelJCacheEventType}: ${body}"
+----
+====
+
=== JCache Policy
The JCachePolicy is an interceptor around a route that caches the "result of
the route" (the message body) after the route is completed.
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/knative-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/knative-component.adoc
index 3765787d3bcf..00084b346f47 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/knative-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/knative-component.adoc
@@ -228,6 +228,54 @@ RouteBuilder.addRoutes(context, b -> {
<2> transform data to proper Http CloudEvents format
<3> push event to the broker that gets resolved via the `Knative Environment`
+The same route in the DSLs, with the component configured through
`camel.component.knative.environmentPath`
+as shown above:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("timer:tick")
+ .setBody().simple("Hello Knative!")
+ .transformDataType("http:application-cloudevents")
+ .to("knative:event/default?kind=Broker&name=default");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="timer:tick"/>
+ <setBody>
+ <simple>Hello Knative!</simple>
+ </setBody>
+ <transformDataType toType="http:application-cloudevents"/>
+ <to uri="knative:event/default?kind=Broker&name=default"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: timer:tick
+ steps:
+ - setBody:
+ expression:
+ simple:
+ expression: Hello Knative!
+ - transformDataType:
+ toType: http:application-cloudevents
+ - to:
+ uri: knative:event/default?kind=Broker&name=default
+----
+====
+
The Knative eventing broker uses CloudEvents data format by default.
This is why we transform the data with the given data type before sending the
request to the broker.
The data type will set proper CloudEvent attributes like event type, id,
source, subject and so on.
@@ -361,6 +409,42 @@ RouteBuilder.addRoutes(context, b -> {
});
----
+The same route in the DSLs; the body is the data of the CloudEvent and its
attributes are message headers such
+as `CamelCloudEventType` and `CamelCloudEventSource`:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("knative:event/default?kind=Broker&name=default")
+ .log("Received event: ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="knative:event/default?kind=Broker&name=default"/>
+ <log message="Received event: ${body}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: knative:event/default?kind=Broker&name=default
+ steps:
+ - log:
+ message: "Received event: ${body}"
+----
+====
+
The according `Knative Environment` configuration that specifies the Http
service looks like this:
.knative.json
@@ -384,3 +468,51 @@ The according `Knative Environment` configuration that
specifies the Http servic
This will create a proper Http service with the right resource path routing so
that all incoming event requests will be consumed by the Camel route.
Once again the Knative broker will use CloudEvent data format by default, so
you can access the CloudEvent attributes such as event type, id, source,
subject in the Camel route.
+
+=== Bridging channels
+
+The `channel` resource type works the same way with
https://knative.dev/docs/eventing/channels/[Knative channels]:
+a route consumes the messages of one channel and produces to another, with
both channels declared in the
+`Knative Environment` as `channel` resources, the consumed one with
`"endpointKind": "source"` and the produced
+one with `"endpointKind": "sink"`:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("knative:channel/messages")
+ .transform().simple("transformed ${body}")
+ .to("knative:channel/words");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="knative:channel/messages"/>
+ <transform>
+ <simple>transformed ${body}</simple>
+ </transform>
+ <to uri="knative:channel/words"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: knative:channel/messages
+ steps:
+ - transform:
+ expression:
+ simple:
+ expression: transformed ${body}
+ - to:
+ uri: knative:channel/words
+----
+====
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mapstruct-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mapstruct-component.adoc
index b73bd57aa366..05b6389d0599 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mapstruct-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mapstruct-component.adoc
@@ -92,6 +92,49 @@ YAML::
Where `MyFooDto` is a POJO that MapStruct is able to convert to/from.
+=== Using the mapstruct endpoint
+
+The same conversion can be a step of the route with the `mapstruct` endpoint,
whose path is the fully qualified
+class name of the POJO to convert the message body to. This makes the mapping
visible in the route, and with
+`mandatory=false` a body that no mapper can convert passes through unchanged
instead of failing:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:foo")
+ .to("mapstruct:com.foo.MyFooDto")
+ .to("direct:process");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="direct:foo"/>
+ <to uri="mapstruct:com.foo.MyFooDto"/>
+ <to uri="direct:process"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:foo
+ steps:
+ - to:
+ uri: mapstruct:com.foo.MyFooDto
+ - to:
+ uri: direct:process
+----
+====
+
NOTE: Camel does not support mapper methods defined with a `void` return type
such as those used with `@MappingTarget`.
WARNING: If you define multiple mapping methods for the same from / to types,
then the implementation chosen by
diff --git
a/components/camel-aws/camel-aws-secrets-manager/src/main/docs/aws-secrets-manager-component.adoc
b/components/camel-aws/camel-aws-secrets-manager/src/main/docs/aws-secrets-manager-component.adoc
index a0e521f61bdb..75f33128a8e1 100644
---
a/components/camel-aws/camel-aws-secrets-manager/src/main/docs/aws-secrets-manager-component.adoc
+++
b/components/camel-aws/camel-aws-secrets-manager/src/main/docs/aws-secrets-manager-component.adoc
@@ -526,6 +526,216 @@ Camel-AWS-Secrets-manager component provides the
following operation on the prod
- batchGetSecret
- updateSecret
- replicateSecretToRegions
+- restoreSecret
+- putSecretValue
+
+The `operation` option selects what to do (the
`CamelAwsSecretsManagerOperation` header overrides it per
+message), and the secret to work on comes from a header:
`CamelAwsSecretsManagerSecretName` when creating a
+secret, `CamelAwsSecretsManagerSecretId` (the name or the ARN) for the other
operations. The path of the
+endpoint is a logical name for the client, not a secret. With
`pojoRequest=true` the message body is the AWS
+SDK request object instead.
+
+==== Creating a secret
+
+The message body is the value of the secret, as a string (with
`binaryPayload=true` it is stored as binary):
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:createSecret")
+ .setHeader(SecretsManagerConstants.SECRET_NAME, constant("database"))
+ .setBody(constant("{\"username\":\"camel\",\"password\":\"secret\"}"))
+
.to("aws-secrets-manager:secrets?operation=createSecret®ion=eu-west-1&useDefaultCredentialsProvider=true");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:createSecret"/>
+ <setHeader name="CamelAwsSecretsManagerSecretName">
+ <constant>database</constant>
+ </setHeader>
+ <setBody>
+ <constant>{"username":"camel","password":"secret"}</constant>
+ </setBody>
+ <to
uri="aws-secrets-manager:secrets?operation=createSecret&region=eu-west-1&useDefaultCredentialsProvider=true"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:createSecret
+ steps:
+ - setHeader:
+ name: CamelAwsSecretsManagerSecretName
+ expression:
+ constant:
+ expression: database
+ - setBody:
+ expression:
+ constant:
+ expression: '{"username":"camel","password":"secret"}'
+ - to:
+ uri:
aws-secrets-manager:secrets?operation=createSecret®ion=eu-west-1&useDefaultCredentialsProvider=true
+----
+====
+
+==== Getting a secret
+
+The message body becomes the value of the secret, and the
`CamelAwsSecretsManagerSecretVersionId` response
+header is set to the version id of the retrieved secret:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:getSecret")
+ .setHeader(SecretsManagerConstants.SECRET_ID, constant("database"))
+
.to("aws-secrets-manager:secrets?operation=getSecret®ion=eu-west-1&useDefaultCredentialsProvider=true")
+ .log("The database secret is ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:getSecret"/>
+ <setHeader name="CamelAwsSecretsManagerSecretId">
+ <constant>database</constant>
+ </setHeader>
+ <to
uri="aws-secrets-manager:secrets?operation=getSecret&region=eu-west-1&useDefaultCredentialsProvider=true"/>
+ <log message="The database secret is ${body}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:getSecret
+ steps:
+ - setHeader:
+ name: CamelAwsSecretsManagerSecretId
+ expression:
+ constant:
+ expression: database
+ - to:
+ uri:
aws-secrets-manager:secrets?operation=getSecret®ion=eu-west-1&useDefaultCredentialsProvider=true
+ - log:
+ message: "The database secret is ${body}"
+----
+====
+
+==== Deleting a secret
+
+The secret is scheduled for deletion with the default recovery window; the
`CamelAwsSecretsManagerSecretForceDeletion`
+header set to `true` deletes it without a retention period:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:deleteSecret")
+ .setHeader(SecretsManagerConstants.SECRET_ID, constant("database"))
+
.to("aws-secrets-manager:secrets?operation=deleteSecret®ion=eu-west-1&useDefaultCredentialsProvider=true");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:deleteSecret"/>
+ <setHeader name="CamelAwsSecretsManagerSecretId">
+ <constant>database</constant>
+ </setHeader>
+ <to
uri="aws-secrets-manager:secrets?operation=deleteSecret&region=eu-west-1&useDefaultCredentialsProvider=true"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:deleteSecret
+ steps:
+ - setHeader:
+ name: CamelAwsSecretsManagerSecretId
+ expression:
+ constant:
+ expression: database
+ - to:
+ uri:
aws-secrets-manager:secrets?operation=deleteSecret®ion=eu-west-1&useDefaultCredentialsProvider=true
+----
+====
+
+==== Listing the secrets
+
+The message body becomes the `ListSecretsResponse` of the AWS SDK, with the
list of the secrets in the region;
+the `CamelAwsSecretsManagerMaxResults` header limits how many are returned:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:listSecrets")
+
.to("aws-secrets-manager:secrets?operation=listSecrets®ion=eu-west-1&useDefaultCredentialsProvider=true")
+ .log("The secrets are ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:listSecrets"/>
+ <to
uri="aws-secrets-manager:secrets?operation=listSecrets&region=eu-west-1&useDefaultCredentialsProvider=true"/>
+ <log message="The secrets are ${body}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:listSecrets
+ steps:
+ - to:
+ uri:
aws-secrets-manager:secrets?operation=listSecrets®ion=eu-west-1&useDefaultCredentialsProvider=true
+ - log:
+ message: "The secrets are ${body}"
+----
+====
== Dependencies
diff --git
a/components/camel-hashicorp-vault/src/main/docs/hashicorp-vault-component.adoc
b/components/camel-hashicorp-vault/src/main/docs/hashicorp-vault-component.adoc
index 3126e6d75312..8f6f56c53380 100644
---
a/components/camel-hashicorp-vault/src/main/docs/hashicorp-vault-component.adoc
+++
b/components/camel-hashicorp-vault/src/main/docs/hashicorp-vault-component.adoc
@@ -55,6 +55,222 @@ When using a HashiCorp Vault Cloud instance, in addition to
the standard paramet
== Examples
+=== Using the producer operations
+
+The producer works on a secrets engine, given as the path of the endpoint
(`secret` is the default key/value
+engine), and connects with the `host`, `port`, `scheme` and `token` endpoint
options. The `operation` option
+selects what to do, and `secretPath` names the secret to work on; the
`CamelHashicorpVaultProducerOperation`
+and `CamelHashicorpVaultSecretPath` headers override them per message.
+
+==== Creating a secret
+
+The message body is the map of key/value pairs to store as the secret:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:createSecret")
+
.to("hashicorp-vault:secret?operation=createSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:createSecret"/>
+ <to
uri="hashicorp-vault:secret?operation=createSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:createSecret
+ steps:
+ - to:
+ uri:
hashicorp-vault:secret?operation=createSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}
+----
+====
+
+==== Getting a secret
+
+The message body becomes the data of the secret; the
`CamelHashicorpVaultSecretVersion` header reads a given
+version instead of the latest:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:getSecret")
+
.to("hashicorp-vault:secret?operation=getSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}")
+ .log("The database secret is ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:getSecret"/>
+ <to
uri="hashicorp-vault:secret?operation=getSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}"/>
+ <log message="The database secret is ${body}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:getSecret
+ steps:
+ - to:
+ uri:
hashicorp-vault:secret?operation=getSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}
+ - log:
+ message: "The database secret is ${body}"
+----
+====
+
+The secret can also be chosen per message with the
`CamelHashicorpVaultSecretPath` header:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:getSecret")
+ .setHeader(HashicorpVaultConstants.SECRET_PATH, constant("database"))
+
.to("hashicorp-vault:secret?operation=getSecret&host=localhost&port=8200&scheme=http&token={{vault.token}}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:getSecret"/>
+ <setHeader name="CamelHashicorpVaultSecretPath">
+ <constant>database</constant>
+ </setHeader>
+ <to
uri="hashicorp-vault:secret?operation=getSecret&host=localhost&port=8200&scheme=http&token={{vault.token}}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:getSecret
+ steps:
+ - setHeader:
+ name: CamelHashicorpVaultSecretPath
+ expression:
+ constant:
+ expression: database
+ - to:
+ uri:
hashicorp-vault:secret?operation=getSecret&host=localhost&port=8200&scheme=http&token={{vault.token}}
+----
+====
+
+==== Deleting a secret
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:deleteSecret")
+
.to("hashicorp-vault:secret?operation=deleteSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:deleteSecret"/>
+ <to
uri="hashicorp-vault:secret?operation=deleteSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:deleteSecret
+ steps:
+ - to:
+ uri:
hashicorp-vault:secret?operation=deleteSecret&secretPath=database&host=localhost&port=8200&scheme=http&token={{vault.token}}
+----
+====
+
+==== Listing the secrets
+
+The message body becomes the list of the names of the secrets in the engine:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:listSecrets")
+
.to("hashicorp-vault:secret?operation=listSecrets&host=localhost&port=8200&scheme=http&token={{vault.token}}")
+ .log("The secrets are ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<camelContext>
+ <route>
+ <from uri="direct:listSecrets"/>
+ <to
uri="hashicorp-vault:secret?operation=listSecrets&host=localhost&port=8200&scheme=http&token={{vault.token}}"/>
+ <log message="The secrets are ${body}"/>
+ </route>
+</camelContext>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:listSecrets
+ steps:
+ - to:
+ uri:
hashicorp-vault:secret?operation=listSecrets&host=localhost&port=8200&scheme=http&token={{vault.token}}
+ - log:
+ message: "The secrets are ${body}"
+----
+====
+
=== Using HashiCorp Vault Property Function
To use this function, you'll need to provide credentials for HashiCorp Vault
as environment variables:
diff --git
a/components/camel-infinispan/camel-infinispan-embedded/src/main/docs/infinispan-embedded-component.adoc
b/components/camel-infinispan/camel-infinispan-embedded/src/main/docs/infinispan-embedded-component.adoc
index a7dcd7c17f2b..6be7f5019d0f 100644
---
a/components/camel-infinispan/camel-infinispan-embedded/src/main/docs/infinispan-embedded-component.adoc
+++
b/components/camel-infinispan/camel-infinispan-embedded/src/main/docs/infinispan-embedded-component.adoc
@@ -225,7 +225,7 @@ Write methods like put(key, value) and remove(key) do not
return the previous va
from("direct:start")
.setHeader(InfinispanConstants.OPERATION).constant(InfinispanOperation.PUT) //
<1>
.setHeader(InfinispanConstants.KEY).constant("123") // <2>
- .to("infinispan:myCacheName&cacheContainer=#cacheContainer"); // <3>
+ .to("infinispan-embedded:myCacheName?cacheContainer=#cacheContainer"); //
<3>
----
<1> Set the operation to perform
<2> Set the key used to identify the element in the cache
@@ -243,7 +243,7 @@ from("direct:start")
.setHeader(InfinispanConstants.KEY).constant("123")
.setHeader(InfinispanConstants.LIFESPAN_TIME).constant(100L) // <1>
.setHeader(InfinispanConstants.LIFESPAN_TIME_UNIT).constant(TimeUnit.MILLISECONDS.toString())
// <2>
- .to("infinispan:myCacheName");
+ .to("infinispan-embedded:myCacheName");
----
<1> Set the lifespan of the entry
<2> Set the time unit for the lifespan
@@ -262,7 +262,7 @@ from("direct:start")
return qf.from(User.class).having("name").like("%abc%").build();
}
})
- .to("infinispan:myCacheName?cacheContainer=#cacheManager") ;
+ .to("infinispan-embedded:myCacheName?cacheContainer=#cacheManager") ;
----
+
@@ -274,7 +274,7 @@ Java::
+
[source,java]
----
-from("infinispan://?cacheContainer=#cacheManager&customListener=#myCustomListener")
+from("infinispan-embedded:myCacheName?cacheContainer=#cacheManager&customListener=#myCustomListener")
.to("mock:result");
----
@@ -283,7 +283,7 @@ XML::
[source,xml]
----
<route>
- <from
uri="infinispan://?cacheContainer=#cacheManager&customListener=#myCustomListener"/>
+ <from
uri="infinispan-embedded:myCacheName?cacheContainer=#cacheManager&customListener=#myCustomListener"/>
<to uri="mock:result"/>
</route>
----
@@ -294,7 +294,7 @@ YAML::
----
- route:
from:
- uri: "infinispan://"
+ uri: infinispan-embedded:myCacheName
parameters:
cacheContainer: "#cacheManager"
customListener: "#myCustomListener"
diff --git a/components/camel-jcache/src/main/docs/jcache-component.adoc
b/components/camel-jcache/src/main/docs/jcache-component.adoc
index a22fcfaed2e5..aba87a4c06b4 100644
--- a/components/camel-jcache/src/main/docs/jcache-component.adoc
+++ b/components/camel-jcache/src/main/docs/jcache-component.adoc
@@ -29,6 +29,155 @@ include::partial$component-endpoint-headers.adoc[]
== Usage
+=== Producer operations
+
+The producer performs one cache operation per message: the `action` option
sets the default, and the
+`CamelJCacheAction` header overrides it per message. The operations are `PUT`,
`PUTALL`, `PUTIFABSENT`, `GET`,
+`GETALL`, `GETANDREMOVE`, `GETANDREPLACE`, `GETANDPUT`, `REPLACE`, `REMOVE`,
`REMOVEALL`, `CLEAR` and `INVOKE`.
+The `CamelJCacheKey` header names the entry (`CamelJCacheKeys`, a set of keys,
for the `ALL` operations), the
+message body is the value to store, and a `GET` puts the value found in the
body.
+
+Storing a value under a key:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:put")
+ .setHeader(JCacheConstants.KEY, constant("123"))
+ .to("jcache:orders?action=PUT");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="direct:put"/>
+ <setHeader name="CamelJCacheKey">
+ <constant>123</constant>
+ </setHeader>
+ <to uri="jcache:orders?action=PUT"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:put
+ steps:
+ - setHeader:
+ name: CamelJCacheKey
+ expression:
+ constant:
+ expression: "123"
+ - to:
+ uri: jcache:orders?action=PUT
+----
+====
+
+Reading a value back, the operation chosen by the header:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:get")
+ .setHeader(JCacheConstants.ACTION, constant("GET"))
+ .setHeader(JCacheConstants.KEY, constant("123"))
+ .to("jcache:orders")
+ .log("Order 123 is ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="direct:get"/>
+ <setHeader name="CamelJCacheAction">
+ <constant>GET</constant>
+ </setHeader>
+ <setHeader name="CamelJCacheKey">
+ <constant>123</constant>
+ </setHeader>
+ <to uri="jcache:orders"/>
+ <log message="Order 123 is ${body}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:get
+ steps:
+ - setHeader:
+ name: CamelJCacheAction
+ expression:
+ constant:
+ expression: GET
+ - setHeader:
+ name: CamelJCacheKey
+ expression:
+ constant:
+ expression: "123"
+ - to:
+ uri: jcache:orders
+ - log:
+ message: "Order 123 is ${body}"
+----
+====
+
+=== Consuming cache events
+
+The consumer receives the events of the cache: the `CamelJCacheEventType`
header is `CREATED`, `UPDATED`,
+`REMOVED` or `EXPIRED`, `CamelJCacheKey` is the key, the body is the value,
and with `oldValueRequired=true`
+the `CamelJCacheOldValue` header is the previous value. The `filteredEvents`
option names the events to leave
+out:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("jcache:orders?filteredEvents=EXPIRED")
+ .log("Order ${header.CamelJCacheKey} was ${header.CamelJCacheEventType}:
${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="jcache:orders?filteredEvents=EXPIRED"/>
+ <log message="Order ${header.CamelJCacheKey} was
${header.CamelJCacheEventType}: ${body}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: jcache:orders?filteredEvents=EXPIRED
+ steps:
+ - log:
+ message: "Order ${header.CamelJCacheKey} was
${header.CamelJCacheEventType}: ${body}"
+----
+====
+
=== JCache Policy
The JCachePolicy is an interceptor around a route that caches the "result of
the route" (the message body) after the route is completed.
diff --git
a/components/camel-knative/camel-knative-component/src/main/docs/knative-component.adoc
b/components/camel-knative/camel-knative-component/src/main/docs/knative-component.adoc
index 3765787d3bcf..00084b346f47 100644
---
a/components/camel-knative/camel-knative-component/src/main/docs/knative-component.adoc
+++
b/components/camel-knative/camel-knative-component/src/main/docs/knative-component.adoc
@@ -228,6 +228,54 @@ RouteBuilder.addRoutes(context, b -> {
<2> transform data to proper Http CloudEvents format
<3> push event to the broker that gets resolved via the `Knative Environment`
+The same route in the DSLs, with the component configured through
`camel.component.knative.environmentPath`
+as shown above:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("timer:tick")
+ .setBody().simple("Hello Knative!")
+ .transformDataType("http:application-cloudevents")
+ .to("knative:event/default?kind=Broker&name=default");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="timer:tick"/>
+ <setBody>
+ <simple>Hello Knative!</simple>
+ </setBody>
+ <transformDataType toType="http:application-cloudevents"/>
+ <to uri="knative:event/default?kind=Broker&name=default"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: timer:tick
+ steps:
+ - setBody:
+ expression:
+ simple:
+ expression: Hello Knative!
+ - transformDataType:
+ toType: http:application-cloudevents
+ - to:
+ uri: knative:event/default?kind=Broker&name=default
+----
+====
+
The Knative eventing broker uses CloudEvents data format by default.
This is why we transform the data with the given data type before sending the
request to the broker.
The data type will set proper CloudEvent attributes like event type, id,
source, subject and so on.
@@ -361,6 +409,42 @@ RouteBuilder.addRoutes(context, b -> {
});
----
+The same route in the DSLs; the body is the data of the CloudEvent and its
attributes are message headers such
+as `CamelCloudEventType` and `CamelCloudEventSource`:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("knative:event/default?kind=Broker&name=default")
+ .log("Received event: ${body}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="knative:event/default?kind=Broker&name=default"/>
+ <log message="Received event: ${body}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: knative:event/default?kind=Broker&name=default
+ steps:
+ - log:
+ message: "Received event: ${body}"
+----
+====
+
The according `Knative Environment` configuration that specifies the Http
service looks like this:
.knative.json
@@ -384,3 +468,51 @@ The according `Knative Environment` configuration that
specifies the Http servic
This will create a proper Http service with the right resource path routing so
that all incoming event requests will be consumed by the Camel route.
Once again the Knative broker will use CloudEvent data format by default, so
you can access the CloudEvent attributes such as event type, id, source,
subject in the Camel route.
+
+=== Bridging channels
+
+The `channel` resource type works the same way with
https://knative.dev/docs/eventing/channels/[Knative channels]:
+a route consumes the messages of one channel and produces to another, with
both channels declared in the
+`Knative Environment` as `channel` resources, the consumed one with
`"endpointKind": "source"` and the produced
+one with `"endpointKind": "sink"`:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("knative:channel/messages")
+ .transform().simple("transformed ${body}")
+ .to("knative:channel/words");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="knative:channel/messages"/>
+ <transform>
+ <simple>transformed ${body}</simple>
+ </transform>
+ <to uri="knative:channel/words"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: knative:channel/messages
+ steps:
+ - transform:
+ expression:
+ simple:
+ expression: transformed ${body}
+ - to:
+ uri: knative:channel/words
+----
+====
diff --git a/components/camel-mapstruct/src/main/docs/mapstruct-component.adoc
b/components/camel-mapstruct/src/main/docs/mapstruct-component.adoc
index b73bd57aa366..05b6389d0599 100644
--- a/components/camel-mapstruct/src/main/docs/mapstruct-component.adoc
+++ b/components/camel-mapstruct/src/main/docs/mapstruct-component.adoc
@@ -92,6 +92,49 @@ YAML::
Where `MyFooDto` is a POJO that MapStruct is able to convert to/from.
+=== Using the mapstruct endpoint
+
+The same conversion can be a step of the route with the `mapstruct` endpoint,
whose path is the fully qualified
+class name of the POJO to convert the message body to. This makes the mapping
visible in the route, and with
+`mandatory=false` a body that no mapper can convert passes through unchanged
instead of failing:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:foo")
+ .to("mapstruct:com.foo.MyFooDto")
+ .to("direct:process");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+ <from uri="direct:foo"/>
+ <to uri="mapstruct:com.foo.MyFooDto"/>
+ <to uri="direct:process"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+ from:
+ uri: direct:foo
+ steps:
+ - to:
+ uri: mapstruct:com.foo.MyFooDto
+ - to:
+ uri: direct:process
+----
+====
+
NOTE: Camel does not support mapper methods defined with a `void` return type
such as those used with `@MappingTarget`.
WARNING: If you define multiple mapping methods for the same from / to types,
then the implementation chosen by
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogSamplesTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogSamplesTest.java
index 8899f5644d75..669663a3f1b1 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogSamplesTest.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogSamplesTest.java
@@ -270,7 +270,7 @@ public class CatalogSamplesTest {
}
@Test
- void componentsSharingAPageAndPagesWithoutAnEndpointExample() {
+ void componentsSharingAPageAndPagesThatOnceLackedAnEndpointExample() {
CamelCatalog catalog = new DefaultCamelCatalog();
// smtp, imap and pop3 are documented on the mail page
JsonObject smtp = CatalogSamples.sample(catalog, "smtp", 1);
@@ -281,14 +281,16 @@ public class CatalogSamplesTest {
JsonObject mail = CatalogSamples.sample(catalog, "mail", 1);
assertThat(mail.getString("name")).isEqualTo("mail");
assertThat(mail.get("note")).isNull();
- // mapstruct is used through convertBodyTo, no mapstruct: endpoint in
its examples
+ // mapstruct used to be shown only through convertBodyTo; the page now
has a mapstruct: endpoint example too
JsonObject mapstruct = CatalogSamples.sample(catalog, "mapstruct", 1);
assertThat((Integer) mapstruct.get("count")).isPositive();
- assertThat(mapstruct.getString("note")).contains("none of the
examples");
- // knative shows Kubernetes manifests, no route example
+ assertThat(mapstruct.get("note")).isNull();
+ assertThat(yaml(mapstruct, 0)).contains("mapstruct:");
+ // knative used to show only Kubernetes manifests; the page now has
route examples
JsonObject knative = CatalogSamples.sample(catalog, "knative", 1);
- assertThat((Integer) knative.get("count")).isZero();
- assertThat(knative.getString("hint")).contains("no YAML route
example");
+ assertThat((Integer) knative.get("count")).isPositive();
+ assertThat(knative.get("hint")).isNull();
+ assertThat(yaml(knative, 0)).contains("knative:");
}
@Test