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 3e995e4b664d CAMEL-26235: camel-hazelcast - clear errors for a missing
operation, header or body, getAll copies, map expired events and a working
queue removeIf (#29077)
3e995e4b664d is described below
commit 3e995e4b664d90d748d738f91887d203b9aa4c22
Author: Andrea Cosentino <[email protected]>
AuthorDate: Tue Nov 3 12:11:38 2026 +0100
CAMEL-26235: camel-hazelcast - clear errors for a missing operation, header
or body, getAll copies, map expired events and a working queue removeIf (#29077)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
.../camel/catalog/components/hazelcast-list.json | 2 +-
.../camel/catalog/components/hazelcast-map.json | 2 +-
.../catalog/components/hazelcast-pncounter.json | 3 +
.../camel/catalog/components/hazelcast-queue.json | 4 +-
.../camel/catalog/components/hazelcast-set.json | 2 +-
.../catalog/docs/hazelcast-list-component.adoc | 3 +-
.../catalog/docs/hazelcast-map-component.adoc | 30 +--
.../catalog/docs/hazelcast-multimap-component.adoc | 32 ++--
.../docs/hazelcast-pncounter-component.adoc | 42 +++--
.../catalog/docs/hazelcast-queue-component.adoc | 7 +
.../docs/hazelcast-replicatedmap-component.adoc | 26 ++-
.../docs/hazelcast-ringbuffer-component.adoc | 8 +-
.../catalog/docs/hazelcast-set-component.adoc | 2 +-
.../component/hazelcast/list/hazelcast-list.json | 2 +-
.../component/hazelcast/map/hazelcast-map.json | 2 +-
.../hazelcast/pncounter/hazelcast-pncounter.json | 3 +
.../component/hazelcast/queue/hazelcast-queue.json | 4 +-
.../component/hazelcast/set/hazelcast-set.json | 2 +-
.../src/main/docs/hazelcast-list-component.adoc | 3 +-
.../src/main/docs/hazelcast-map-component.adoc | 30 +--
.../main/docs/hazelcast-multimap-component.adoc | 32 ++--
.../main/docs/hazelcast-pncounter-component.adoc | 42 +++--
.../src/main/docs/hazelcast-queue-component.adoc | 7 +
.../docs/hazelcast-replicatedmap-component.adoc | 26 ++-
.../main/docs/hazelcast-ringbuffer-component.adoc | 8 +-
.../src/main/docs/hazelcast-set-component.adoc | 2 +-
.../component/hazelcast/HazelcastConstants.java | 2 +-
.../hazelcast/HazelcastDefaultProducer.java | 11 +-
.../hazelcast/list/HazelcastListEndpoint.java | 4 +-
.../hazelcast/list/HazelcastListProducer.java | 8 +-
.../hazelcast/listener/CamelMapListener.java | 5 +
.../hazelcast/listener/MapEntryListener.java | 3 +-
.../hazelcast/map/HazelcastMapEndpoint.java | 7 +-
.../pncounter/HazelcastPNCounterProducer.java | 6 +-
.../hazelcast/queue/HazelcastQueueEndpoint.java | 14 +-
.../hazelcast/queue/HazelcastQueueProducer.java | 30 ++-
.../hazelcast/seda/HazelcastSedaProducer.java | 8 +
.../hazelcast/set/HazelcastSetEndpoint.java | 2 +-
.../hazelcast/set/HazelcastSetProducer.java | 4 +-
.../hazelcast/HazelcastMapConsumerExpiredTest.java | 96 ++++++++++
.../hazelcast/HazelcastProducerChecksTest.java | 202 +++++++++++++++++++++
.../hazelcast/HazelcastQueueProducerTest.java | 11 +-
.../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc | 25 +++
.../builder/endpoint/EndpointHeaderBuilders.java | 14 ++
.../HazelcastPNCounterEndpointBuilderFactory.java | 37 ++++
45 files changed, 663 insertions(+), 152 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-list.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-list.json
index 3b3134981753..683c433e3ec6 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-list.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-list.json
@@ -42,7 +42,7 @@
"bodyTypes": {
"consumerOut": { "carriers": [ "pojo" ], "javaType":
"com.hazelcast.collection.ItemEvent", "description": "The Hazelcast ItemEvent
of an item added to or removed from the list, not the item: ${body.item} is the
item, and the CamelHazelcastListenerAction header is added or removed" },
"producerIn": { "carriers": [ "text", "bytes", "file", "value", "map",
"list", "pojo" ], "description": "The item that add and setValue store, at the
index in the CamelHazelcastObjectIndex header when set, and that removeValue
removes when the header is not set: an object Hazelcast can serialize, so a
stream or no body fails. A Collection for addAll, removeAll and retainAll. The
other operations do not use the body" },
- "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option":
"defaultOperation", "value": "add", "carriers": [ "unchanged" ] }, { "option":
"defaultOperation", "value": "setValue", "carriers": [ "unchanged" ] }, {
"option": "defaultOperation", "value": "removeValue", "carriers": [ "unchanged"
] }, { "option": "defaultOperation", "value": "clear", "carriers": [
"unchanged" ] }, { "option": "defaultOperation", "value": "addAll", "carriers":
[ "unchanged" ] }, { "option": "defa [...]
+ "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option":
"defaultOperation", "value": "add", "carriers": [ "unchanged" ] }, { "option":
"defaultOperation", "value": "setValue", "carriers": [ "unchanged" ] }, {
"option": "defaultOperation", "value": "removeValue", "carriers": [ "unchanged"
] }, { "option": "defaultOperation", "value": "clear", "carriers": [
"unchanged" ] }, { "option": "defaultOperation", "value": "addAll", "carriers":
[ "unchanged" ] }, { "option": "defa [...]
},
"properties": {
"cacheName": { "index": 0, "kind": "path", "displayName": "Cache Name",
"group": "common", "label": "", "required": true, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The name of the cache" },
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-map.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-map.json
index 776191f1c24c..17c3a4840618 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-map.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-map.json
@@ -43,7 +43,7 @@
"CamelHazelcastOperationType": { "index": 9, "kind": "header",
"displayName": "", "group": "producer", "label": "producer", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The operation to perform",
"constantName":
"org.apache.camel.component.hazelcast.HazelcastConstants#OPERATION" }
},
"bodyTypes": {
- "consumerOut": { "carriers": [ "unknown" ], "description": "The value of
the entry for an added or updated event, as any member of the cluster stored
it, and no body for removed and evicted: the key is in the
CamelHazelcastObjectId header and the event in CamelHazelcastListenerAction" },
+ "consumerOut": { "carriers": [ "unknown" ], "description": "The value of
the entry for an added or updated event, as any member of the cluster stored
it, and no body for removed, evicted and expired (the time to live of the entry
ended): the key is in the CamelHazelcastObjectId header and the event in
CamelHazelcastListenerAction" },
"producerIn": { "carriers": [ "text", "bytes", "file", "value", "map",
"list", "pojo" ], "description": "The value that put, putIfAbsent and update
store under the key in the CamelHazelcastObjectId header, and that
containsValue looks for: an object Hazelcast can serialize, so a stream fails
(convert it to bytes or text first), and no body fails. The other operations do
not use the body" },
"producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option":
"defaultOperation", "value": "put", "carriers": [ "unchanged" ] }, { "option":
"defaultOperation", "value": "putIfAbsent", "carriers": [ "unchanged" ] }, {
"option": "defaultOperation", "value": "update", "carriers": [ "unchanged" ] },
{ "option": "defaultOperation", "value": "delete", "carriers": [ "unchanged" ]
}, { "option": "defaultOperation", "value": "evict", "carriers": [ "unchanged"
] }, { "option": "defaul [...]
},
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-pncounter.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-pncounter.json
index 68cdfc8f833a..44f041e8dfda 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-pncounter.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-pncounter.json
@@ -29,6 +29,9 @@
"hazelcastInstance": { "index": 2, "kind": "property", "displayName":
"Hazelcast Instance", "group": "advanced", "label": "advanced", "required":
false, "type": "object", "javaType": "com.hazelcast.core.HazelcastInstance",
"deprecated": false, "autowired": false, "secret": false, "description": "The
hazelcast instance reference which can be used for hazelcast endpoint. If you
don't specify the instance reference, camel use the default hazelcast instance
from the camel-hazelcast insta [...]
"hazelcastMode": { "index": 3, "kind": "property", "displayName":
"Hazelcast Mode", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": "node", "description":
"The hazelcast mode reference which kind of instance should be used. If you
don't specify the mode, then the node mode will be the default." }
},
+ "headers": {
+ "CamelHazelcastOperationType": { "index": 0, "kind": "header",
"displayName": "", "group": "producer", "label": "producer", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The operation to perform",
"constantName":
"org.apache.camel.component.hazelcast.HazelcastConstants#OPERATION" }
+ },
"bodyTypes": {
"producerIn": { "carriers": [ "any" ], "description": "Not used, except by
getAndAdd, which adds the body, a number or the text of one, to the counter: no
body fails" },
"producerOut": { "carriers": [ "value" ], "javaType": "java.lang.Long",
"byOption": [ { "option": "defaultOperation", "value": "destroy", "carriers": [
"unchanged" ] } ], "description": "The value of the counter as a Long: after
the change for increment and decrement, before it for getAndAdd, and the
current value for get; destroy keeps the body. The operation comes from the
CamelHazelcastOperationType header, or else the defaultOperation option:
without either the producer fails" }
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-queue.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-queue.json
index 227998360619..0b8a2b4f6b6c 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-queue.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-queue.json
@@ -41,8 +41,8 @@
},
"bodyTypes": {
"consumerOut": { "carriers": [ "pojo" ], "javaType":
"com.hazelcast.collection.ItemEvent", "byOption": [ { "option":
"queueConsumerMode", "value": "poll", "carriers": [ "unknown" ] } ],
"description": "In Listen mode, the default, the Hazelcast ItemEvent of an item
added to or removed from the queue, not the item: ${body.item} is the item, and
the CamelHazelcastListenerAction header is added or removed. In Poll mode the
consumer takes the items off the queue, and the body is the item [...]
- "producerIn": { "carriers": [ "text", "bytes", "file", "value", "map",
"list", "pojo" ], "description": "The item that add, the default, put and offer
add to the queue, and that removeValue removes (without a body it removes the
head): an object Hazelcast can serialize, so a stream or no body fails. A
Collection for removeAll and retainAll. The other operations do not use the
body" },
- "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option":
"defaultOperation", "value": "poll", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "peek", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "take", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "remainingCapacity", "carriers": [ "value" ],
"javaType": "java.lang.Integer" }, { "option": "defaultOperation", "value":
"drainTo", "carriers": [ "value [...]
+ "producerIn": { "carriers": [ "text", "bytes", "file", "value", "map",
"list", "pojo" ], "description": "The item that add, the default, put and offer
add to the queue, and that removeValue removes (without a body it removes the
head): an object Hazelcast can serialize, so a stream or no body fails. A
Collection for removeAll and retainAll, and a java.util.function.Predicate for
removeIf, which fails without one. The other operations do not use the body" },
+ "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option":
"defaultOperation", "value": "poll", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "peek", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "take", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "remainingCapacity", "carriers": [ "value" ],
"javaType": "java.lang.Integer" }, { "option": "defaultOperation", "value":
"drainTo", "carriers": [ "value [...]
},
"properties": {
"cacheName": { "index": 0, "kind": "path", "displayName": "Cache Name",
"group": "common", "label": "", "required": true, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The name of the cache" },
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-set.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-set.json
index 8beaf30aa2b3..63cf22d3932b 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-set.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/hazelcast-set.json
@@ -41,7 +41,7 @@
"bodyTypes": {
"consumerOut": { "carriers": [ "pojo" ], "javaType":
"com.hazelcast.collection.ItemEvent", "description": "The Hazelcast ItemEvent
of an item added to or removed from the set, not the item: ${body.item} is the
item, and the CamelHazelcastListenerAction header is added or removed" },
"producerIn": { "carriers": [ "text", "bytes", "file", "value", "map",
"list", "pojo" ], "description": "The item that add adds and removeValue
removes: an object Hazelcast can serialize, so a stream or no body fails. A
Collection for addAll, removeAll and retainAll. clear and getAll do not use the
body" },
- "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option":
"defaultOperation", "value": "getAll", "carriers": [ "list" ] } ],
"description": "The operations that change the set keep the body. getAll gives
the Hazelcast set itself: a live distributed Set, not a copy. The operation
comes from the CamelHazelcastOperationType header, or else the defaultOperation
option: without either the producer fails" }
+ "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option":
"defaultOperation", "value": "getAll", "carriers": [ "list" ] } ],
"description": "The operations that change the set keep the body. getAll gives
a copy of the items of the set as a Set. The operation comes from the
CamelHazelcastOperationType header, or else the defaultOperation option:
without either the producer fails" }
},
"properties": {
"cacheName": { "index": 0, "kind": "path", "displayName": "Cache Name",
"group": "common", "label": "", "required": true, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The name of the cache" },
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-list-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-list-component.adoc
index 319ad2d3fa25..9f8a86fa1263 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-list-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-list-component.adoc
@@ -211,7 +211,8 @@ YAML::
====
Note that *CamelHazelcastObjectIndex* header is used for indexing
-purpose.
+purpose. The *get* operation needs it: without the header the producer fails.
+The *getAll* operation sets a copy of the items of the list as the message
body.
== List consumer – from(“hazelcast-list:foo”)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-map-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-map-component.adoc
index c0045187a6b7..2cc99093e4fa 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-map-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-map-component.adoc
@@ -344,10 +344,10 @@ template.sendBodyAndHeader("direct:query", null,
"CamelHazelcastQuery", q1);
Hazelcast provides event listeners on their data grid. If you want to be
notified if a cache is manipulated, you can use the map consumer.
-There are four events: *put*, *update*, *delete* and *envict*. The event
-type will be stored in the "*hazelcast.listener.action*" header
-variable. The map consumer provides some additional information inside
-these variables:
+There are five events: *added*, *updated*, *removed*, *evicted* and
+*expired* (the time to live of the entry ended). The event type is stored
+in the `CamelHazelcastListenerAction` header. The map consumer provides
+some additional information inside these variables:
Header Variables inside the response message:
@@ -359,7 +359,7 @@ Header Variables inside the response message:
|`CamelHazelcastListenerType` |`String` |the map consumer sets here
"cachelistener"
-|`CamelHazelcastListenerAction` |`String` |type of event (*added*, *updated*,
*envicted* and *removed*).
+|`CamelHazelcastListenerAction` |`String` |type of event (*added*, *updated*,
*removed*, *evicted* and *expired*).
|`CamelHazelcastObjectId` |`String` |the oid of the object
@@ -368,7 +368,7 @@ Header Variables inside the response message:
|`CamelHazelcastCacheType` |`String` |the type of the cache (e.g., map)
|=======================================================================
-The object value will be stored within *put* and *update* actions inside
+The object value will be stored within *added* and *updated* events inside
the message body.
Here's a sample:
@@ -385,9 +385,9 @@ from("hazelcast-map:foo")
.when(header("CamelHazelcastListenerAction").isEqualTo("added"))
.log("...added")
.to("mock:added")
- .when(header("CamelHazelcastListenerAction").isEqualTo("envicted"))
- .log("...envicted")
- .to("mock:envicted")
+ .when(header("CamelHazelcastListenerAction").isEqualTo("evicted"))
+ .log("...evicted")
+ .to("mock:evicted")
.when(header("CamelHazelcastListenerAction").isEqualTo("updated"))
.log("...updated")
.to("mock:updated")
@@ -412,9 +412,9 @@ XML::
<to uri="mock:added"/>
</when>
<when>
- <simple>${header.CamelHazelcastListenerAction} == 'envicted'</simple>
- <log message="...envicted"/>
- <to uri="mock:envicted"/>
+ <simple>${header.CamelHazelcastListenerAction} == 'evicted'</simple>
+ <log message="...evicted"/>
+ <to uri="mock:evicted"/>
</when>
<when>
<simple>${header.CamelHazelcastListenerAction} == 'updated'</simple>
@@ -451,12 +451,12 @@ YAML::
message: "...added"
- to:
uri: mock:added
- - simple: "${header.CamelHazelcastListenerAction} == 'envicted'"
+ - simple: "${header.CamelHazelcastListenerAction} == 'evicted'"
steps:
- log:
- message: "...envicted"
+ message: "...evicted"
- to:
- uri: mock:envicted
+ uri: mock:evicted
- simple: "${header.CamelHazelcastListenerAction} == 'updated'"
steps:
- log:
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-multimap-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-multimap-component.adoc
index ed2173f1bbe9..ad2527ca5af3 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-multimap-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-multimap-component.adoc
@@ -61,7 +61,7 @@ XML::
<route>
<from uri="direct:put"/>
<log message="put.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>put</constant>
</setHeader>
<to uri="hazelcast-multimap:foo"/>
@@ -77,8 +77,10 @@ YAML::
uri: direct:put
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: put
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: put
- to:
uri: hazelcast-multimap:foo
----
@@ -104,7 +106,7 @@ XML::
<route>
<from uri="direct:removevalue"/>
<log message="removevalue..."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>removevalue</constant>
</setHeader>
<to uri="hazelcast-multimap:foo"/>
@@ -120,8 +122,10 @@ YAML::
uri: direct:removevalue
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: removevalue
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: removevalue
- to:
uri: hazelcast-multimap:foo
----
@@ -153,7 +157,7 @@ XML::
<route>
<from uri="direct:get"/>
<log message="get.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>get</constant>
</setHeader>
<to uri="hazelcast-multimap:foo"/>
@@ -170,8 +174,10 @@ YAML::
uri: direct:get
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: get
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: get
- to:
uri: hazelcast-multimap:foo
- to:
@@ -199,7 +205,7 @@ XML::
<route>
<from uri="direct:delete"/>
<log message="delete.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>delete</constant>
</setHeader>
<to uri="hazelcast-multimap:foo"/>
@@ -215,8 +221,10 @@ YAML::
uri: direct:delete
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: delete
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: delete
- to:
uri: hazelcast-multimap:foo
----
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-pncounter-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-pncounter-component.adoc
index 129ab0d831d8..36c9aee9ca69 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-pncounter-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-pncounter-component.adoc
@@ -58,7 +58,7 @@ XML::
----
<route>
<from uri="direct:increment"/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>increment</constant>
</setHeader>
<to uri="hazelcast-pncounter:foo"/>
@@ -74,8 +74,10 @@ YAML::
uri: direct:increment
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: increment
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: increment
- to:
uri: hazelcast-pncounter:foo
----
@@ -102,7 +104,7 @@ XML::
----
<route>
<from uri="direct:decrement"/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>decrement</constant>
</setHeader>
<to uri="hazelcast-pncounter:foo"/>
@@ -118,8 +120,10 @@ YAML::
uri: direct:decrement
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: decrement
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: decrement
- to:
uri: hazelcast-pncounter:foo
----
@@ -146,7 +150,7 @@ XML::
----
<route>
<from uri="direct:get"/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>get</constant>
</setHeader>
<to uri="hazelcast-pncounter:foo"/>
@@ -162,8 +166,10 @@ YAML::
uri: direct:get
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: get
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: get
- to:
uri: hazelcast-pncounter:foo
----
@@ -191,7 +197,7 @@ XML::
----
<route>
<from uri="direct:getAndAdd"/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>getAndAdd</constant>
</setHeader>
<to uri="hazelcast-pncounter:foo"/>
@@ -207,8 +213,10 @@ YAML::
uri: direct:getAndAdd
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: getAndAdd
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: getAndAdd
- to:
uri: hazelcast-pncounter:foo
----
@@ -217,7 +225,7 @@ YAML::
Provide the delta value in the message body (e.g., 5 to add 5 to the counter):
`long previousValue = template.requestBody("direct:getAndAdd", 5L,
Long.class);`
-The previous value (before the add) will be returned in the message body.
+The previous value (before the add) will be returned in the message body.
Without a numeric body the producer fails.
=== Example for *destroy*:
@@ -238,7 +246,7 @@ XML::
----
<route>
<from uri="direct:destroy"/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>destroy</constant>
</setHeader>
<to uri="hazelcast-pncounter:foo"/>
@@ -254,8 +262,10 @@ YAML::
uri: direct:destroy
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: destroy
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: destroy
- to:
uri: hazelcast-pncounter:foo
----
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-queue-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-queue-component.adoc
index 3c51cdb5c996..eedee2ded338 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-queue-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-queue-component.adoc
@@ -419,6 +419,10 @@ YAML::
----
====
+The message body is the `java.util.function.Predicate` that selects the items
to remove, and after the call the body
+is `true` when an item was removed. A Hazelcast queue cannot remove through
its iterator, so the producer tests the
+items the queue holds and then removes the matching ones in one call: the
operation is not atomic.
+
=== Example for *drain to*:
[tabs]
@@ -461,6 +465,9 @@ YAML::
----
====
+The *CamelHazelcastDrainToCollection* header must hold the `Collection` the
items are moved into: without it the
+producer fails. After the call the body is the number of items moved.
+
=== Example for *take*:
[tabs]
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-replicatedmap-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-replicatedmap-component.adoc
index 4b7c941c28f0..58c6577ffd3c 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-replicatedmap-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-replicatedmap-component.adoc
@@ -14,7 +14,7 @@
*{component-header}*
-The http://www.hazelcast.com/[Hazelcast] instance component is one of Camel
Hazelcast Components which allows you to consume join/leave events of the cache
instance in the cluster.
+The http://www.hazelcast.com/[Hazelcast] Replicated Map component is one of
Camel Hazelcast Components which allows you to access a Hazelcast replicated
map.
A replicated map is a weakly consistent, distributed key-value data structure
with no data partition.
@@ -56,7 +56,7 @@ XML::
<route>
<from uri="direct:put"/>
<log message="put.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>put</constant>
</setHeader>
<to uri="hazelcast-replicatedmap:foo"/>
@@ -72,8 +72,10 @@ YAML::
uri: direct:put
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: put
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: put
- to:
uri: hazelcast-replicatedmap:foo
----
@@ -100,7 +102,7 @@ XML::
<route>
<from uri="direct:get"/>
<log message="get.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>get</constant>
</setHeader>
<to uri="hazelcast-replicatedmap:foo"/>
@@ -117,8 +119,10 @@ YAML::
uri: direct:get
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: get
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: get
- to:
uri: hazelcast-replicatedmap:foo
- to:
@@ -146,7 +150,7 @@ XML::
<route>
<from uri="direct:delete"/>
<log message="delete.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>delete</constant>
</setHeader>
<to uri="hazelcast-replicatedmap:foo"/>
@@ -162,8 +166,10 @@ YAML::
uri: direct:delete
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: delete
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: delete
- to:
uri: hazelcast-replicatedmap:foo
----
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-ringbuffer-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-ringbuffer-component.adoc
index 78f437bbefac..d98b7f6650e7 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-ringbuffer-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-ringbuffer-component.adoc
@@ -55,7 +55,7 @@ XML::
<route>
<from uri="direct:put"/>
<log message="put.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>add</constant>
</setHeader>
<to uri="hazelcast-ringbuffer:foo"/>
@@ -71,8 +71,10 @@ YAML::
uri: direct:put
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: add
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: add
- to:
uri: hazelcast-ringbuffer:foo
----
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-set-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-set-component.adoc
index d1307dc3bc3c..892a3638b0ae 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-set-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hazelcast-set-component.adoc
@@ -37,7 +37,7 @@ The set producer provides seven operations:
The operation comes from the `CamelHazelcastOperationType` header, or from the
`defaultOperation` option when the
header is not set. `add` and `removeValue` take the item from the message
body, and `addAll`, `removeAll` and
-`retainAll` take a collection. `getAll` sets the set itself as the message
body:
+`retainAll` take a collection. `getAll` sets a copy of the items of the set as
the message body:
[source,yaml]
----
diff --git
a/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/list/hazelcast-list.json
b/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/list/hazelcast-list.json
index 3b3134981753..683c433e3ec6 100644
---
a/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/list/hazelcast-list.json
+++
b/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/list/hazelcast-list.json
@@ -42,7 +42,7 @@
"bodyTypes": {
"consumerOut": { "carriers": [ "pojo" ], "javaType":
"com.hazelcast.collection.ItemEvent", "description": "The Hazelcast ItemEvent
of an item added to or removed from the list, not the item: ${body.item} is the
item, and the CamelHazelcastListenerAction header is added or removed" },
"producerIn": { "carriers": [ "text", "bytes", "file", "value", "map",
"list", "pojo" ], "description": "The item that add and setValue store, at the
index in the CamelHazelcastObjectIndex header when set, and that removeValue
removes when the header is not set: an object Hazelcast can serialize, so a
stream or no body fails. A Collection for addAll, removeAll and retainAll. The
other operations do not use the body" },
- "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option":
"defaultOperation", "value": "add", "carriers": [ "unchanged" ] }, { "option":
"defaultOperation", "value": "setValue", "carriers": [ "unchanged" ] }, {
"option": "defaultOperation", "value": "removeValue", "carriers": [ "unchanged"
] }, { "option": "defaultOperation", "value": "clear", "carriers": [
"unchanged" ] }, { "option": "defaultOperation", "value": "addAll", "carriers":
[ "unchanged" ] }, { "option": "defa [...]
+ "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option":
"defaultOperation", "value": "add", "carriers": [ "unchanged" ] }, { "option":
"defaultOperation", "value": "setValue", "carriers": [ "unchanged" ] }, {
"option": "defaultOperation", "value": "removeValue", "carriers": [ "unchanged"
] }, { "option": "defaultOperation", "value": "clear", "carriers": [
"unchanged" ] }, { "option": "defaultOperation", "value": "addAll", "carriers":
[ "unchanged" ] }, { "option": "defa [...]
},
"properties": {
"cacheName": { "index": 0, "kind": "path", "displayName": "Cache Name",
"group": "common", "label": "", "required": true, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The name of the cache" },
diff --git
a/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/map/hazelcast-map.json
b/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/map/hazelcast-map.json
index 776191f1c24c..17c3a4840618 100644
---
a/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/map/hazelcast-map.json
+++
b/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/map/hazelcast-map.json
@@ -43,7 +43,7 @@
"CamelHazelcastOperationType": { "index": 9, "kind": "header",
"displayName": "", "group": "producer", "label": "producer", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The operation to perform",
"constantName":
"org.apache.camel.component.hazelcast.HazelcastConstants#OPERATION" }
},
"bodyTypes": {
- "consumerOut": { "carriers": [ "unknown" ], "description": "The value of
the entry for an added or updated event, as any member of the cluster stored
it, and no body for removed and evicted: the key is in the
CamelHazelcastObjectId header and the event in CamelHazelcastListenerAction" },
+ "consumerOut": { "carriers": [ "unknown" ], "description": "The value of
the entry for an added or updated event, as any member of the cluster stored
it, and no body for removed, evicted and expired (the time to live of the entry
ended): the key is in the CamelHazelcastObjectId header and the event in
CamelHazelcastListenerAction" },
"producerIn": { "carriers": [ "text", "bytes", "file", "value", "map",
"list", "pojo" ], "description": "The value that put, putIfAbsent and update
store under the key in the CamelHazelcastObjectId header, and that
containsValue looks for: an object Hazelcast can serialize, so a stream fails
(convert it to bytes or text first), and no body fails. The other operations do
not use the body" },
"producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option":
"defaultOperation", "value": "put", "carriers": [ "unchanged" ] }, { "option":
"defaultOperation", "value": "putIfAbsent", "carriers": [ "unchanged" ] }, {
"option": "defaultOperation", "value": "update", "carriers": [ "unchanged" ] },
{ "option": "defaultOperation", "value": "delete", "carriers": [ "unchanged" ]
}, { "option": "defaultOperation", "value": "evict", "carriers": [ "unchanged"
] }, { "option": "defaul [...]
},
diff --git
a/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/pncounter/hazelcast-pncounter.json
b/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/pncounter/hazelcast-pncounter.json
index 68cdfc8f833a..44f041e8dfda 100644
---
a/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/pncounter/hazelcast-pncounter.json
+++
b/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/pncounter/hazelcast-pncounter.json
@@ -29,6 +29,9 @@
"hazelcastInstance": { "index": 2, "kind": "property", "displayName":
"Hazelcast Instance", "group": "advanced", "label": "advanced", "required":
false, "type": "object", "javaType": "com.hazelcast.core.HazelcastInstance",
"deprecated": false, "autowired": false, "secret": false, "description": "The
hazelcast instance reference which can be used for hazelcast endpoint. If you
don't specify the instance reference, camel use the default hazelcast instance
from the camel-hazelcast insta [...]
"hazelcastMode": { "index": 3, "kind": "property", "displayName":
"Hazelcast Mode", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": "node", "description":
"The hazelcast mode reference which kind of instance should be used. If you
don't specify the mode, then the node mode will be the default." }
},
+ "headers": {
+ "CamelHazelcastOperationType": { "index": 0, "kind": "header",
"displayName": "", "group": "producer", "label": "producer", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The operation to perform",
"constantName":
"org.apache.camel.component.hazelcast.HazelcastConstants#OPERATION" }
+ },
"bodyTypes": {
"producerIn": { "carriers": [ "any" ], "description": "Not used, except by
getAndAdd, which adds the body, a number or the text of one, to the counter: no
body fails" },
"producerOut": { "carriers": [ "value" ], "javaType": "java.lang.Long",
"byOption": [ { "option": "defaultOperation", "value": "destroy", "carriers": [
"unchanged" ] } ], "description": "The value of the counter as a Long: after
the change for increment and decrement, before it for getAndAdd, and the
current value for get; destroy keeps the body. The operation comes from the
CamelHazelcastOperationType header, or else the defaultOperation option:
without either the producer fails" }
diff --git
a/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/queue/hazelcast-queue.json
b/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/queue/hazelcast-queue.json
index 227998360619..0b8a2b4f6b6c 100644
---
a/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/queue/hazelcast-queue.json
+++
b/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/queue/hazelcast-queue.json
@@ -41,8 +41,8 @@
},
"bodyTypes": {
"consumerOut": { "carriers": [ "pojo" ], "javaType":
"com.hazelcast.collection.ItemEvent", "byOption": [ { "option":
"queueConsumerMode", "value": "poll", "carriers": [ "unknown" ] } ],
"description": "In Listen mode, the default, the Hazelcast ItemEvent of an item
added to or removed from the queue, not the item: ${body.item} is the item, and
the CamelHazelcastListenerAction header is added or removed. In Poll mode the
consumer takes the items off the queue, and the body is the item [...]
- "producerIn": { "carriers": [ "text", "bytes", "file", "value", "map",
"list", "pojo" ], "description": "The item that add, the default, put and offer
add to the queue, and that removeValue removes (without a body it removes the
head): an object Hazelcast can serialize, so a stream or no body fails. A
Collection for removeAll and retainAll. The other operations do not use the
body" },
- "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option":
"defaultOperation", "value": "poll", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "peek", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "take", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "remainingCapacity", "carriers": [ "value" ],
"javaType": "java.lang.Integer" }, { "option": "defaultOperation", "value":
"drainTo", "carriers": [ "value [...]
+ "producerIn": { "carriers": [ "text", "bytes", "file", "value", "map",
"list", "pojo" ], "description": "The item that add, the default, put and offer
add to the queue, and that removeValue removes (without a body it removes the
head): an object Hazelcast can serialize, so a stream or no body fails. A
Collection for removeAll and retainAll, and a java.util.function.Predicate for
removeIf, which fails without one. The other operations do not use the body" },
+ "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option":
"defaultOperation", "value": "poll", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "peek", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "take", "carriers": [ "unknown" ] }, { "option":
"defaultOperation", "value": "remainingCapacity", "carriers": [ "value" ],
"javaType": "java.lang.Integer" }, { "option": "defaultOperation", "value":
"drainTo", "carriers": [ "value [...]
},
"properties": {
"cacheName": { "index": 0, "kind": "path", "displayName": "Cache Name",
"group": "common", "label": "", "required": true, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The name of the cache" },
diff --git
a/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/set/hazelcast-set.json
b/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/set/hazelcast-set.json
index 8beaf30aa2b3..63cf22d3932b 100644
---
a/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/set/hazelcast-set.json
+++
b/components/camel-hazelcast/src/generated/resources/META-INF/org/apache/camel/component/hazelcast/set/hazelcast-set.json
@@ -41,7 +41,7 @@
"bodyTypes": {
"consumerOut": { "carriers": [ "pojo" ], "javaType":
"com.hazelcast.collection.ItemEvent", "description": "The Hazelcast ItemEvent
of an item added to or removed from the set, not the item: ${body.item} is the
item, and the CamelHazelcastListenerAction header is added or removed" },
"producerIn": { "carriers": [ "text", "bytes", "file", "value", "map",
"list", "pojo" ], "description": "The item that add adds and removeValue
removes: an object Hazelcast can serialize, so a stream or no body fails. A
Collection for addAll, removeAll and retainAll. clear and getAll do not use the
body" },
- "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option":
"defaultOperation", "value": "getAll", "carriers": [ "list" ] } ],
"description": "The operations that change the set keep the body. getAll gives
the Hazelcast set itself: a live distributed Set, not a copy. The operation
comes from the CamelHazelcastOperationType header, or else the defaultOperation
option: without either the producer fails" }
+ "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option":
"defaultOperation", "value": "getAll", "carriers": [ "list" ] } ],
"description": "The operations that change the set keep the body. getAll gives
a copy of the items of the set as a Set. The operation comes from the
CamelHazelcastOperationType header, or else the defaultOperation option:
without either the producer fails" }
},
"properties": {
"cacheName": { "index": 0, "kind": "path", "displayName": "Cache Name",
"group": "common", "label": "", "required": true, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The name of the cache" },
diff --git
a/components/camel-hazelcast/src/main/docs/hazelcast-list-component.adoc
b/components/camel-hazelcast/src/main/docs/hazelcast-list-component.adoc
index 319ad2d3fa25..9f8a86fa1263 100644
--- a/components/camel-hazelcast/src/main/docs/hazelcast-list-component.adoc
+++ b/components/camel-hazelcast/src/main/docs/hazelcast-list-component.adoc
@@ -211,7 +211,8 @@ YAML::
====
Note that *CamelHazelcastObjectIndex* header is used for indexing
-purpose.
+purpose. The *get* operation needs it: without the header the producer fails.
+The *getAll* operation sets a copy of the items of the list as the message
body.
== List consumer – from(“hazelcast-list:foo”)
diff --git
a/components/camel-hazelcast/src/main/docs/hazelcast-map-component.adoc
b/components/camel-hazelcast/src/main/docs/hazelcast-map-component.adoc
index c0045187a6b7..2cc99093e4fa 100644
--- a/components/camel-hazelcast/src/main/docs/hazelcast-map-component.adoc
+++ b/components/camel-hazelcast/src/main/docs/hazelcast-map-component.adoc
@@ -344,10 +344,10 @@ template.sendBodyAndHeader("direct:query", null,
"CamelHazelcastQuery", q1);
Hazelcast provides event listeners on their data grid. If you want to be
notified if a cache is manipulated, you can use the map consumer.
-There are four events: *put*, *update*, *delete* and *envict*. The event
-type will be stored in the "*hazelcast.listener.action*" header
-variable. The map consumer provides some additional information inside
-these variables:
+There are five events: *added*, *updated*, *removed*, *evicted* and
+*expired* (the time to live of the entry ended). The event type is stored
+in the `CamelHazelcastListenerAction` header. The map consumer provides
+some additional information inside these variables:
Header Variables inside the response message:
@@ -359,7 +359,7 @@ Header Variables inside the response message:
|`CamelHazelcastListenerType` |`String` |the map consumer sets here
"cachelistener"
-|`CamelHazelcastListenerAction` |`String` |type of event (*added*, *updated*,
*envicted* and *removed*).
+|`CamelHazelcastListenerAction` |`String` |type of event (*added*, *updated*,
*removed*, *evicted* and *expired*).
|`CamelHazelcastObjectId` |`String` |the oid of the object
@@ -368,7 +368,7 @@ Header Variables inside the response message:
|`CamelHazelcastCacheType` |`String` |the type of the cache (e.g., map)
|=======================================================================
-The object value will be stored within *put* and *update* actions inside
+The object value will be stored within *added* and *updated* events inside
the message body.
Here's a sample:
@@ -385,9 +385,9 @@ from("hazelcast-map:foo")
.when(header("CamelHazelcastListenerAction").isEqualTo("added"))
.log("...added")
.to("mock:added")
- .when(header("CamelHazelcastListenerAction").isEqualTo("envicted"))
- .log("...envicted")
- .to("mock:envicted")
+ .when(header("CamelHazelcastListenerAction").isEqualTo("evicted"))
+ .log("...evicted")
+ .to("mock:evicted")
.when(header("CamelHazelcastListenerAction").isEqualTo("updated"))
.log("...updated")
.to("mock:updated")
@@ -412,9 +412,9 @@ XML::
<to uri="mock:added"/>
</when>
<when>
- <simple>${header.CamelHazelcastListenerAction} == 'envicted'</simple>
- <log message="...envicted"/>
- <to uri="mock:envicted"/>
+ <simple>${header.CamelHazelcastListenerAction} == 'evicted'</simple>
+ <log message="...evicted"/>
+ <to uri="mock:evicted"/>
</when>
<when>
<simple>${header.CamelHazelcastListenerAction} == 'updated'</simple>
@@ -451,12 +451,12 @@ YAML::
message: "...added"
- to:
uri: mock:added
- - simple: "${header.CamelHazelcastListenerAction} == 'envicted'"
+ - simple: "${header.CamelHazelcastListenerAction} == 'evicted'"
steps:
- log:
- message: "...envicted"
+ message: "...evicted"
- to:
- uri: mock:envicted
+ uri: mock:evicted
- simple: "${header.CamelHazelcastListenerAction} == 'updated'"
steps:
- log:
diff --git
a/components/camel-hazelcast/src/main/docs/hazelcast-multimap-component.adoc
b/components/camel-hazelcast/src/main/docs/hazelcast-multimap-component.adoc
index ed2173f1bbe9..ad2527ca5af3 100644
--- a/components/camel-hazelcast/src/main/docs/hazelcast-multimap-component.adoc
+++ b/components/camel-hazelcast/src/main/docs/hazelcast-multimap-component.adoc
@@ -61,7 +61,7 @@ XML::
<route>
<from uri="direct:put"/>
<log message="put.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>put</constant>
</setHeader>
<to uri="hazelcast-multimap:foo"/>
@@ -77,8 +77,10 @@ YAML::
uri: direct:put
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: put
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: put
- to:
uri: hazelcast-multimap:foo
----
@@ -104,7 +106,7 @@ XML::
<route>
<from uri="direct:removevalue"/>
<log message="removevalue..."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>removevalue</constant>
</setHeader>
<to uri="hazelcast-multimap:foo"/>
@@ -120,8 +122,10 @@ YAML::
uri: direct:removevalue
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: removevalue
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: removevalue
- to:
uri: hazelcast-multimap:foo
----
@@ -153,7 +157,7 @@ XML::
<route>
<from uri="direct:get"/>
<log message="get.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>get</constant>
</setHeader>
<to uri="hazelcast-multimap:foo"/>
@@ -170,8 +174,10 @@ YAML::
uri: direct:get
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: get
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: get
- to:
uri: hazelcast-multimap:foo
- to:
@@ -199,7 +205,7 @@ XML::
<route>
<from uri="direct:delete"/>
<log message="delete.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>delete</constant>
</setHeader>
<to uri="hazelcast-multimap:foo"/>
@@ -215,8 +221,10 @@ YAML::
uri: direct:delete
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: delete
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: delete
- to:
uri: hazelcast-multimap:foo
----
diff --git
a/components/camel-hazelcast/src/main/docs/hazelcast-pncounter-component.adoc
b/components/camel-hazelcast/src/main/docs/hazelcast-pncounter-component.adoc
index 129ab0d831d8..36c9aee9ca69 100644
---
a/components/camel-hazelcast/src/main/docs/hazelcast-pncounter-component.adoc
+++
b/components/camel-hazelcast/src/main/docs/hazelcast-pncounter-component.adoc
@@ -58,7 +58,7 @@ XML::
----
<route>
<from uri="direct:increment"/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>increment</constant>
</setHeader>
<to uri="hazelcast-pncounter:foo"/>
@@ -74,8 +74,10 @@ YAML::
uri: direct:increment
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: increment
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: increment
- to:
uri: hazelcast-pncounter:foo
----
@@ -102,7 +104,7 @@ XML::
----
<route>
<from uri="direct:decrement"/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>decrement</constant>
</setHeader>
<to uri="hazelcast-pncounter:foo"/>
@@ -118,8 +120,10 @@ YAML::
uri: direct:decrement
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: decrement
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: decrement
- to:
uri: hazelcast-pncounter:foo
----
@@ -146,7 +150,7 @@ XML::
----
<route>
<from uri="direct:get"/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>get</constant>
</setHeader>
<to uri="hazelcast-pncounter:foo"/>
@@ -162,8 +166,10 @@ YAML::
uri: direct:get
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: get
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: get
- to:
uri: hazelcast-pncounter:foo
----
@@ -191,7 +197,7 @@ XML::
----
<route>
<from uri="direct:getAndAdd"/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>getAndAdd</constant>
</setHeader>
<to uri="hazelcast-pncounter:foo"/>
@@ -207,8 +213,10 @@ YAML::
uri: direct:getAndAdd
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: getAndAdd
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: getAndAdd
- to:
uri: hazelcast-pncounter:foo
----
@@ -217,7 +225,7 @@ YAML::
Provide the delta value in the message body (e.g., 5 to add 5 to the counter):
`long previousValue = template.requestBody("direct:getAndAdd", 5L,
Long.class);`
-The previous value (before the add) will be returned in the message body.
+The previous value (before the add) will be returned in the message body.
Without a numeric body the producer fails.
=== Example for *destroy*:
@@ -238,7 +246,7 @@ XML::
----
<route>
<from uri="direct:destroy"/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>destroy</constant>
</setHeader>
<to uri="hazelcast-pncounter:foo"/>
@@ -254,8 +262,10 @@ YAML::
uri: direct:destroy
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: destroy
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: destroy
- to:
uri: hazelcast-pncounter:foo
----
diff --git
a/components/camel-hazelcast/src/main/docs/hazelcast-queue-component.adoc
b/components/camel-hazelcast/src/main/docs/hazelcast-queue-component.adoc
index 3c51cdb5c996..eedee2ded338 100644
--- a/components/camel-hazelcast/src/main/docs/hazelcast-queue-component.adoc
+++ b/components/camel-hazelcast/src/main/docs/hazelcast-queue-component.adoc
@@ -419,6 +419,10 @@ YAML::
----
====
+The message body is the `java.util.function.Predicate` that selects the items
to remove, and after the call the body
+is `true` when an item was removed. A Hazelcast queue cannot remove through
its iterator, so the producer tests the
+items the queue holds and then removes the matching ones in one call: the
operation is not atomic.
+
=== Example for *drain to*:
[tabs]
@@ -461,6 +465,9 @@ YAML::
----
====
+The *CamelHazelcastDrainToCollection* header must hold the `Collection` the
items are moved into: without it the
+producer fails. After the call the body is the number of items moved.
+
=== Example for *take*:
[tabs]
diff --git
a/components/camel-hazelcast/src/main/docs/hazelcast-replicatedmap-component.adoc
b/components/camel-hazelcast/src/main/docs/hazelcast-replicatedmap-component.adoc
index 4b7c941c28f0..58c6577ffd3c 100644
---
a/components/camel-hazelcast/src/main/docs/hazelcast-replicatedmap-component.adoc
+++
b/components/camel-hazelcast/src/main/docs/hazelcast-replicatedmap-component.adoc
@@ -14,7 +14,7 @@
*{component-header}*
-The http://www.hazelcast.com/[Hazelcast] instance component is one of Camel
Hazelcast Components which allows you to consume join/leave events of the cache
instance in the cluster.
+The http://www.hazelcast.com/[Hazelcast] Replicated Map component is one of
Camel Hazelcast Components which allows you to access a Hazelcast replicated
map.
A replicated map is a weakly consistent, distributed key-value data structure
with no data partition.
@@ -56,7 +56,7 @@ XML::
<route>
<from uri="direct:put"/>
<log message="put.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>put</constant>
</setHeader>
<to uri="hazelcast-replicatedmap:foo"/>
@@ -72,8 +72,10 @@ YAML::
uri: direct:put
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: put
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: put
- to:
uri: hazelcast-replicatedmap:foo
----
@@ -100,7 +102,7 @@ XML::
<route>
<from uri="direct:get"/>
<log message="get.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>get</constant>
</setHeader>
<to uri="hazelcast-replicatedmap:foo"/>
@@ -117,8 +119,10 @@ YAML::
uri: direct:get
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: get
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: get
- to:
uri: hazelcast-replicatedmap:foo
- to:
@@ -146,7 +150,7 @@ XML::
<route>
<from uri="direct:delete"/>
<log message="delete.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>delete</constant>
</setHeader>
<to uri="hazelcast-replicatedmap:foo"/>
@@ -162,8 +166,10 @@ YAML::
uri: direct:delete
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: delete
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: delete
- to:
uri: hazelcast-replicatedmap:foo
----
diff --git
a/components/camel-hazelcast/src/main/docs/hazelcast-ringbuffer-component.adoc
b/components/camel-hazelcast/src/main/docs/hazelcast-ringbuffer-component.adoc
index 78f437bbefac..d98b7f6650e7 100644
---
a/components/camel-hazelcast/src/main/docs/hazelcast-ringbuffer-component.adoc
+++
b/components/camel-hazelcast/src/main/docs/hazelcast-ringbuffer-component.adoc
@@ -55,7 +55,7 @@ XML::
<route>
<from uri="direct:put"/>
<log message="put.."/>
- <setHeader name="hazelcast.operation.type">
+ <setHeader name="CamelHazelcastOperationType">
<constant>add</constant>
</setHeader>
<to uri="hazelcast-ringbuffer:foo"/>
@@ -71,8 +71,10 @@ YAML::
uri: direct:put
steps:
- setHeader:
- name: hazelcast.operation.type
- constant: add
+ name: CamelHazelcastOperationType
+ expression:
+ constant:
+ expression: add
- to:
uri: hazelcast-ringbuffer:foo
----
diff --git
a/components/camel-hazelcast/src/main/docs/hazelcast-set-component.adoc
b/components/camel-hazelcast/src/main/docs/hazelcast-set-component.adoc
index d1307dc3bc3c..892a3638b0ae 100644
--- a/components/camel-hazelcast/src/main/docs/hazelcast-set-component.adoc
+++ b/components/camel-hazelcast/src/main/docs/hazelcast-set-component.adoc
@@ -37,7 +37,7 @@ The set producer provides seven operations:
The operation comes from the `CamelHazelcastOperationType` header, or from the
`defaultOperation` option when the
header is not set. `add` and `removeValue` take the item from the message
body, and `addAll`, `removeAll` and
-`retainAll` take a collection. `getAll` sets the set itself as the message
body:
+`retainAll` take a collection. `getAll` sets a copy of the items of the set as
the message body:
[source,yaml]
----
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/HazelcastConstants.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/HazelcastConstants.java
index 35393d5dd53b..5c666b71c81a 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/HazelcastConstants.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/HazelcastConstants.java
@@ -108,7 +108,7 @@ public final class HazelcastConstants {
@Metadata(label = "producer", description = "The operation to perform",
javaType = "String",
applicableFor = {
SCHEME_MULTIMAP, SCHEME_REPLICATED_MAP, SCHEME_LIST,
SCHEME_QUEUE, SCHEME_SET, SCHEME_MAP, SCHEME_TOPIC,
- SCHEME_RING_BUFFER })
+ SCHEME_RING_BUFFER, SCHEME_PNCOUNTER })
public static final String OPERATION = "CamelHazelcastOperationType";
/**
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/HazelcastDefaultProducer.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/HazelcastDefaultProducer.java
index d9e774bfa259..5ef1e5ceb41e 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/HazelcastDefaultProducer.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/HazelcastDefaultProducer.java
@@ -30,8 +30,13 @@ public abstract class HazelcastDefaultProducer extends
DefaultProducer {
}
protected HazelcastOperation lookupOperation(Exchange exchange) {
-
- return HazelcastComponentHelper.lookupOperation(exchange,
getEndpoint().getDefaultOperation());
-
+ HazelcastOperation operation
+ = HazelcastComponentHelper.lookupOperation(exchange,
getEndpoint().getDefaultOperation());
+ if (operation == null) {
+ throw new IllegalArgumentException(
+ "No operation to perform: set the " +
HazelcastConstants.OPERATION
+ + " header or the
defaultOperation option of the endpoint");
+ }
+ return operation;
}
}
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/list/HazelcastListEndpoint.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/list/HazelcastListEndpoint.java
index 4a2e93cd5d6e..974018aa7063 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/list/HazelcastListEndpoint.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/list/HazelcastListEndpoint.java
@@ -62,8 +62,8 @@ import static
org.apache.camel.component.hazelcast.HazelcastConstants.SCHEME_LIS
+ "sets, or else the
defaultOperation option (without either the "
+ "producer fails): the item
at the index in the "
+ "CamelHazelcastObjectIndex
header for get, which needs the "
- + "header, and the Hazelcast
list itself for getAll: a live "
- + "distributed List, not a
copy. The other operations keep the body"))
+ + "header, and a copy of the
items of the list as a List for "
+ + "getAll. The other
operations keep the body"))
public class HazelcastListEndpoint extends HazelcastDefaultEndpoint {
public HazelcastListEndpoint(HazelcastInstance hazelcastInstance, String
endpointUri, Component component,
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/list/HazelcastListProducer.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/list/HazelcastListProducer.java
index 169a9ba27d8b..7babcd42f678 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/list/HazelcastListProducer.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/list/HazelcastListProducer.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.component.hazelcast.list;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
@@ -118,6 +119,10 @@ public class HazelcastListProducer extends
HazelcastDefaultProducer {
}
private void get(Integer pos, Exchange exchange) {
+ if (pos == null) {
+ throw new IllegalArgumentException(
+ "The get operation needs the index of the item in the " +
HazelcastConstants.OBJECT_POS + " header");
+ }
exchange.getMessage().setBody(this.list.get(pos));
}
@@ -166,6 +171,7 @@ public class HazelcastListProducer extends
HazelcastDefaultProducer {
}
private void getAll(Exchange exchange) {
- exchange.getMessage().setBody(list);
+ // a copy: the list itself is a proxy of the distributed list, which
later steps would read and change
+ exchange.getMessage().setBody(new ArrayList<>(list));
}
}
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/listener/CamelMapListener.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/listener/CamelMapListener.java
index 9eeccfd6cea0..7490613a17c6 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/listener/CamelMapListener.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/listener/CamelMapListener.java
@@ -40,6 +40,11 @@ public class CamelMapListener extends CamelListener
implements MapEntryListener<
this.sendExchange(HazelcastConstants.EVICTED, event.getKey(),
event.getValue());
}
+ @Override
+ public void entryExpired(EntryEvent<Object, Object> event) {
+ this.sendExchange(HazelcastConstants.EXPIRED, event.getKey(),
event.getValue());
+ }
+
@Override
public void entryMerged(EntryEvent<Object, Object> event) {
// noop
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/listener/MapEntryListener.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/listener/MapEntryListener.java
index d204449aabd5..df9ae2739421 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/listener/MapEntryListener.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/listener/MapEntryListener.java
@@ -18,6 +18,7 @@ package org.apache.camel.component.hazelcast.listener;
import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.map.listener.EntryEvictedListener;
+import com.hazelcast.map.listener.EntryExpiredListener;
import com.hazelcast.map.listener.EntryMergedListener;
import com.hazelcast.map.listener.EntryRemovedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
@@ -26,6 +27,6 @@ import com.hazelcast.map.listener.MapEvictedListener;
public interface MapEntryListener<K, V>
extends MapClearedListener, MapEvictedListener,
- EntryAddedListener<K, V>, EntryEvictedListener<K, V>,
EntryRemovedListener<K, V>,
+ EntryAddedListener<K, V>, EntryEvictedListener<K, V>,
EntryExpiredListener<K, V>, EntryRemovedListener<K, V>,
EntryMergedListener<K, V>, EntryUpdatedListener<K, V> {
}
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/map/HazelcastMapEndpoint.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/map/HazelcastMapEndpoint.java
index ab2f4abd3e56..091cff76b650 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/map/HazelcastMapEndpoint.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/map/HazelcastMapEndpoint.java
@@ -39,9 +39,10 @@ import static
org.apache.camel.component.hazelcast.HazelcastConstants.SCHEME_MAP
category = { Category.CACHE, Category.CLUSTERING }, headersClass
= HazelcastConstants.class)
@BodyTypes(consumerOut = @BodyType(value = Carrier.UNKNOWN,
description = "The value of the entry for
an added or updated event, as any "
- + "member of the cluster
stored it, and no body for removed and "
- + "evicted: the key is in the
CamelHazelcastObjectId header and the "
- + "event in
CamelHazelcastListenerAction"),
+ + "member of the cluster
stored it, and no body for removed, evicted "
+ + "and expired (the time to
live of the entry ended): the key is in "
+ + "the CamelHazelcastObjectId
header and the event in "
+ +
"CamelHazelcastListenerAction"),
producerIn = @BodyType(value = {
Carrier.TEXT, Carrier.BYTES, Carrier.FILE, Carrier.VALUE,
Carrier.MAP, Carrier.LIST, Carrier.POJO },
description = "The value that put,
putIfAbsent and update store under the key "
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/pncounter/HazelcastPNCounterProducer.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/pncounter/HazelcastPNCounterProducer.java
index 9840218f054d..a85ec99c6409 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/pncounter/HazelcastPNCounterProducer.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/pncounter/HazelcastPNCounterProducer.java
@@ -85,7 +85,11 @@ public class HazelcastPNCounterProducer extends
HazelcastDefaultProducer {
}
private void getAndAdd(Exchange exchange) {
- long delta = exchange.getIn().getBody(Long.class);
+ Long delta = exchange.getIn().getBody(Long.class);
+ if (delta == null) {
+ throw new IllegalArgumentException(
+ "The getAndAdd operation needs a numeric body: the number
to add to the counter");
+ }
exchange.getMessage().setBody(this.pnCounter.getAndAdd(delta));
}
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/queue/HazelcastQueueEndpoint.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/queue/HazelcastQueueEndpoint.java
index bc5431e2de90..2a1804993167 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/queue/HazelcastQueueEndpoint.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/queue/HazelcastQueueEndpoint.java
@@ -54,8 +54,9 @@ import static
org.apache.camel.component.hazelcast.HazelcastConstants.SCHEME_QUE
description = "The item that add, the
default, put and offer add to the queue, "
+ "and that removeValue
removes (without a body it removes the "
+ "head): an object Hazelcast
can serialize, so a stream or no body "
- + "fails. A Collection for
removeAll and retainAll. The other "
- + "operations do not use the
body"),
+ + "fails. A Collection for
removeAll and retainAll, and a "
+ +
"java.util.function.Predicate for removeIf, which fails without "
+ + "one. The other operations
do not use the body"),
producerOut = @BodyType(value = Carrier.UNCHANGED, byOption = {
@BodyType.When(option = "defaultOperation", value = "poll",
carriers = Carrier.UNKNOWN),
@BodyType.When(option = "defaultOperation", value = "peek",
carriers = Carrier.UNKNOWN),
@@ -63,13 +64,16 @@ import static
org.apache.camel.component.hazelcast.HazelcastConstants.SCHEME_QUE
@BodyType.When(option = "defaultOperation", value =
"remainingCapacity", carriers = Carrier.VALUE,
javaType = "java.lang.Integer"),
@BodyType.When(option = "defaultOperation", value =
"drainTo", carriers = Carrier.VALUE,
- javaType = "java.lang.Integer") },
+ javaType = "java.lang.Integer"),
+ @BodyType.When(option = "defaultOperation", value =
"removeIf", carriers = Carrier.VALUE,
+ javaType = "java.lang.Boolean") },
description = "Unchanged for add, the
default, and the other operations that "
+ "change the queue. poll and
peek give the head of the queue, or "
+ "null when it is empty, and
take waits for one; remainingCapacity "
+ "gives an Integer, and
drainTo the number of items it moved into "
- + "the Collection of the
CamelHazelcastDrainToCollection header. "
- + "The
CamelHazelcastOperationType header overrides the "
+ + "the Collection of the
CamelHazelcastDrainToCollection header, "
+ + "which it needs. removeIf
gives a Boolean, true when it removed "
+ + "an item. The
CamelHazelcastOperationType header overrides the "
+ "defaultOperation option"))
public class HazelcastQueueEndpoint extends HazelcastDefaultEndpoint {
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/queue/HazelcastQueueProducer.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/queue/HazelcastQueueProducer.java
index 606925799e6a..20a5a8bcfb72 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/queue/HazelcastQueueProducer.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/queue/HazelcastQueueProducer.java
@@ -16,7 +16,9 @@
*/
package org.apache.camel.component.hazelcast.queue;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
@@ -94,7 +96,7 @@ public class HazelcastQueueProducer extends
HazelcastDefaultProducer {
break;
case DRAIN_TO:
- this.drainTo((Collection<?>) drainToCollection, exchange);
+ this.drainTo(drainToCollection, exchange);
break;
case TAKE:
@@ -152,8 +154,14 @@ public class HazelcastQueueProducer extends
HazelcastDefaultProducer {
exchange.getMessage().setBody(this.queue.remainingCapacity());
}
- private void drainTo(Collection c, Exchange exchange) {
- exchange.getMessage().setBody(this.queue.drainTo(c));
+ @SuppressWarnings("unchecked")
+ private void drainTo(Object drainToCollection, Exchange exchange) {
+ if (!(drainToCollection instanceof Collection<?> c)) {
+ throw new IllegalArgumentException(
+ "The drainTo operation needs the Collection to move the
items into in the "
+ +
HazelcastConstants.DRAIN_TO_COLLECTION + " header");
+ }
+ exchange.getMessage().setBody(this.queue.drainTo((Collection<Object>)
c));
exchange.getMessage().setHeader(HazelcastConstants.DRAIN_TO_COLLECTION, c);
}
@@ -162,9 +170,21 @@ public class HazelcastQueueProducer extends
HazelcastDefaultProducer {
this.queue.removeAll(body);
}
+ @SuppressWarnings("unchecked")
private void removeIf(Exchange exchange) {
- Predicate filter = exchange.getIn().getBody(Predicate.class);
- exchange.getMessage().setBody(this.queue.removeIf(filter));
+ Predicate<Object> filter = exchange.getIn().getBody(Predicate.class);
+ if (filter == null) {
+ throw new IllegalArgumentException("The removeIf operation needs a
java.util.function.Predicate as the body");
+ }
+ // Collection.removeIf removes through the iterator, which a Hazelcast
queue does not support: test the items
+ // the queue holds now, then remove the matching ones in one call (so
not atomic)
+ List<Object> matching = new ArrayList<>();
+ for (Object item : queue) {
+ if (filter.test(item)) {
+ matching.add(item);
+ }
+ }
+ exchange.getMessage().setBody(!matching.isEmpty() &&
this.queue.removeAll(matching));
}
private void take(Exchange exchange) throws InterruptedException {
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/seda/HazelcastSedaProducer.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/seda/HazelcastSedaProducer.java
index 9214b8b4fc9a..4b32f5a2c4e2 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/seda/HazelcastSedaProducer.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/seda/HazelcastSedaProducer.java
@@ -59,6 +59,14 @@ public class HazelcastSedaProducer extends
DefaultAsyncProducer {
// in case body is not serializable convert to byte array
if (!(body instanceof Serializable)) {
obj = exchange.getIn().getBody(byte[].class);
+ if (obj == null) {
+ // a Hazelcast queue does not take a null item
+ throw new IllegalArgumentException(
+ body == null
+ ? "The message has no body to put on the
Hazelcast queue"
+ : "The body must be Serializable or
convertible to bytes to be put on the Hazelcast queue,"
+ + " but it is a " +
body.getClass().getName());
+ }
} else {
obj = body;
}
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/set/HazelcastSetEndpoint.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/set/HazelcastSetEndpoint.java
index c39e9a3fdb2f..2c140c0e5720 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/set/HazelcastSetEndpoint.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/set/HazelcastSetEndpoint.java
@@ -50,7 +50,7 @@ import static
org.apache.camel.component.hazelcast.HazelcastConstants.SCHEME_SET
producerOut = @BodyType(value = Carrier.UNCHANGED, byOption = {
@BodyType.When(option = "defaultOperation", value =
"getAll", carriers = Carrier.LIST) },
description = "The operations that change
the set keep the body. getAll gives "
- + "the Hazelcast set itself:
a live distributed Set, not a copy. "
+ + "a copy of the items of the
set as a Set. "
+ "The operation comes from
the CamelHazelcastOperationType header, "
+ "or else the
defaultOperation option: without either the producer "
+ "fails"))
diff --git
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/set/HazelcastSetProducer.java
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/set/HazelcastSetProducer.java
index b33bc5e58b08..10fe693558a9 100644
---
a/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/set/HazelcastSetProducer.java
+++
b/components/camel-hazelcast/src/main/java/org/apache/camel/component/hazelcast/set/HazelcastSetProducer.java
@@ -17,6 +17,7 @@
package org.apache.camel.component.hazelcast.set;
import java.util.Collection;
+import java.util.LinkedHashSet;
import com.hazelcast.collection.ISet;
import com.hazelcast.core.HazelcastInstance;
@@ -115,6 +116,7 @@ public class HazelcastSetProducer extends
HazelcastDefaultProducer {
}
private void getAll(Exchange exchange) {
- exchange.getMessage().setBody(set);
+ // a copy: the set itself is a proxy of the distributed set, which
later steps would read and change
+ exchange.getMessage().setBody(new LinkedHashSet<>(set));
}
}
diff --git
a/components/camel-hazelcast/src/test/java/org/apache/camel/component/hazelcast/HazelcastMapConsumerExpiredTest.java
b/components/camel-hazelcast/src/test/java/org/apache/camel/component/hazelcast/HazelcastMapConsumerExpiredTest.java
new file mode 100644
index 000000000000..9f24c9fb2ed9
--- /dev/null
+++
b/components/camel-hazelcast/src/test/java/org/apache/camel/component/hazelcast/HazelcastMapConsumerExpiredTest.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.hazelcast;
+
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The map consumer against a Hazelcast member: an entry whose time to live
ends gives an expired event.
+ */
+class HazelcastMapConsumerExpiredTest extends CamelTestSupport {
+
+ private HazelcastInstance member;
+
+ @Override
+ protected CamelContext createCamelContext() throws Exception {
+ Config config = new Config();
+ config.setClusterName("map-expired-" + UUID.randomUUID());
+ config.getMetricsConfig().setEnabled(false);
+
config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
+
config.getNetworkConfig().getJoin().getAutoDetectionConfig().setEnabled(false);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(false);
+ // look for expired entries every second rather than every five
+
config.setProperty("hazelcast.internal.map.expiration.task.period.seconds",
"1");
+ member = Hazelcast.newHazelcastInstance(config);
+
+ CamelContext context = super.createCamelContext();
+ HazelcastCamelTestHelper.registerHazelcastComponents(context, member);
+ return context;
+ }
+
+ @AfterEach
+ void stopMember() {
+ // stop the route before the member, so the consumer removes its
listener from a running member
+ context.stop();
+ if (member != null) {
+ member.shutdown();
+ }
+ }
+
+ @Test
+ void entryWhoseTimeToLiveEndsGivesAnExpiredEvent() throws Exception {
+ MockEndpoint added = getMockEndpoint("mock:added");
+ added.expectedMessageCount(1);
+ added.expectedHeaderReceived(HazelcastConstants.OBJECT_ID, "4711");
+ MockEndpoint expired = getMockEndpoint("mock:expired");
+ expired.expectedMessageCount(1);
+ expired.expectedHeaderReceived(HazelcastConstants.OBJECT_ID, "4711");
+ expired.expectedHeaderReceived(HazelcastConstants.LISTENER_TYPE,
HazelcastConstants.CACHE_LISTENER);
+
+ member.getMap("expiring").put("4711", "my-foo", 1, TimeUnit.SECONDS);
+
+ MockEndpoint.assertIsSatisfied(context, 30, TimeUnit.SECONDS);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("hazelcast-map:expiring")
+ .choice()
+
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED))
+ .to("mock:added")
+
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.EXPIRED))
+ .to("mock:expired")
+ .otherwise()
+ .to("mock:other");
+ }
+ };
+ }
+}
diff --git
a/components/camel-hazelcast/src/test/java/org/apache/camel/component/hazelcast/HazelcastProducerChecksTest.java
b/components/camel-hazelcast/src/test/java/org/apache/camel/component/hazelcast/HazelcastProducerChecksTest.java
new file mode 100644
index 000000000000..3abf82d35f1c
--- /dev/null
+++
b/components/camel-hazelcast/src/test/java/org/apache/camel/component/hazelcast/HazelcastProducerChecksTest.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.hazelcast;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.function.Predicate;
+
+import com.hazelcast.collection.IList;
+import com.hazelcast.collection.IQueue;
+import com.hazelcast.collection.ISet;
+import com.hazelcast.config.Config;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The producers against a Hazelcast member: a missing operation, header or
body fails with a message that names what is
+ * missing, getAll gives a copy of the list or set, and removeIf works on a
Hazelcast queue.
+ */
+class HazelcastProducerChecksTest extends CamelTestSupport {
+
+ private static HazelcastInstance member;
+
+ @BeforeAll
+ static void startMember() {
+ Config config = new Config();
+ config.setClusterName("producer-checks-" + UUID.randomUUID());
+ config.getMetricsConfig().setEnabled(false);
+
config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
+
config.getNetworkConfig().getJoin().getAutoDetectionConfig().setEnabled(false);
+ config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(false);
+ member = Hazelcast.newHazelcastInstance(config);
+ }
+
+ @AfterAll
+ static void stopMember() {
+ if (member != null) {
+ member.shutdown();
+ }
+ }
+
+ @Override
+ protected CamelContext createCamelContext() throws Exception {
+ CamelContext context = super.createCamelContext();
+ HazelcastCamelTestHelper.registerHazelcastComponents(context, member);
+ return context;
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = { "map", "multimap", "replicatedmap", "list",
"set", "ringbuffer", "pncounter" })
+ void noOperationNamesTheHeaderAndTheOption(String type) {
+ IllegalArgumentException e = failure(() ->
template.sendBody("hazelcast-" + type + ":no-operation", "a"));
+ assertTrue(e.getMessage().contains(HazelcastConstants.OPERATION),
e.getMessage());
+ assertTrue(e.getMessage().contains("defaultOperation"),
e.getMessage());
+ }
+
+ @Test
+ void listGetWithoutIndexNamesTheHeader() {
+ member.getList("get-without-index").add("a");
+
+ IllegalArgumentException e = failure(() ->
template.sendBodyAndHeader("hazelcast-list:get-without-index", null,
+ HazelcastConstants.OPERATION, HazelcastOperation.GET));
+ assertTrue(e.getMessage().contains(HazelcastConstants.OBJECT_POS),
e.getMessage());
+ }
+
+ @Test
+ void listGetAllGivesACopy() {
+ IList<Object> list = member.getList("get-all");
+ list.add("a");
+
+ List<?> body = template.requestBodyAndHeader("hazelcast-list:get-all",
null, HazelcastConstants.OPERATION,
+ HazelcastOperation.GET_ALL, List.class);
+ assertFalse(body instanceof IList, "the body is the distributed list
itself");
+
+ // a change of the distributed list does not show in the body, and the
reverse
+ list.add("b");
+ assertEquals(List.of("a"), body);
+ ((List<Object>) body).add("c");
+ assertEquals(List.of("a", "b"), new ArrayList<>(list));
+ }
+
+ @Test
+ void setGetAllGivesACopy() {
+ ISet<Object> set = member.getSet("get-all");
+ set.add("a");
+
+ Set<?> body = template.requestBodyAndHeader("hazelcast-set:get-all",
null, HazelcastConstants.OPERATION,
+ HazelcastOperation.GET_ALL, Set.class);
+ assertFalse(body instanceof ISet, "the body is the distributed set
itself");
+
+ // a change of the distributed set does not show in the body, and the
reverse
+ set.add("b");
+ assertEquals(Set.of("a"), body);
+ ((Set<Object>) body).add("c");
+ assertEquals(Set.of("a", "b"), Set.copyOf(set));
+ }
+
+ @Test
+ void queueRemoveIfRemovesTheMatchingItems() {
+ IQueue<Object> queue = member.getQueue("remove-if");
+ queue.addAll(List.of("a", "bb", "ccc", "dd", "bb"));
+
+ Predicate<Object> twoLetters = item -> item.toString().length() == 2;
+ Boolean removed =
template.requestBodyAndHeader("hazelcast-queue:remove-if", twoLetters,
+ HazelcastConstants.OPERATION, HazelcastOperation.REMOVE_IF,
Boolean.class);
+ assertTrue(removed);
+ assertEquals(List.of("a", "ccc"), new ArrayList<>(queue));
+
+ // nothing matches any more
+ removed = template.requestBodyAndHeader("hazelcast-queue:remove-if",
twoLetters,
+ HazelcastConstants.OPERATION, HazelcastOperation.REMOVE_IF,
Boolean.class);
+ assertFalse(removed);
+ assertEquals(List.of("a", "ccc"), new ArrayList<>(queue));
+ }
+
+ @Test
+ void queueRemoveIfWithoutPredicateSaysSo() {
+ IQueue<Object> queue = member.getQueue("remove-if-without-predicate");
+ queue.add("a");
+
+ IllegalArgumentException e = failure(() ->
template.sendBodyAndHeader("hazelcast-queue:remove-if-without-predicate",
+ null, HazelcastConstants.OPERATION,
HazelcastOperation.REMOVE_IF));
+ assertTrue(e.getMessage().contains("Predicate"), e.getMessage());
+ assertEquals(1, queue.size());
+ }
+
+ @Test
+ void queueDrainToWithoutCollectionNamesTheHeader() {
+ IQueue<Object> queue = member.getQueue("drain-to-without-collection");
+ queue.add("a");
+
+ IllegalArgumentException e = failure(() ->
template.sendBodyAndHeader("hazelcast-queue:drain-to-without-collection",
+ null, HazelcastConstants.OPERATION,
HazelcastOperation.DRAIN_TO));
+
assertTrue(e.getMessage().contains(HazelcastConstants.DRAIN_TO_COLLECTION),
e.getMessage());
+ // no item was taken from the queue
+ assertEquals(1, queue.size());
+ }
+
+ @Test
+ void pnCounterGetAndAddWithoutBodySaysSo() {
+ IllegalArgumentException e = failure(() ->
template.sendBodyAndHeader("hazelcast-pncounter:get-and-add", null,
+ HazelcastConstants.OPERATION, HazelcastOperation.GET_AND_ADD));
+ assertTrue(e.getMessage().contains("numeric body"), e.getMessage());
+ assertEquals(0, member.getPNCounter("get-and-add").get());
+ }
+
+ @Test
+ void sedaBodyNeitherSerializableNorBytesSaysSo() {
+ IllegalArgumentException e = failure(() ->
template.sendBody("hazelcast-seda:not-serializable", new NotSerializable()));
+ assertTrue(e.getMessage().contains("Serializable or convertible to
bytes"), e.getMessage());
+ assertTrue(e.getMessage().contains(NotSerializable.class.getName()),
e.getMessage());
+ assertEquals(0, member.getQueue("not-serializable").size());
+ }
+
+ @Test
+ void sedaWithoutBodySaysSo() {
+ IllegalArgumentException e = failure(() ->
template.sendBody("hazelcast-seda:no-body", null));
+ assertTrue(e.getMessage().contains("no body"), e.getMessage());
+ assertEquals(0, member.getQueue("no-body").size());
+ }
+
+ private static IllegalArgumentException failure(Runnable send) {
+ CamelExecutionException e =
assertThrows(CamelExecutionException.class, send::run);
+ return assertInstanceOf(IllegalArgumentException.class, e.getCause());
+ }
+
+ /**
+ * A body that is not Serializable and that no type converter turns into
bytes.
+ */
+ private static final class NotSerializable {
+ }
+}
diff --git
a/components/camel-hazelcast/src/test/java/org/apache/camel/component/hazelcast/HazelcastQueueProducerTest.java
b/components/camel-hazelcast/src/test/java/org/apache/camel/component/hazelcast/HazelcastQueueProducerTest.java
index d9d8928bf0c6..341b411f6967 100644
---
a/components/camel-hazelcast/src/test/java/org/apache/camel/component/hazelcast/HazelcastQueueProducerTest.java
+++
b/components/camel-hazelcast/src/test/java/org/apache/camel/component/hazelcast/HazelcastQueueProducerTest.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
@@ -31,6 +32,7 @@ import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -138,9 +140,14 @@ public class HazelcastQueueProducerTest extends
HazelcastCamelTestSupport {
@Test
public void removeIf() throws InterruptedException {
+ // a Hazelcast queue cannot remove through its iterator: the producer
tests the items and removes the matching ones
+ when(queue.iterator()).thenReturn(List.of("short", "longer
one").iterator());
+ when(queue.removeAll(List.of("longer one"))).thenReturn(true);
Predicate<String> i = s -> s.length() > 5;
- template.sendBody("direct:removeIf", i);
- verify(queue).removeIf(i);
+ boolean removed = template.requestBody("direct:removeIf", i,
Boolean.class);
+ verify(queue).iterator();
+ verify(queue).removeAll(List.of("longer one"));
+ assertTrue(removed);
}
@Test
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index fcde13086ce7..95a84ce3a204 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -4899,6 +4899,31 @@ message that suggests `responseFormat=b64_json`. Before,
it gave the bytes of th
`.to("spring-ai-image:gen").to("file:out?fileName=image.png")` wrote the URL
into the `.png` file. The conversion to
`String` still gives the URL.
+=== camel-hazelcast - getAll copies, map expired events, queue removeIf and
clear errors
+
+The `getAll` operation of `hazelcast-list` and `hazelcast-set` now sets a copy
of the items as the message body (a
+`java.util.ArrayList` and a `java.util.LinkedHashSet`) instead of the
distributed list or set itself. A later change of
+the body no longer changes the distributed collection, and the body no longer
shows the changes made to it afterwards.
+
+The `hazelcast-map` consumer now also routes an event when the time to live of
an entry ends: the
+`CamelHazelcastListenerAction` header is `expired`, the key is in the
`CamelHazelcastObjectId` header, and there is no
+body, as for `evicted`. Before, such an entry gave no event. A route that
sends an unknown event to an error path must
+handle `expired`.
+
+The `removeIf` operation of `hazelcast-queue` now works: it tests the items of
the queue with the
+`java.util.function.Predicate` of the body, removes the matching ones, and
sets the body to `true` when it removed an
+item. Before, it always failed with an `UnsupportedOperationException`. The
operation is not atomic: the items are read
+first, and the matching ones removed in one call afterwards.
+
+The following now fail with an `IllegalArgumentException` that names what is
missing, where they failed with a
+`NullPointerException` before: a producer of `hazelcast-map`,
`hazelcast-multimap`, `hazelcast-replicatedmap`,
+`hazelcast-list`, `hazelcast-set`, `hazelcast-ringbuffer` or
`hazelcast-pncounter` with neither the
+`CamelHazelcastOperationType` header nor the `defaultOperation` option, `get`
on `hazelcast-list` without the
+`CamelHazelcastObjectIndex` header, `drainTo` on `hazelcast-queue` without a
`Collection` in the
+`CamelHazelcastDrainToCollection` header (a value that is not a `Collection`
failed with a `ClassCastException`),
+`removeIf` without a `Predicate` body, `getAndAdd` on `hazelcast-pncounter`
without a numeric body, and a
+`hazelcast-seda` producer with no body or a body that is neither
`Serializable` nor convertible to bytes.
+
=== camel-spring-redis - commands the producer does not run fail, and a read
that finds nothing gives no body
The `spring-redis` producer now fails the exchange for a `CamelRedis.Command`
it does not run. Previously these did
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointHeaderBuilders.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointHeaderBuilders.java
index f6f86af1cf76..d2719e0d3548 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointHeaderBuilders.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointHeaderBuilders.java
@@ -1829,6 +1829,20 @@ public class EndpointHeaderBuilders {
public static
HazelcastMultimapEndpointBuilderFactory.HazelcastMultimapHeaderNameBuilder
hazelcastMultimap() {
return
HazelcastMultimapEndpointBuilderFactory.HazelcastMultimapHeaderNameBuilder.INSTANCE;
}
+ /**
+ * Hazelcast PN Counter (camel-hazelcast)
+ * Increment, decrement, get, etc. operations on a Hazelcast PN Counter
+ * (CRDT counter).
+ *
+ * Category: cache,clustering
+ * Since: 4.19
+ * Maven coordinates: org.apache.camel:camel-hazelcast
+ *
+ * @return the dsl builder for the headers' name.
+ */
+ public static
HazelcastPNCounterEndpointBuilderFactory.HazelcastPNCounterHeaderNameBuilder
hazelcastPncounter() {
+ return
HazelcastPNCounterEndpointBuilderFactory.HazelcastPNCounterHeaderNameBuilder.INSTANCE;
+ }
/**
* Hazelcast Queue (camel-hazelcast)
* Perform operations on Hazelcast distributed queue.
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/HazelcastPNCounterEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/HazelcastPNCounterEndpointBuilderFactory.java
index 36778575e38d..052703f4fa34 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/HazelcastPNCounterEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/HazelcastPNCounterEndpointBuilderFactory.java
@@ -205,6 +205,20 @@ public interface HazelcastPNCounterEndpointBuilderFactory {
}
public interface HazelcastPNCounterBuilders {
+ /**
+ * Hazelcast PN Counter (camel-hazelcast)
+ * Increment, decrement, get, etc. operations on a Hazelcast PN Counter
+ * (CRDT counter).
+ *
+ * Category: cache,clustering
+ * Since: 4.19
+ * Maven coordinates: org.apache.camel:camel-hazelcast
+ *
+ * @return the dsl builder for the headers' name.
+ */
+ default HazelcastPNCounterHeaderNameBuilder hazelcastPncounter() {
+ return HazelcastPNCounterHeaderNameBuilder.INSTANCE;
+ }
/**
* Hazelcast PN Counter (camel-hazelcast)
* Increment, decrement, get, etc. operations on a Hazelcast PN Counter
@@ -249,6 +263,29 @@ public interface HazelcastPNCounterEndpointBuilderFactory {
}
}
+ /**
+ * The builder of headers' name for the Hazelcast PN Counter component.
+ */
+ public static class HazelcastPNCounterHeaderNameBuilder {
+ /**
+ * The internal instance of the builder used to access to all the
+ * methods representing the name of headers.
+ */
+ public static final HazelcastPNCounterHeaderNameBuilder INSTANCE = new
HazelcastPNCounterHeaderNameBuilder();
+
+ /**
+ * The operation to perform.
+ *
+ * The option is a: {@code String} type.
+ *
+ * Group: producer
+ *
+ * @return the name of the header {@code HazelcastOperationType}.
+ */
+ public String hazelcastOperationType() {
+ return "CamelHazelcastOperationType";
+ }
+ }
static HazelcastPNCounterEndpointBuilder endpointBuilder(String
componentName, String path) {
class HazelcastPNCounterEndpointBuilderImpl extends
AbstractEndpointBuilder implements HazelcastPNCounterEndpointBuilder,
AdvancedHazelcastPNCounterEndpointBuilder {
public HazelcastPNCounterEndpointBuilderImpl(String path) {