Skip to content

Fix #1585: add an SAP NetWeaver sink Kamelet - #3011

Merged
oscerd merged 1 commit into
apache:mainfrom
oscerd:ci-issue-1585
Sep 7, 2026
Merged

Fix #1585: add an SAP NetWeaver sink Kamelet#3011
oscerd merged 1 commit into
apache:mainfrom
oscerd:ci-issue-1585

Conversation

@oscerd

@oscerd oscerd commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Fixes #1585.

camel-sap-netweaver is still current in the 4.22 catalog — not deprecated, first shipped in 2.12.0 — and it is producerOnly, so a sink is both the right shape and the only one available.

The command is a property, not a per-message header

This is the one design decision worth explaining. The component takes the OData command from a mandatory header; there is no endpoint option for it, and it becomes the request path:

String command = ExchangeHelper.getMandatoryHeader(exchange, NetWeaverConstants.COMMAND, String.class);
...
httpExchange.getIn().setHeader(NetWeaverConstants.HTTP_PATH, command);

So the Kamelet exposes command as a required property and sets the header from it:

      - setHeader:
          name: CamelNetWeaverCommand
          constant: "{{command}}"

That also means an inbound CamelNetWeaverCommand is overwritten rather than honoured, so a caller cannot pick the request path — the same posture as the dispatch-header work in #2978. Verified with the terminal endpoint swapped for a log:

in:  CamelNetWeaverCommand=ATTACKER-COMMAND, keepMe=yes
out: CamelNetWeaverCommand=OPERATOR-COMMAND, keepMe=yes

The operator's command wins and unrelated headers are untouched.

Properties

property notes
url required — the gateway server URL
command required — the OData command, sent as the request path
username required by the component; credentials descriptor
password required by the component; format: password + credentials descriptor
json default true; when false the gateway returns XML in Atom format
jsonAsMap default true; turns the returned JSON into a Map
flatternMap default true; single-entry Map is unwrapped to its value

flatternMap keeps the component's spelling, typo and all, rather than inventing a corrected name the underlying option would not accept.

Verification

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

Binding checked against the real component with camel run — worth doing here because the gateway URL contains :// and gets embedded in the endpoint URI, which is exactly the sort of thing that fails quietly:

Routes startup (total:1 started:1 kamelets:1)
... java.net.UnknownHostException: gateway.example.invalid

Every parameter binds, the URL survives, and the route gets as far as attempting the HTTP call, failing only on the deliberately invalid host.

No Citrus test — this needs a real SAP NetWeaver Gateway and there is no emulator for one, so it ships Preview without kamelet.verified=true.

The icon is a plain SVG glyph authored for this Kamelet, consistent with how other non-vendor Kamelets are handled.


Claude Code on behalf of Andrea Cosentino

camel-sap-netweaver is producerOnly and still current in the 4.22 catalog
(not deprecated, first shipped in 2.12.0), so a sink is both the right shape
and the only one available.

The command is a Kamelet property rather than a per-message input. The
component reads it from CamelNetWeaverCommand as a *mandatory* header --
there is no endpoint option for it -- and turns it straight into the request
path:

    String command = ExchangeHelper.getMandatoryHeader(exchange, COMMAND, String.class);
    httpExchange.getIn().setHeader(HTTP_PATH, command);

Setting that header from the pinned property means an inbound value cannot
choose the request path, which is the same posture as the dispatch-header
work in apache#2978. Verified with the terminal endpoint swapped for a log:

  in:  CamelNetWeaverCommand=ATTACKER-COMMAND, keepMe=yes
  out: CamelNetWeaverCommand=OPERATOR-COMMAND, keepMe=yes

Marked Preview, no Citrus test: this needs a real SAP NetWeaver Gateway and
there is no emulator for one.

Verified against the real component with `camel run`: every parameter binds,
the gateway URL survives being embedded in the endpoint URI, and the route
fails only with UnknownHostException against a deliberately invalid host --
so it got as far as making the call.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tz352mt7yzGWLfvYTBo2Dk
@oscerd
oscerd merged commit e333d89 into apache:main Sep 7, 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.

Create a Camel-SAP-Netweaver Sink Kamelet

1 participant