Skip to content

Fix #2263: add a Salesforce Pub/Sub source Kamelet - #3012

Merged
oscerd merged 1 commit into
apache:mainfrom
oscerd:ci-issue-2263
Sep 8, 2026
Merged

Fix #2263: add a Salesforce Pub/Sub source Kamelet#3012
oscerd merged 1 commit into
apache:mainfrom
oscerd:ci-issue-2263

Conversation

@oscerd

@oscerd oscerd commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Fixes #2263. Also covers the first half of #1546, which asks for the same thing — I have left that one open and commented there rather than closing it, because its second question about keystore authentication is separate and still unanswered.

The API has been there; the catalog had not caught up

camel-salesforce in 4.22 carries both Pub/Sub operations:

operationName enum -> [..., 'subscribe', 'pubSubSubscribe', 'pubSubPublish']

along with pubSubBatchSize, pubSubDeserializeType, pubSubPojoClass, pubSubReplayId, replayPreset, and host/port options. The catalog only had salesforce-source, which uses the older streaming API (subscribe, topics, notifyForOperation*). This adds a source for the gRPC one.

I did the source rather than both halves: #2263 asks about consuming, and a pubSubPublish sink is a clean follow-up rather than something to bundle here.

One default deliberately differs from the component

deserializeType defaults to JSON, where the component defaults to AVRO.

A Kamelet emits to kamelet:sink, and AVRO puts binary on the body that the next step has to decode before it is useful. JSON is usable as-is, which is the point of a Kamelet. All five values remain available, and the property description states plainly that AVRO is the component's own default so nobody is surprised.

A runtime caveat worth knowing about

Verifying this turned up something users will hit. Under Camel JBang the resolved protobuf-java is older than the generated gRPC stubs in camel-salesforce expect, and the route dies during class loading:

java.lang.NoClassDefFoundError: com/google/protobuf/RuntimeVersion$RuntimeDomain

That is before any endpoint is built, so it looks nothing like a configuration problem. Adding protobuf explicitly fixes it:

camel run route.yaml --dep=com.google.protobuf:protobuf-java:4.35.1

I put this in the Kamelet description rather than leaving it to be rediscovered.

I did not add it to spec.dependencies. It would work, and protobuf is BSD-3 so the licence is fine, but every pinned mvn: version in this catalog is managed from the root pom by the UpdateKamelets step — artemis-jakarta-client-all is the model. Hardcoding 4.35.1 here would drift from Camel the first time it moves. Wiring a managed protobuf-version property is the correct fix and is a maintainer decision about version coupling, so I have flagged it rather than made it. Say the word and I will do it properly.

Verification

script/validator reports no errors, script/generator adds the nav.adoc entry, mvn clean install passes with tests from the repository root.

With protobuf pinned, the Kamelet reaches a real login attempt and fails only on the deliberately invalid host:

Failed to start component local-salesforce-pubsub-1 because of
  SalesforceException: Unexpected login error: login.salesforce.invalid
Caused by: java.net.UnknownHostException

Every parameter binds and the gRPC path is exercised — the failure is the network, not the configuration.

No Citrus test: this needs a real Salesforce org, which no emulator provides. Ships Preview without kamelet.verified=true.


Claude Code on behalf of Andrea Cosentino

camel-salesforce has supported the gRPC Pub/Sub API for a while -- the
operations enum carries pubSubSubscribe and pubSubPublish -- but the catalog
only covered the older streaming API through salesforce-source. This adds a
source for the modern one.

deserializeType defaults to JSON rather than the component default of AVRO.
A Kamelet emits to kamelet:sink, and AVRO puts binary on the body that the
next step has to decode; JSON is usable as-is. The other four values remain
available, and the description says which default is the component's.

The Kamelet description carries a runtime caveat found while verifying it:
under Camel JBang the resolved protobuf-java is older than the generated
gRPC stubs in camel-salesforce expect, and the route dies at class loading
with NoClassDefFoundError on com.google.protobuf.RuntimeVersion long before
any endpoint is built. Adding protobuf-java explicitly fixes it.

Verified with that dependency in place: the component starts, attempts a
real login and fails only with UnknownHostException against a deliberately
invalid loginUrl, so every parameter binds and the gRPC path is reached.

Marked Preview, no Citrus test: this needs a real Salesforce org.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tz352mt7yzGWLfvYTBo2Dk
@oscerd
oscerd merged commit 13f59f7 into apache:main Sep 8, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Salesforce Publish/Subscribe Kamelet

1 participant