Skip to content

CAMEL-24238: camel-aws2-ses - send RawMessage body content instead of the SdkBytes descriptor#25015

Open
oscerd wants to merge 1 commit into
apache:mainfrom
oscerd:fix/CAMEL-24238
Open

CAMEL-24238: camel-aws2-ses - send RawMessage body content instead of the SdkBytes descriptor#25015
oscerd wants to merge 1 commit into
apache:mainfrom
oscerd:fix/CAMEL-24238

Conversation

@oscerd

@oscerd oscerd commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Problem

Ses2Producer.createMessage() builds the outgoing Content from
exchange.getIn().getBody(String.class). When the body is an SES
RawMessage, there is no type converter for it, so the conversion falls back
to Object.toString() on the SDK type.

SdkBytes.toString() renders a debug descriptor, not the payload:

SdkBytes(bytes=0x46726f6d3a2066726f6d406578616d706c652e636f6d0d0a...)

That descriptor is what ends up in the e-mail body — the actual MIME content
is never sent.

Fix

When the body is a RawMessage, read the payload from
RawMessage.data().asUtf8String():

if (exchange.getIn().getBody() instanceof RawMessage raw) {
    // SdkBytes.toString() is a debug descriptor (SdkBytes(bytes=0x...)), not the payload
    content = raw.data().asUtf8String();
} else {
    content = exchange.getIn().getBody(String.class);
}

Note this path is distinct from the jakarta.mail.Message body, which already
goes through sendRawEmail and is unaffected.

Test

SesComponentTest.rawMessageBodyIsSentAsItsContentNotTheSdkBytesDescriptor()
sends a RawMessage and asserts the text captured by the mock SES client
equals the original MIME string. The test fails on main with the
SdkBytes(bytes=0x...) descriptor and passes with the fix.

assertj-core is added test-scoped so the new assertion follows the project's
AssertJ preference; the pre-existing JUnit assertions in the file are left
untouched.

Backport

The same code is present on camel-4.18.x and camel-4.14.x, so this is
targeted at 4.22.0, 4.18.4 and 4.14.9.


Claude Code on behalf of oscerd

… the SdkBytes descriptor

When the exchange body is an SES RawMessage, Ses2Producer built the outgoing
Content from the body converted to String, which for a RawMessage falls back
to Object.toString() on the SDK type. SdkBytes.toString() renders a debug
descriptor ("SdkBytes(bytes=0x46726f6d...)"), so the recipient received that
descriptor instead of the MIME payload.

Read the payload from RawMessage.data().asUtf8String() when the body is a
RawMessage, and cover it with a test asserting the sent text equals the
original MIME content.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Andrea Cosentino <ancosen@gmail.com>
@oscerd
oscerd requested a review from davsclaus July 22, 2026 10:59
@oscerd oscerd added this to the 4.22.0 milestone Jul 22, 2026
@oscerd
oscerd requested a review from Croway July 22, 2026 10:59
@oscerd oscerd added the bug Something isn't working label Jul 22, 2026

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, well-targeted bug fix. SdkBytes.toString() returns a debug descriptor (e.g., SdkBytes(bytes=0x46726F6D...)) rather than the actual content — so when a RawMessage body was used, the email text was garbled with the descriptor string instead of the MIME content.

The fix correctly uses raw.data().asUtf8String() which decodes the actual byte content as UTF-8 — appropriate for MIME email content.

Test added: rawMessageBodyIsSentAsItsContentNotTheSdkBytesDescriptor() constructs a RawMessage with MIME content, sends it through the route, and verifies the actual content is preserved. The test would have caught the original bug (the assertion would fail comparing "SdkBytes(bytes=0x...)" against the expected MIME string).

Checklist:

  • Bug fix — correct API usage (asUtf8String() vs toString())
  • Test — new test covers the exact bug scenario
  • AssertJ dependency added (project standard for assertions)
  • Commit convention — CAMEL-24238: prefix
  • No public API changes
  • CI — pending

