Claus Ibsen created CAMEL-26235:
-----------------------------------

             Summary: camel-hazelcast - with no operation header and no 
defaultOperation the producers fail with a NullPointerException, and the map 
consumer never gets TTL expiry events
                 Key: CAMEL-26235
                 URL: https://issues.apache.org/jira/browse/CAMEL-26235
             Project: Camel
          Issue Type: Bug
          Components: camel-hazelcast
            Reporter: Claus Ibsen
             Fix For: 4.24.0


Found while adding the catalog body types of the eleven hazelcast components 
(CAMEL-24961, PR #28396).

h4. 1. No operation: NullPointerException instead of a clear error (map, 
multimap, replicatedmap, list, set, ringbuffer, pncounter)

{{HazelcastComponentHelper.lookupOperation}} (main 2a465aa4814c, line 63) 
returns the endpoint's {{defaultOperation}}, which is null when not set, and 
the producers switch on it ({{HazelcastMapProducer}} line 76, 
{{HazelcastMultimapProducer}} line 53, {{HazelcastReplicatedmapProducer}} line 
54, {{HazelcastListProducer}} line 61, {{HazelcastSetProducer}} line 48, 
{{HazelcastRingbufferProducer}} line 43, {{HazelcastPNCounterProducer}} line 
43), so a message without {{CamelHazelcastOperationType}} fails with a 
NullPointerException ('"operation" is null'). Checked on 4.24.0-SNAPSHOT with 
an embedded Hazelcast 5.4 cluster.

Proposed: fail with a message that names the {{CamelHazelcastOperationType}} 
header and the {{defaultOperation}} option.

h4. 2. map consumer: TTL expiry gives no event

{{CamelMapListener}} (line 27) implements {{MapEntryListener}}, which extends 
the added, updated, removed, evicted, merged and cleared listeners but not 
{{EntryExpiredListener}} ({{MapEntryListener}} lines 27-30), so an entry that 
expires by TTL never reaches the route. The multimap and replicatedmap 
{{CamelEntryListener}} handles {{entryExpired}}. Read in the code, not run.

Proposed: add {{EntryExpiredListener}} to {{MapEntryListener}} and send an 
expired event as the other listener does.

h4. 3. list: get without CamelHazelcastObjectIndex fails with a 
NullPointerException

{{HazelcastListProducer.get}} (line 121) calls {{list.get(pos)}} with the 
{{Integer}} from the {{CamelHazelcastObjectIndex}} header (line 56); without 
the header {{pos}} is null and unboxing throws. Checked on 4.24.0-SNAPSHOT with 
an embedded Hazelcast 5.4 cluster.

Proposed: fail with a message that the get operation needs the 
{{CamelHazelcastObjectIndex}} header.

h4. 4. list and set: getAll puts the live proxy in the body

{{HazelcastListProducer.getAll}} (line 169) and {{HazelcastSetProducer.getAll}} 
(line 118) set the distributed {{IList}} / {{ISet}} proxy as the body, not a 
copy, so later steps see (and can change) the live collection. Checked on 
4.24.0-SNAPSHOT with an embedded Hazelcast 5.4 cluster.

Proposed: set a copy ({{new ArrayList<>(list)}}, {{new HashSet<>(set)}}).

h4. 5. queue: removeIf always fails, drainTo without its header passes null

{{HazelcastQueueProducer.removeIf}} (lines 165-167) calls 
{{queue.removeIf(filter)}}, which the Hazelcast queue proxy does not support 
(UnsupportedOperationException "remove() is not supported!"), so the operation 
can never work (seen). {{drainTo}} (lines 96-97, 155) passes the 
{{CamelHazelcastDrainToCollection}} header as is, so without it 
{{queue.drainTo(null)}} fails (read in the code). Checked on 4.24.0-SNAPSHOT 
with an embedded Hazelcast 5.4 cluster.

Proposed: implement removeIf by iterating and removing the matching items (or 
remove the operation), and fail with a clear message when the drainTo 
collection header is missing.

h4. 6. pncounter: getAndAdd with no body fails with a NullPointerException

{{HazelcastPNCounterProducer.getAndAdd}} (line 88) unboxes 
{{getBody(Long.class)}} into a {{long}}. Checked on 4.24.0-SNAPSHOT with an 
embedded Hazelcast 5.4 cluster.

Proposed: fail with a message that getAndAdd needs a numeric body.

h4. 7. seda: a body that is neither Serializable nor convertible to bytes gives 
an unclear error

{{HazelcastSedaProducer.checkAndStore}} (lines 60-67) converts a 
non-Serializable body with {{getBody(byte[].class)}}; when that gives null, 
{{queue.add(null)}} fails with "Null item is not allowed!". Checked on 
4.24.0-SNAPSHOT with an embedded Hazelcast 5.4 cluster.

Proposed: fail with a message that the body must be Serializable or convertible 
to bytes.

h4. 8. Docs: replicatedmap intro and old header name in the samples

{{hazelcast-replicatedmap-component.adoc}} starts with the intro of the 
instance component ("consume join/leave events of the cache instance in the 
cluster"), and the XML and YAML samples of the replicatedmap, multimap, 
pncounter and ringbuffer pages set the old header {{hazelcast.operation.type}} 
instead of {{CamelHazelcastOperationType}}. Not fixed in the PR.

Proposed: fix the intro and use {{CamelHazelcastOperationType}} in the samples.

_Claude Code on behalf of davsclaus_



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to