[
https://issues.apache.org/jira/browse/CAMEL-24160?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen reassigned CAMEL-24160:
-----------------------------------
Assignee: Claus Ibsen
> camel-salesforce - Umbrella: high-severity findings from July 2026 review
> (auth, streaming/pubsub, REST/bulk/composite)
> -----------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24160
> URL: https://issues.apache.org/jira/browse/CAMEL-24160
> Project: Camel
> Issue Type: Bug
> Components: camel-salesforce
> Reporter: Federico Mariani
> Assignee: Claus Ibsen
> Priority: Major
> Labels: review-2026-07
> Attachments: camel-salesforce-review-2026-07.md
>
>
> Umbrella for the high-severity findings of a deep code review of
> camel-salesforce-component on main (4.22.0-SNAPSHOT). The full findings
> document is attached. External behavior was verified against decompiled jars
> (Jetty 12.1.11, CometD 9.0.1, grpc-api 1.82.2). The critical finding
> (streamQueryResult iterator hanging the route thread forever on queryMore
> failure) is tracked separately with a failing reproducer test. Individual
> findings can be split out into their own issues as they are picked up.
> *Auth / session / HTTP client*
> # {{SalesforceSecurityHandler:176,181,218}} — 401 handling unconditionally
> dereferences the nullable conversation client attribute; CometD streaming
> requests (no attribute) NPE inside the listener, so handler-level transparent
> re-login for streaming is dead (regression from CAMEL-17346; transport stalls
> until maxNetworkDelay).
> # {{SalesforceSession:112-131}} — attemptLoginUntilSuccessful latch race: the
> winning thread replaces the already-counted-down latch only after the CAS, so
> concurrent waiters proceed with the stale token on every login cycle after
> the first (code carries a "TODO: This is janky").
> *Streaming (CometD) / Pub/Sub (gRPC)*
> # {{SubscriptionHelper:147-149}} — handshake failures retry in a tight loop
> ({{client.handshake()}} immediately, no backoff, no maxBackoff abort —
> machinery exists but is only applied to subscription failures; pre-rewrite
> code had it).
> # {{PubSubApiClient:341-344}} — onError logs trailers via
> {{Metadata.Key.of(name, ASCII_STRING_MARSHALLER)}}, which throws
> IllegalArgumentException for {{-bin}} keys (e.g. standard
> {{grpc-status-details-bin}}) before resubscribeOnError() is reached —
> reconnection permanently dead, no exception-handler notification.
> # {{PubSubApiClient:380-398}} — resubscribeOnError() has no
> stop/channel-state check; a stop racing an in-flight error loops forever
> (UNAVAILABLE -> sleep -> resubscribe) on a gRPC callback thread.
> *REST / Bulk / Composite processors*
> # {{SalesforceEndpointConfig.toValueMap}} — the documented {{allOrNone}} URI
> option is never put into the endpoint config map, so it can never take
> effect; batches lose the requested atomicity silently (only the header works).
> # {{DefaultBulkApiV2Client:111-125,235-249}} —
> changeJobState/changeQueryJobState error branch is missing a return, invoking
> the AsyncCallback twice; a 400 on bulk2CloseJob/AbortJob makes the remainder
> of the route execute twice for one input.
> # {{JsonRestProcessor:202-260}} — deferred SObject-type detection: when no
> "type" property is found (zero-record query, aggregate query, apexCall), the
> resulting RuntimeException escapes the IOException-only catch,
> callback.done(false) still runs without setting an exception, and the
> exchange completes *successfully* with the request body as the "result".
> # {{JsonRestProcessor:244}} — {{while (parser.nextToken() != END_OBJECT)}}
> never terminates for non-object JSON (bare scalar/array); a Jetty worker
> thread spins at 100% CPU forever and the exchange never completes (apexCall
> with deferred detection).
> _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)