Federico Mariani created CAMEL-24158:
----------------------------------------
Summary: camel-azure - Umbrella: high-severity findings from July
2026 review (storage-blob, servicebus, eventhubs, storage-queue,
storage-datalake)
Key: CAMEL-24158
URL: https://issues.apache.org/jira/browse/CAMEL-24158
Project: Camel
Issue Type: Bug
Components: camel-azure-servicebus, camel-azure, camel-azure-eventhubs
Reporter: Federico Mariani
Attachments: camel-azure-review-2026-07.md
Umbrella for the high-severity findings of a deep code review of
camel-azure-storage-blob, -servicebus, -eventhubs, -storage-queue and
-storage-datalake on main (4.22.0-SNAPSHOT). The full findings document
(failure scenarios and suggested fixes per item) is attached. Key SDK-behavior
claims were verified against decompiled Azure SDK jars (e.g.
azure-messaging-servicebus 7.17.16). Individual findings can be split out into
their own issues as they are picked up.
*camel-azure-storage-blob*
# {{BlobOperations:830-842}} — {{leaseBlob=true}} acquires a lease but the
lease id is set on a discarded local BlobRequestConditions; every lease-guarded
write fails with 412 LeaseIdMissing (since CAMEL-17530).
# {{BlobConsumer:275-288}} — {{moveAfterRead}} copies via bare source URL (no
source SAS / copy-source-authorization); 401 CannotVerifyCopySource under the
default AZURE_IDENTITY and SAS auth, error swallowed in processCommit -> blob
re-consumed forever.
# {{BlobUtils:37-65}} — non-mark-supporting InputStream bodies are uploaded as
0-byte blobs (length forced to 0) with a successful exchange; mark-supporting
streams >8 KB throw "Resetting to invalid mark".
# {{BlobConfigurationOptionsProxy:122-133}} — page-blob range download
off-by-one ({{end - start}} instead of {{end - start + 1}}); last byte of the
range silently missing.
*camel-azure-servicebus*
# {{ServiceBusConsumer:110-124}} — an exception inside processMessage (e.g. SDK
{{getBody()}} throws UnsupportedOperationException for AMQP VALUE/SEQUENCE
bodies from non-Camel senders) leaves the message unsettled (Camel disables
auto-complete) and permanently leaks {{pendingExchanges}}; PEEK_LOCK messages
redeliver until dead-lettered, RECEIVE_AND_DELETE messages are lost, graceful
shutdown stalls.
*camel-azure-eventhubs*
# {{EventHubsConsumer:210-236}} + {{EventHubsCheckpointUpdaterTask}} —
checkpoint batching state (counter, timeout task, last EventContext) is
consumer-wide but checkpoints are per-partition; low-traffic partitions are
never checkpointed -> mass replay on restart/rebalance; checkpoints can also
move backwards.
# {{EventHubsProducerOperations:90-94}} + {{EventHubsConsumer:136-137}} — the
consumer unconditionally sets both partition id and partition key headers; the
producer reads the same names and throws IllegalArgumentException("Both
partitionKey and partitionId are set") -> EventHubs-to-EventHubs bridges fail
for every keyed event.
# {{EventHubsProducerOperations:154-155}} —
{{eventData.getProperties().putAll(headers)}} with no HeaderFilterStrategy;
Camel* headers leak to the wire and non-AMQP-encodable header values
(Instant/Map, planted by the consumer itself) fail every bridged send.
*camel-azure-storage-queue*
# {{QueueConsumer:129-151}} — on completion the consumer restores the
pre-processing popReceipt snapshot, clobbering the fresh receipt returned by a
mid-route updateMessage (visibility extension); the delete fails with
PopReceiptMismatch, is swallowed ("This exception is ignored"), and the message
is silently redelivered.
*camel-azure-storage-datalake*
# {{DataLakeConsumer:112-116}} + {{DataLakeFileOperations:110-119}} — consumer
downloadToFile: parent directories never created for sub-path files (documented
example fails) and default CREATE_NEW open options make every poll after the
first throw FileAlreadyExistsException.
# {{DataLakeFileOperations:182-189}} — flushToFile NPEs when {{position}} is
unset and double-counts the committed size; the component doc's own
append+flush example silently discards the appended data.
# {{DataLakeFileClientWrapper:66-71}} — default getFile/consumer read path uses
the Blob Query API ({{openQueryInputStream("SELECT * from BlobStorage")}})
wrapped in SkipLastByteInputStream; binary files (parquet/zip/images) and
quoted CSVs are corrupted, last byte dropped for 0x0A-terminated content, fails
outright without query acceleration. The SDK's plain {{openInputStream()}}
should be used.
_This issue was researched and filed by Claude Code (AI) on behalf of Federico
Mariani (fmariani). Full findings document from the review is attached to the
umbrella issues._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)