Skip to content

Fix #1938: add an AWS Bedrock Agent sink Kamelet - #2997

Merged
oscerd merged 2 commits into
apache:mainfrom
oscerd:ci-issue-1938
Sep 3, 2026
Merged

Fix #1938: add an AWS Bedrock Agent sink Kamelet#2997
oscerd merged 2 commits into
apache:mainfrom
oscerd:ci-issue-1938

Conversation

@oscerd

@oscerd oscerd commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #1938.

The issue asks for Bedrock Agent support. Two thirds of it already shipped — this closes the remaining gap.

Camel component Kamelet status
aws-bedrock aws-bedrock-text-sink already in the catalog
aws-bedrock-agent-runtime aws-bedrock-agent-runtime-sink already in the catalog
aws-bedrock-agent aws-bedrock-agent-sink added here

aws-bedrock-agent is the knowledge-base management component. Its three operations are all about data source ingestion jobs:

enum=['startIngestionJob', 'listIngestionJobs', 'getIngestionJob']

A sink is the right and only shape — the component is producer-oriented, so the "and Source" half of the issue title has nothing to map onto. Say the word if you disagree and I will look again.

Properties

knowledgeBaseId and region are required; operation defaults to startIngestionJob.

property notes
knowledgeBaseId required
dataSourceId required by startIngestionJob
operation startIngestionJob (default) / listIngestionJobs / getIngestionJob
region required, enum matching the component
accessKey / secretKey / sessionToken format: password + credentials descriptor
the usual credentials-provider and endpoint-override options mirroring aws-bedrock-agent-runtime-sink

The header strip, and why it is not optional here

BedrockAgentProducer.determineOperation reads the header before the endpoint:

private BedrockAgentOperations determineOperation(Exchange exchange) {
    ... = exchange.getIn().getHeader(BedrockAgentConstants.OPERATION, BedrockAgentOperations.class);

and knowledgeBaseId / dataSourceId are header-overridable the same way. Without a strip, an inbound message could point a sink configured for one knowledge base at another, or turn a startIngestionJob into something else — the exact pattern addressed for aws-ec2-sink in #2978.

      - removeHeaders:
          pattern: "CamelAwsBedrockAgent*"
          excludePattern: "CamelAwsBedrockAgentIngestionJobId"

CamelAwsBedrockAgentIngestionJobId is excluded deliberately — getIngestionJob has to name a job, so that one header is the Kamelet's intended message-level input rather than something it never asked for.

Verification

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

Parameter binding against the real component with camel run — the route starts with everything bound:

Routes startup (total:1 started:1 kamelets:1)
    Started bed-real (timer://t)

The strip, checked by swapping the terminal endpoint for a log so the surviving headers are visible. Sending every overridable header plus an unrelated one:

in:  CamelAwsBedrockAgentOperation=listIngestionJobs
     CamelAwsBedrockAgentKnowledgeBaseId=attacker-kb
     CamelAwsBedrockAgentDataSourceId=attacker-ds
     CamelAwsBedrockAgentIngestionJobId=job-42
     keepMe=yes

out: {CamelAwsBedrockAgentIngestionJobId=job-42, keepMe=yes}

The three dispatch-controlling headers are gone, the deliberate input survives, unrelated headers are untouched.

No Citrus test — this needs a real Bedrock knowledge base and there is no emulator for it in the project's Citrus/Testcontainers toolchain, so it ships Preview without kamelet.verified=true.

Note

The catalog's headers block for aws-bedrock-agent lists CamelAwsBedrockAgentRuntime* names, but the component's own BedrockAgentConstants uses CamelAwsBedrockAgent* (OPERATION = "CamelAwsBedrockAgentOperation"). I went with the constants, which is what the producer actually reads and what the probe above confirms. The catalog metadata looks like it has the runtime component's headers copied into it — worth a separate look upstream, but it does not affect this Kamelet.


Claude Code on behalf of Andrea Cosentino

oscerd and others added 2 commits September 1, 2026 11:09
The catalog already covers aws-bedrock (aws-bedrock-text-sink) and
aws-bedrock-agent-runtime (aws-bedrock-agent-runtime-sink). The
aws-bedrock-agent component had no Kamelet, which is the gap this closes:
managing the data source ingestion jobs of a knowledge base via
startIngestionJob, listIngestionJobs and getIngestionJob.

BedrockAgentProducer.determineOperation reads CamelAwsBedrockAgentOperation
from the message before falling back to the endpoint, and knowledgeBaseId
and dataSourceId are header-overridable the same way. A sink that pins
those three as properties therefore has to strip the family, or an inbound
header could redirect the call to a different knowledge base or a different
operation. Same shape as the aws-ec2-sink strip.

CamelAwsBedrockAgentIngestionJobId is excluded from the strip: it is the
one input the Kamelet deliberately takes from the message, since
getIngestionJob has to name a job.

Marked Preview, no Citrus test: exercising this needs a real Bedrock
knowledge base and there is no emulator for it in the project's toolchain.

Verified with `camel run` against the real component -- the route starts
with every parameter bound -- and the strip verified with the terminal
endpoint swapped for a log:

  in:  Operation=listIngestionJobs, KnowledgeBaseId=attacker-kb,
       DataSourceId=attacker-ds, IngestionJobId=job-42, keepMe=yes
  out: CamelAwsBedrockAgentIngestionJobId=job-42, keepMe=yes

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
KameletsCatalogTest.testGetKameletsByNamespace asserts an exact count for
the AWS namespace, so adding aws-bedrock-agent-sink takes it from 31 to
32 and the catalog module's tests fail.

Verified against the tree rather than just following the CI delta: 31
kamelets carry kamelet.namespace "AWS" on main, 32 with this branch.

Only the AWS namespace is count-asserted, which is why the SMPP and SNMP
Kamelets added in apache#2988, apache#2989 and apache#2990 did not trip it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@oscerd

oscerd commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Pushed a fix for the red build check.

KameletsCatalogTest.testGetKameletsByNamespace asserts an exact count for the AWS namespace, so a new AWS Kamelet fails it by construction:

KameletsCatalogTest.testGetKameletsByNamespace:124 expected: <31> but was: <32>

Bumped the expectation to 32. Verified against the tree rather than just trusting the CI delta — 31 Kamelets carry kamelet.namespace: "AWS" on main, 32 with this branch.

Worth noting the AWS namespace is the only one with a count assertion, which is why the SMPP and SNMP Kamelets in #2988, #2989 and #2990 did not trip it. If a maintainer would rather this were a lower bound than a change detector, that is a reasonable separate cleanup — but changing the assertion's intent felt like scope creep inside a Kamelet PR, so I left the design alone and just updated the number.

My own fault for not catching it before opening: I had run the root build with -DskipTests, which skips the catalog module's tests entirely. Re-ran the full mvn clean install with tests after the fix:

Tests run: 18, Failures: 0, Errors: 0, Skipped: 0 -- in KameletsCatalogTest
BUILD SUCCESS

Also rebased onto current main while I was here, so the branch is up to date.


Claude Code on behalf of Andrea Cosentino

@oscerd
oscerd merged commit 113b8dd into apache:main Sep 3, 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.

Support Camel AWS Bedrock Agent Sink and Source

1 participant