Reviewed with Claude Code on behalf of gnodet. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, focused bug fix. SdkBytes.toString() returns a debug descriptor (SdkBytes(bytes=0x...)), not the actual payload — asUtf8String() is the correct API.

Verified:

  • The bug was introduced in fe3d038cd6a9 (CAMEL-21593, Jan 2025) when RawMessage support was added — the toString() vs asUtf8String() mistake has been present since the feature was first added
  • Routing logic in process() dispatches jakarta.mail.Message bodies to sendRawEmail() and everything else (including RawMessage) to sendEmail() via createMessage() — the fix targets the correct code path
  • Test rawMessageBodyIsSentAsItsContentNotTheSdkBytesDescriptor() directly tests the regression: builds a RawMessage from a MIME string, sends it, and asserts the captured body equals the original content
  • New test uses AssertJ and drops public per project conventions; existing JUnit assertions left untouched
  • Comment explains WHY asUtf8String() is used — a genuine SDK gotcha worth documenting
  • No scope drift, commit convention correct

Claude Code on behalf of davsclaus. This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-aws/camel-aws2-ses

🔬 Scalpel shadow comparison — Scalpel: 9 tested, 29 compile-only — current: 9 all tested

Maveniverse Scalpel detected 38 affected modules (current approach: 9).

⚠️ Modules only in Scalpel (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

Skip-tests mode would test 9 modules (1 direct + 8 downstream), skip tests for 29 (generated code, meta-modules)

Modules Scalpel would test (9)
  • camel-aws2-ses
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-launcher-container
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
Modules with tests skipped (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

All tested modules (38 modules)
  • Camel :: AWS2 SES
  • Camel :: All Components Sync point
  • Camel :: Assembly
  • Camel :: Catalog :: CSimple Maven Plugin (deprecated)
  • Camel :: Catalog :: Camel Catalog
  • Camel :: Catalog :: Camel Report Maven Plugin
  • Camel :: Catalog :: Camel Route Parser
  • Camel :: Catalog :: Console
  • Camel :: Catalog :: Dummy Component
  • Camel :: Catalog :: Lucene (deprecated)
  • Camel :: Catalog :: Maven
  • Camel :: Catalog :: Suggest
  • Camel :: Component DSL
  • Camel :: Coverage
  • Camel :: Docs
  • Camel :: Endpoint DSL
  • Camel :: Endpoint DSL :: Support
  • Camel :: Integration Tests
  • Camel :: JBang :: Core
  • Camel :: JBang :: Integration tests
  • Camel :: JBang :: MCP
  • Camel :: JBang :: Main
  • Camel :: JBang :: Plugin :: Edit
  • Camel :: JBang :: Plugin :: Generate
  • Camel :: JBang :: Plugin :: Kubernetes
  • Camel :: JBang :: Plugin :: MCP
  • Camel :: JBang :: Plugin :: Route Parser
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: Testing
  • Camel :: JBang :: Plugin :: Validate
  • Camel :: Kamelet Main
  • Camel :: Launcher
  • Camel :: Launcher :: Container
  • Camel :: YAML DSL
  • Camel :: YAML DSL :: Deserializers
  • Camel :: YAML DSL :: Maven Plugins
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin

⚙️ View full build and test results

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct one-line fix for a genuine bug introduced in CAMEL-21593 where SdkBytes.toString() yields a debug descriptor instead of the payload. The fix to use asUtf8String() is consistent with how other AWS components in the codebase extract text from SdkBytes. Test is appropriate and validates the fix.

Minor suggestions (non-blocking):

  • The assertj-core dependency is added solely for a single assertThat call. Using assertEquals(mime, sent) would be consistent with the rest of the test file and avoid the extra dependency.
  • New test method uses package-private access while existing methods use public void — minor style inconsistency.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working components components-aws

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants