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) {

Reply via email to