Apache Camel 4.x Upgrade Guide

This document is for helping you upgrade your Apache Camel application from Camel 4.x to 4.y. For example, if you are upgrading Camel 4.0 to 4.2, then you should follow the guides from both 4.0 to 4.1 and 4.1 to 4.2.

The Camel Upgrade Recipes project provides automated assistance for some common migration tasks. Note that manual migration is still required. See the documentation page for details.

Upgrading from 4.18.1 to 4.18.3

camel-core

The org.apache.camel.support.DefaultHeaderFilterStrategy changed default setting for lowercase from false to true.

camel-jms

JMS ObjectMessage support is now disabled by default. Java object serialization is a recurring source of security issues, and Camel JMS routes rarely use ObjectMessage in practice. The component will now refuse to create or read jakarta.jms.ObjectMessage instances unless the new objectMessageEnabled option is explicitly set to true.

This affects the following endpoint/component options that rely on ObjectMessage internally:

  • jmsMessageType=Object (or sending a Serializable body that is auto-detected as Object)

  • transferExchange=true

  • transferException=true

  • receiving a JMS ObjectMessage produced by an external sender

To restore the previous behavior, enable the option at the component or endpoint level:

camel.component.jms.objectMessageEnabled=true

Or, on a single endpoint:

jms:queue:foo?objectMessageEnabled=true

camel-sjms / camel-sjms2

The same default applies to camel-sjms (and camel-sjms2, which inherits from it): JMS ObjectMessage support is now disabled by default and gated by a new objectMessageEnabled option (default false) on SjmsComponent / SjmsEndpoint.

This affects the same endpoint/component options as camel-jms:

  • jmsMessageType=Object (or sending a Serializable body that is auto-detected as Object)

  • transferException=true

  • receiving a JMS ObjectMessage produced by an external sender

To restore the previous behavior, enable the option at the component or endpoint level:

camel.component.sjms.objectMessageEnabled=true
camel.component.sjms2.objectMessageEnabled=true

Or, on a single endpoint:

sjms:queue:foo?objectMessageEnabled=true
sjms2:queue:foo?objectMessageEnabled=true

camel-aws-bedrock

The applyGuardrail producer operation now reads the guardrail identifier from a new dedicated header CamelAwsBedrockGuardrailIdentifier (constant BedrockConstants.GUARDRAIL_IDENTIFIER, typed String) instead of CamelAwsBedrockGuardrailConfig. The CamelAwsBedrockGuardrailConfig header is typed GuardrailConfiguration and is reserved for the converse and converseStream operations; the previous code path silently produced null whenever a route mixed converse and applyGuardrail calls. If you were not setting the guardrail identifier via header, the endpoint-level guardrailIdentifier option continues to work without changes.

camel-hazelcast

Hazelcast instances created and managed by Camel (when no user-supplied Config or HazelcastInstance is provided) now apply a default JavaSerializationFilterConfig on the SerializationConfig of the Config built by Camel. The default whitelists the class name prefixes java., javax., org.apache.camel. and blacklists java.net..

This affects:

  • camel-hazelcast component endpoints when neither hazelcastInstance, hazelcastConfigUri, nor a referenced Config is supplied

  • HazelcastAggregationRepository and HazelcastIdempotentRepository when no hazelcastInstance is supplied

  • HazelcastUtil#newInstance() (no-arg)

A user-supplied JavaSerializationFilterConfig (set on the SerializationConfig of a Config provided via hazelcastConfigUri, a referenced Config bean, or already wired into a pre-built HazelcastInstance) is respected and is not overwritten.

Applications that store classes outside the default whitelist on a Hazelcast topic, queue, map, list, set, or in one of the repositories above must provide their own Config with a JavaSerializationFilterConfig configured for their class names.

camel-jgroups - potential breaking change

The Exchange header constants in JGroupsConstants have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

JGroupsConstants.HEADER_JGROUPS_CHANNEL_ADDRESS

JGROUPS_CHANNEL_ADDRESS

CamelJGroupsChannelAddress

JGroupsConstants.HEADER_JGROUPS_DEST

JGROUPS_DEST

CamelJGroupsDest

JGroupsConstants.HEADER_JGROUPS_SRC

JGROUPS_SRC

CamelJGroupsSrc

JGroupsConstants.HEADER_JGROUPS_ORIGINAL_MESSAGE

JGROUPS_ORIGINAL_MESSAGE

CamelJGroupsOriginalMessage

This is a breaking change for routes that read or write these headers by their literal string value. Routes that reference the constant symbolically (for example setHeader(JGroupsConstants.HEADER_JGROUPS_DEST, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("JGROUPS_DEST", …​)) must be updated to use the new value (setHeader("CamelJGroupsDest", …​)).

camel-lucene

The Exchange header values exposed by LuceneConstants have been renamed to follow the standard Camel naming convention. The field names are unchanged, so routes referencing the constants (LuceneConstants.HEADER_QUERY, LuceneConstants.HEADER_RETURN_LUCENE_DOCS) continue to work without modification. However, routes that set or read these headers using the raw string values must be updated:

  • QUERYCamelLuceneQuery

  • RETURN_LUCENE_DOCSCamelLuceneReturnLuceneDocs

As a consequence, the generated Endpoint DSL header accessors on LuceneHeaderNameBuilder have been renamed accordingly:

  • qUERY()luceneQuery()

  • returnLuceneDocs()luceneReturnLuceneDocs()

camel-jgroups-raft

The Exchange header constants in JGroupsRaftConstants have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

JGroupsRaftConstants.HEADER_JGROUPSRAFT_LOG_SIZE

JGROUPSRAFT_LOG_SIZE

CamelJGroupsRaftLogSize

JGroupsRaftConstants.HEADER_JGROUPSRAFT_COMMIT_INDEX

JGROUPSRAFT_COMMIT_INDEX

CamelJGroupsRaftCommitIndex

JGroupsRaftConstants.HEADER_JGROUPSRAFT_CURRENT_TERM

JGROUPSRAFT_CURRENT_TERM

CamelJGroupsRaftCurrentTerm

JGroupsRaftConstants.HEADER_JGROUPSRAFT_IS_LEADER

JGROUPSRAFT_IS_LEADER

CamelJGroupsRaftIsLeader

JGroupsRaftConstants.HEADER_JGROUPSRAFT_LAST_APPLIED

JGROUPSRAFT_LAST_APPLIED

CamelJGroupsRaftLastApplied

JGroupsRaftConstants.HEADER_JGROUPSRAFT_LEADER_ADDRESS

JGROUPSRAFT_LEADER_ADDRESS

CamelJGroupsRaftLeaderAddress

JGroupsRaftConstants.HEADER_JGROUPSRAFT_RAFT_ID

JGROUPSRAFT_RAFT_ID

CamelJGroupsRaftRaftId

JGroupsRaftConstants.HEADER_JGROUPSRAFT_EVENT_TYPE

JGROUPSRAFT_EVENT_TYPE

CamelJGroupsRaftEventType

JGroupsRaftConstants.HEADER_JGROUPSRAFT_SET_OFFSET

JGROUPSRAFT_SET_OFFSET

CamelJGroupsRaftSetOffset

JGroupsRaftConstants.HEADER_JGROUPSRAFT_SET_LENGTH

JGROUPSRAFT_SET_LENGTH

CamelJGroupsRaftSetLength

JGroupsRaftConstants.HEADER_JGROUPSRAFT_SET_TIMEOUT

JGROUPSRAFT_SET_TIMEOUT

CamelJGroupsRaftSetTimeout

JGroupsRaftConstants.HEADER_JGROUPSRAFT_SET_TIMEUNIT

JGROUPSRAFT_SET_TIMEUNIT

CamelJGroupsRaftSetTimeUnit

Routes that reference the constant symbolically (for example setHeader(JGroupsRaftConstants.HEADER_JGROUPSRAFT_SET_TIMEOUT, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("JGROUPSRAFT_SET_TIMEOUT", …​)) must be updated to use the new value (setHeader("CamelJGroupsRaftSetTimeout", …​)).

camel-elasticsearch-rest-client

The Exchange header constants in ElasticSearchRestClientConstant have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

ElasticSearchRestClientConstant.ID

ID

CamelElasticsearchId

ElasticSearchRestClientConstant.SEARCH_QUERY

SEARCH_QUERY

CamelElasticsearchSearchQuery

ElasticSearchRestClientConstant.INDEX_SETTINGS

INDEX_SETTINGS

CamelElasticsearchIndexSettings

ElasticSearchRestClientConstant.INDEX_NAME

INDEX_NAME

CamelElasticsearchIndexName

ElasticSearchRestClientConstant.OPERATION

OPERATION

CamelElasticsearchOperation

Routes that reference the constant symbolically (for example setHeader(ElasticSearchRestClientConstant.SEARCH_QUERY, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("SEARCH_QUERY", …​)) must be updated to use the new value (setHeader("CamelElasticsearchSearchQuery", …​)).

camel-neo4j

When using the RETRIEVE_NODES or DELETE_NODE operations with the CamelNeo4jMatchProperties header, the property names provided in the JSON match map are now validated before the MATCH / DELETE WHERE clause is built. Property names must be valid identifiers matching [A-Za-z_][A-Za-z0-9_]*. A request whose match map contains a property name that does not match this pattern now fails fast with an IllegalArgumentException (wrapped in a Neo4jOperationException) instead of producing a malformed query. Property values continue to be passed as bound query parameters and are unaffected.

camel-mail

The SMTP producer no longer extracts dynamic JavaMail session properties from message headers by default. Previously any message header whose key started with mail.smtp. (or mail.smtps.) was applied to a per-message JavaMailSender, which meant an upstream producer that mapped untrusted input into the exchange header map (for example platform-http query parameters, JMS or Kafka messages from untrusted producers) could override transport-security settings such as mail.smtp.ssl.trust or mail.smtp.starttls.enable, or redirect the SMTP connection.

This behaviour is now disabled by default. Routes that legitimately rely on per-message mail.smtp. / mail.smtps. headers must opt back in on the endpoint:

.to("smtp://mymailserver:1234?useJavaMailSessionPropertiesFromHeaders=true");

Even with the opt-in, route authors should still strip the namespace with removeHeaders("mail.smtp.", "mail.smtps.") between any untrusted ingress and the mail producer.

In addition, the inbound MailHeaderFilterStrategy now blocks the mail.smtp. / mail.smtps. prefix as well, so an external mail message can no longer inject these into a downstream exchange.

camel-jira - potential breaking change

The Exchange header constants in JiraConstants have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

JiraConstants.ISSUE_ASSIGNEE_ID

IssueAssigneeId

CamelJiraIssueAssigneeId

JiraConstants.ISSUE_ASSIGNEE

IssueAssignee

CamelJiraIssueAssignee

JiraConstants.ISSUE_COMPONENTS

IssueComponents

CamelJiraIssueComponents

JiraConstants.ISSUE_COMMENT

IssueComment

CamelJiraIssueComment

JiraConstants.ISSUE_CHANGED

IssueChanged

CamelJiraIssueChanged

JiraConstants.ISSUE_KEY

IssueKey

CamelJiraIssueKey

JiraConstants.ISSUE_PRIORITY_ID

IssuePriorityId

CamelJiraIssuePriorityId

JiraConstants.ISSUE_PRIORITY_NAME

IssuePriorityName

CamelJiraIssuePriorityName

JiraConstants.ISSUE_PROJECT_KEY

ProjectKey

CamelJiraIssueProjectKey

JiraConstants.ISSUE_SUMMARY

IssueSummary

CamelJiraIssueSummary

JiraConstants.ISSUE_TRANSITION_ID

IssueTransitionId

CamelJiraIssueTransitionId

JiraConstants.ISSUE_TYPE_ID

IssueTypeId

CamelJiraIssueTypeId

JiraConstants.ISSUE_TYPE_NAME

IssueTypeName

CamelJiraIssueTypeName

JiraConstants.ISSUE_WATCHED_ISSUES

IssueWatchedIssues

CamelJiraIssueWatchedIssues

JiraConstants.ISSUE_WATCHERS_ADD

IssueWatchersAdd

CamelJiraIssueWatchersAdd

JiraConstants.ISSUE_WATCHERS_REMOVE

IssueWatchersRemove

CamelJiraIssueWatchersRemove

JiraConstants.PARENT_ISSUE_KEY

ParentIssueKey

CamelJiraParentIssueKey

JiraConstants.CHILD_ISSUE_KEY

ChildIssueKey

CamelJiraChildIssueKey

JiraConstants.LINK_TYPE

linkType

CamelJiraLinkType

JiraConstants.MINUTES_SPENT

minutesSpent

CamelJiraMinutesSpent

Routes that reference the constants symbolically (for example setHeader(JiraConstants.ISSUE_KEY, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("IssueKey", …​)) must be updated to use the new value (setHeader("CamelJiraIssueKey", …​)).

As a consequence, the generated Endpoint DSL header accessors on JiraHeaderNameBuilder have been renamed accordingly:

  • issueAssigneeId()jiraIssueAssigneeId()

  • issueAssignee()jiraIssueAssignee()

  • issueComponents()jiraIssueComponents()

  • issueChanged()jiraIssueChanged()

  • issueKey()jiraIssueKey()

  • issuePriorityId()jiraIssuePriorityId()

  • issuePriorityName()jiraIssuePriorityName()

  • projectKey()jiraIssueProjectKey()

  • issueSummary()jiraIssueSummary()

  • issueTransitionId()jiraIssueTransitionId()

  • issueTypeId()jiraIssueTypeId()

  • issueTypeName()jiraIssueTypeName()

  • issueWatchedIssues()jiraIssueWatchedIssues()

  • issueWatchersAdd()jiraIssueWatchersAdd()

  • issueWatchersRemove()jiraIssueWatchersRemove()

  • parentIssueKey()jiraParentIssueKey()

  • childIssueKey()jiraChildIssueKey()

  • linkType()jiraLinkType()

  • minutesSpent()jiraMinutesSpent()

camel-pdf - potential breaking change

The Exchange header constants in PdfHeaderConstants have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

PdfHeaderConstants.PROTECTION_POLICY_HEADER_NAME

protection-policy

CamelPdfProtectionPolicy

PdfHeaderConstants.PDF_DOCUMENT_HEADER_NAME

pdf-document

CamelPdfDocument

PdfHeaderConstants.DECRYPTION_MATERIAL_HEADER_NAME

decryption-material

CamelPdfDecryptionMaterial

PdfHeaderConstants.FILES_TO_MERGE_HEADER_NAME

files-to-merge

CamelPdfFilesToMerge

Routes that reference the constants symbolically (for example setHeader(PdfHeaderConstants.PDF_DOCUMENT_HEADER_NAME, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("pdf-document", …​)) must be updated to use the new value (setHeader("CamelPdfDocument", …​)).

As a consequence, the generated Endpoint DSL header accessors on PdfHeaderNameBuilder have been renamed accordingly:

  • protectionPolicy()pdfProtectionPolicy()

  • pdfDocument()pdfDocument() (unchanged in name, returns the new value)

  • decryptionMaterial()pdfDecryptionMaterial()

  • filesToMerge()pdfFilesToMerge()

camel-arangodb - potential breaking change

Two Exchange header constants in ArangoDbConstants that were not in the Camel namespace (and therefore not filtered by the default HeaderFilterStrategy) have been renamed to follow the Camel naming convention. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

ArangoDbConstants.ARANGO_KEY

key

CamelArangoDbKey

ArangoDbConstants.RESULT_CLASS_TYPE

ResultClassType

CamelArangoDbResultClassType

The remaining constants (MULTI_UPDATE, MULTI_INSERT, MULTI_DELETE, AQL_QUERY, AQL_QUERY_BIND_PARAMETERS, AQL_QUERY_OPTIONS) were already Camel-prefixed and are unchanged.

Routes that reference the constants symbolically (for example setHeader(ArangoDbConstants.ARANGO_KEY, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("key", …​)) must be updated to use the new value (setHeader("CamelArangoDbKey", …​)).

As a consequence, the generated Endpoint DSL header accessors on ArangoDbHeaderNameBuilder have been renamed: key()arangoDbKey() and resultClassType()arangoDbResultClassType().

camel-jt400 - potential breaking change

The two Exchange header constants in Jt400Constants that were not in the Camel namespace (and therefore not filtered by the default HeaderFilterStrategy) have been renamed to follow the Camel naming convention. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

Jt400Constants.KEY

KEY

CamelJt400Key

Jt400Constants.SENDER_INFORMATION

SENDER_INFORMATION

CamelJt400SenderInformation

Jt400Constants.KEY is the data-queue key used for keyed-data-queue read and write operations. The remaining constants (MESSAGE, MESSAGE_ID, MESSAGE_FILE, MESSAGE_TYPE, MESSAGE_SEVERITY, MESSAGE_DFT_RPY, MESSAGE_REPLYTO_KEY) were already Camel-prefixed and are unchanged.

Routes that reference the constants symbolically (for example setHeader(Jt400Constants.KEY, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("KEY", …​)) must be updated to use the new value (setHeader("CamelJt400Key", …​)).

As a consequence, the generated Endpoint DSL header accessors on Jt400HeaderNameBuilder have been renamed: kEY()jt400Key() and senderInformation()jt400SenderInformation().

camel-mail - potential breaking change

The consumer-side dispatch header constants in MailConstants that control post-processing of a consumed mail message used header values outside the Camel namespace (copyTo, moveTo, delete) and were therefore not filtered by the default HeaderFilterStrategy. They have been renamed to follow the Camel naming convention (companion to the CAMEL-23522 mail.smtp.* hardening). The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

MailConstants.MAIL_COPY_TO

copyTo

CamelMailCopyTo

MailConstants.MAIL_MOVE_TO

moveTo

CamelMailMoveTo

MailConstants.MAIL_DELETE

delete

CamelMailDelete

The standard RFC 5322 message header constants (MAIL_SUBJECT = Subject, MAIL_FROM = From, MAIL_TO = To, MAIL_CC = Cc, MAIL_BCC = Bcc, MAIL_REPLY_TO = Reply-To, MAIL_CONTENT_TYPE = contentType) are unchanged, as they map directly to the corresponding email fields and renaming them would break mail interoperability.

The equally-named copyTo and moveTo endpoint URI options on the mail consumer are also unchanged; only the Exchange header values are affected.

Routes that reference the constants symbolically (for example setHeader(MailConstants.MAIL_DELETE, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("delete", true)) must be updated to use the new value (setHeader("CamelMailDelete", true)).

As a consequence, the generated Endpoint DSL header accessors on MailHeaderNameBuilder have been renamed: copyTo()mailCopyTo(), moveTo()mailMoveTo(), and delete()mailDelete().

camel-github2 - potential breaking change

The producer-side Exchange header constants in GitHub2Constants have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

GitHub2Constants.GITHUB_PULLREQUEST

GitHubPullRequest

CamelGitHubPullRequest

GitHub2Constants.GITHUB_INRESPONSETO

GitHubInResponseTo

CamelGitHubInResponseTo

GitHub2Constants.GITHUB_PULLREQUEST_HEAD_COMMIT_SHA

GitHubPullRequestHeadCommitSHA

CamelGitHubPullRequestHeadCommitSha

GitHub2Constants.GITHUB_ISSUE_TITLE

GitHubIssueTitle

CamelGitHubIssueTitle

The consumer-side constants (GITHUB_COMMIT_AUTHOR, GITHUB_COMMIT_COMMITTER, GITHUB_COMMIT_SHA, GITHUB_COMMIT_URL, GITHUB_EVENT_PAYLOAD) were already Camel-prefixed (CamelGitHubCommitAuthor, etc.) and are unchanged, as is the GITHUB_CLIENT registry-lookup key (github2Client).

Routes that reference the constants symbolically (for example setHeader(GitHub2Constants.GITHUB_PULLREQUEST, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("GitHubPullRequest", …​)) must be updated to use the new value (setHeader("CamelGitHubPullRequest", …​)).

As a consequence, the generated Endpoint DSL header accessor gitHubPullRequestHeadCommitSHA() on GitHub2HeaderNameBuilder has been renamed to gitHubPullRequestHeadCommitSha(). The remaining accessors (gitHubPullRequest(), gitHubInResponseTo(), gitHubIssueTitle()) keep their names but now return the new Camel-prefixed values.

The deprecated camel-github component (predecessor of camel-github2) is not affected by this change on the 4.18.x line; it remains present in 4.18.x as deprecated and was only removed on the 4.21 development branch.

camel-elasticsearch / camel-opensearch - potential breaking change

The Exchange header constants in ElasticsearchConstants and OpensearchConstants have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed.

ElasticsearchConstants:

Constant Previous value New value

ElasticsearchConstants.PARAM_OPERATION

operation

CamelElasticsearchOperation

ElasticsearchConstants.PARAM_INDEX_ID

indexId

CamelElasticsearchIndexId

ElasticsearchConstants.PARAM_INDEX_NAME

indexName

CamelElasticsearchIndexName

ElasticsearchConstants.PARAM_DOCUMENT_CLASS

documentClass

CamelElasticsearchDocumentClass

ElasticsearchConstants.PARAM_WAIT_FOR_ACTIVE_SHARDS

waitForActiveShards

CamelElasticsearchWaitForActiveShards

ElasticsearchConstants.PARAM_SCROLL_KEEP_ALIVE_MS

scrollKeepAliveMs

CamelElasticsearchScrollKeepAliveMs

ElasticsearchConstants.PARAM_SCROLL

useScroll

CamelElasticsearchUseScroll

ElasticsearchConstants.PARAM_SIZE

size

CamelElasticsearchSize

ElasticsearchConstants.PARAM_FROM

from

CamelElasticsearchFrom

ElasticsearchConstants.PARAM_DOCUMENT_MODE

enableDocumentOnlyMode

CamelElasticsearchEnableDocumentOnlyMode

OpensearchConstants:

Constant Previous value New value

OpensearchConstants.PARAM_OPERATION

operation

CamelOpensearchOperation

OpensearchConstants.PARAM_INDEX_ID

indexId

CamelOpensearchIndexId

OpensearchConstants.PARAM_INDEX_NAME

indexName

CamelOpensearchIndexName

OpensearchConstants.PARAM_DOCUMENT_CLASS

documentClass

CamelOpensearchDocumentClass

OpensearchConstants.PARAM_WAIT_FOR_ACTIVE_SHARDS

waitForActiveShards

CamelOpensearchWaitForActiveShards

OpensearchConstants.PARAM_SCROLL_KEEP_ALIVE_MS

scrollKeepAliveMs

CamelOpensearchScrollKeepAliveMs

OpensearchConstants.PARAM_SCROLL

useScroll

CamelOpensearchUseScroll

OpensearchConstants.PARAM_SIZE

size

CamelOpensearchSize

OpensearchConstants.PARAM_FROM

from

CamelOpensearchFrom

ElasticsearchConstants.PROPERTY_SCROLL_ES_QUERY_COUNT and OpensearchConstants.PROPERTY_SCROLL_OPENSEARCH_QUERY_COUNT were already Camel-prefixed (CamelElasticsearchScrollQueryCount / CamelOpenSearchScrollQueryCount) and are unchanged.

Routes that reference the constants symbolically (for example setHeader(ElasticsearchConstants.PARAM_INDEX_NAME, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("indexName", …​)) must be updated to use the new value (setHeader("CamelElasticsearchIndexName", …​)).

The generated Endpoint DSL header accessors on ElasticsearchHeaderNameBuilder and OpensearchHeaderNameBuilder have been renamed accordingly (operation()elasticsearchOperation() / opensearchOperation(), indexId()elasticsearchIndexId() / opensearchIndexId(), etc.).

camel-google-functions / camel-google-secret-manager - potential breaking change

The Exchange header constants in GoogleCloudFunctionsConstants and GoogleSecretManagerConstants that carried a GoogleCloudFunctions / GoogleSecretManager prefix are not in the Camel namespace and were therefore not filtered by the default HeaderFilterStrategy. They have been renamed to add the Camel prefix. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

GoogleCloudFunctionsConstants.OPERATION

GoogleCloudFunctionsOperation

CamelGoogleCloudFunctionsOperation

GoogleCloudFunctionsConstants.ENTRY_POINT

GoogleCloudFunctionsEntryPoint

CamelGoogleCloudFunctionsEntryPoint

GoogleCloudFunctionsConstants.RUNTIME

GoogleCloudFunctionsRuntime

CamelGoogleCloudFunctionsRuntime

GoogleCloudFunctionsConstants.SOURCE_ARCHIVE_URL

GoogleCloudFunctionsSourceArchiveUrl

CamelGoogleCloudFunctionsSourceArchiveUrl

GoogleCloudFunctionsConstants.RESPONSE_OBJECT

GoogleCloudFunctionsResponseObject

CamelGoogleCloudFunctionsResponseObject

GoogleSecretManagerConstants.OPERATION

GoogleSecretManagerOperation

CamelGoogleSecretManagerOperation

The GoogleSecretManagerConstants.SECRET_ID, VERSION_ID and REPLICATION constants were already Camel-prefixed and are unchanged.

Routes that reference the constants symbolically (for example setHeader(GoogleCloudFunctionsConstants.OPERATION, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("GoogleCloudFunctionsOperation", …​)) must be updated to use the new value (setHeader("CamelGoogleCloudFunctionsOperation", …​)).

The generated Endpoint DSL header accessor names are unchanged (for example googleCloudFunctionsOperation()), since the Camel prefix is stripped when deriving the accessor name; the accessors now return the new Camel-prefixed values.

The companion rename for camel-google-vision, camel-google-text-to-speech and camel-google-speech-to-text from the same main-branch PR (#23467) is not backported to 4.18.x because those components were added after the 4.18.x branch point and do not exist on this maintenance branch.

camel-openstack - potential breaking change

The Exchange header constants in OpenstackConstants, KeystoneConstants, NovaConstants, CinderConstants, GlanceConstants, NeutronConstants, and SwiftConstants have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed.

Common constants (in OpenstackConstants):

Constant Previous value New value

OpenstackConstants.OPERATION

operation

CamelOpenstackOperation

OpenstackConstants.ID

ID

CamelOpenstackId

OpenstackConstants.NAME

name

CamelOpenstackName

OpenstackConstants.DESCRIPTION

description

CamelOpenstackDescription

OpenstackConstants.PROPERTIES

properties

CamelOpenstackProperties

Keystone (KeystoneConstants):

Constant Previous value New value

KeystoneConstants.DESCRIPTION

description

CamelOpenstackKeystoneDescription

KeystoneConstants.DOMAIN_ID

domainId

CamelOpenstackKeystoneDomainId

KeystoneConstants.PARENT_ID

parentId

CamelOpenstackKeystoneParentId

KeystoneConstants.PASSWORD

password

CamelOpenstackKeystonePassword

KeystoneConstants.EMAIL

email

CamelOpenstackKeystoneEmail

KeystoneConstants.USER_ID

userId

CamelOpenstackKeystoneUserId

KeystoneConstants.GROUP_ID

groupId

CamelOpenstackKeystoneGroupId

Nova (NovaConstants):

Constant Previous value New value

NovaConstants.FLAVOR_ID

FlavorId

CamelOpenstackNovaFlavorId

NovaConstants.RAM

RAM

CamelOpenstackNovaRam

NovaConstants.VCPU

VCPU

CamelOpenstackNovaVcpu

NovaConstants.DISK

disk

CamelOpenstackNovaDisk

NovaConstants.SWAP

swap

CamelOpenstackNovaSwap

NovaConstants.RXTXFACTOR

rxtxFactor

CamelOpenstackNovaRxtxFactor

NovaConstants.ADMIN_PASSWORD

AdminPassword

CamelOpenstackNovaAdminPassword

NovaConstants.IMAGE_ID

ImageId

CamelOpenstackNovaImageId

NovaConstants.KEYPAIR_NAME

KeypairName

CamelOpenstackNovaKeypairName

NovaConstants.NETWORK

NetworkId

CamelOpenstackNovaNetworkId

NovaConstants.ACTION

action

CamelOpenstackNovaAction

Cinder (CinderConstants):

Constant Previous value New value

CinderConstants.SIZE

size

CamelOpenstackCinderSize

CinderConstants.VOLUME_TYPE

volumeType

CamelOpenstackCinderVolumeType

CinderConstants.IMAGE_REF

imageRef

CamelOpenstackCinderImageRef

CinderConstants.SNAPSHOT_ID

snapshotId

CamelOpenstackCinderSnapshotId

CinderConstants.IS_BOOTABLE

isBootable

CamelOpenstackCinderIsBootable

CinderConstants.VOLUME_ID

volumeId

CamelOpenstackCinderVolumeId

CinderConstants.FORCE

force

CamelOpenstackCinderForce

Glance (GlanceConstants):

Constant Previous value New value

GlanceConstants.DISK_FORMAT

diskFormat

CamelOpenstackGlanceDiskFormat

GlanceConstants.CONTAINER_FORMAT

containerFormat

CamelOpenstackGlanceContainerFormat

GlanceConstants.OWNER

owner

CamelOpenstackGlanceOwner

GlanceConstants.IS_PUBLIC

isPublic

CamelOpenstackGlanceIsPublic

GlanceConstants.MIN_RAM

minRam

CamelOpenstackGlanceMinRam

GlanceConstants.MIN_DISK

minDisk

CamelOpenstackGlanceMinDisk

GlanceConstants.SIZE

size

CamelOpenstackGlanceSize

GlanceConstants.CHECKSUM

checksum

CamelOpenstackGlanceChecksum

Neutron (NeutronConstants):

Constant Previous value New value

NeutronConstants.TENANT_ID

tenantId

CamelOpenstackNeutronTenantId

NeutronConstants.NETWORK_ID

networkId

CamelOpenstackNeutronNetworkId

NeutronConstants.ADMIN_STATE_UP

adminStateUp

CamelOpenstackNeutronAdminStateUp

NeutronConstants.NETWORK_TYPE

networkType

CamelOpenstackNeutronNetworkType

NeutronConstants.PHYSICAL_NETWORK

physicalNetwork

CamelOpenstackNeutronPhysicalNetwork

NeutronConstants.SEGMENT_ID

segmentId

CamelOpenstackNeutronSegmentId

NeutronConstants.IS_SHARED

isShared

CamelOpenstackNeutronIsShared

NeutronConstants.IS_ROUTER_EXTERNAL

isRouterExternal

CamelOpenstackNeutronIsRouterExternal

NeutronConstants.ENABLE_DHCP

enableDHCP

CamelOpenstackNeutronEnableDhcp

NeutronConstants.GATEWAY

gateway

CamelOpenstackNeutronGateway

NeutronConstants.IP_VERSION

ipVersion

CamelOpenstackNeutronIpVersion

NeutronConstants.CIDR

cidr

CamelOpenstackNeutronCidr

NeutronConstants.SUBNET_POOL

subnetPools

CamelOpenstackNeutronSubnetPools

NeutronConstants.DEVICE_ID

deviceId

CamelOpenstackNeutronDeviceId

NeutronConstants.MAC_ADDRESS

macAddress

CamelOpenstackNeutronMacAddress

NeutronConstants.ROUTER_ID

routerId

CamelOpenstackNeutronRouterId

NeutronConstants.SUBNET_ID

subnetId

CamelOpenstackNeutronSubnetId

NeutronConstants.PORT_ID

portId

CamelOpenstackNeutronPortId

NeutronConstants.ITERFACE_TYPE

interfaceType

CamelOpenstackNeutronInterfaceType

Swift (SwiftConstants):

Constant Previous value New value

SwiftConstants.CONTAINER_NAME

containerName

CamelOpenstackSwiftContainerName

SwiftConstants.OBJECT_NAME

objectName

CamelOpenstackSwiftObjectName

SwiftConstants.LIMIT

limit

CamelOpenstackSwiftLimit

SwiftConstants.MARKER

marker

CamelOpenstackSwiftMarker

SwiftConstants.END_MARKER

end_marker

CamelOpenstackSwiftEndMarker

SwiftConstants.DELIMITER

delimiter

CamelOpenstackSwiftDelimiter

SwiftConstants.PATH

path

CamelOpenstackSwiftPath

SwiftConstants.CONTAINER_METADATA_PREFIX, SwiftConstants.VERSIONS_LOCATION, SwiftConstants.CONTAINER_READ, and SwiftConstants.CONTAINER_WRITE intentionally keep their previous values (X-Container-Meta-, X-Versions-Location, X-Container-Read, X-Container-Write) because they are part of the Swift HTTP protocol contract used by openstack4j to forward container metadata and ACLs to the Swift backend. Renaming them would break interoperability with the Swift API.

Routes that reference the constants symbolically (for example setHeader(OpenstackConstants.OPERATION, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("operation", …​)) must be updated to use the new value (setHeader("CamelOpenstackOperation", …​)).

The generated Endpoint DSL header accessors on each component’s HeaderNameBuilder are renamed accordingly (operation()openstackOperation(), password()openstackKeystonePassword(), adminPassword()openstackNovaAdminPassword(), etc.).

camel-shiro - potential breaking change

The three Exchange header constants in ShiroSecurityConstants that drive Shiro authentication used header values outside the Camel namespace (SHIRO_SECURITY_TOKEN, SHIRO_SECURITY_USERNAME, SHIRO_SECURITY_PASSWORD) and were therefore not filtered by the default HeaderFilterStrategy. They have been renamed to follow the Camel naming convention. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

ShiroSecurityConstants.SHIRO_SECURITY_TOKEN

SHIRO_SECURITY_TOKEN

CamelShiroSecurityToken

ShiroSecurityConstants.SHIRO_SECURITY_USERNAME

SHIRO_SECURITY_USERNAME

CamelShiroSecurityUsername

ShiroSecurityConstants.SHIRO_SECURITY_PASSWORD

SHIRO_SECURITY_PASSWORD

CamelShiroSecurityPassword

These headers carry credentials and a serialized authentication token, so filtering them at transport boundaries by default is particularly important.

Routes that reference the constants symbolically (for example setHeader(ShiroSecurityConstants.SHIRO_SECURITY_USERNAME, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("SHIRO_SECURITY_USERNAME", …​)) must be updated to use the new value (setHeader("CamelShiroSecurityUsername", …​)).

Because the three header values are now in the Camel* namespace, transports that filter Camel-internal headers by default (JMS, CXF, HTTP, etc.) will strip the serialized Shiro authentication token before publishing. This is the intended behavior for untrusted producers. Trusted Shiro-over-transport routes that previously relied on the token surviving the boundary must opt those three headers back in via a custom HeaderFilterStrategy, for example:

public class ShiroFriendlyJmsHeaderFilterStrategy extends JmsHeaderFilterStrategy {
    @Override
    public boolean applyFilterToCamelHeaders(String name, Object value, Exchange ex) {
        if (isShiroSecurityHeader(name)) {
            return false;
        }
        return super.applyFilterToCamelHeaders(name, value, ex);
    }

    @Override
    public boolean applyFilterToExternalHeaders(String name, Object value, Exchange ex) {
        if (isShiroSecurityHeader(name)) {
            return false;
        }
        return super.applyFilterToExternalHeaders(name, value, ex);
    }

    private static boolean isShiroSecurityHeader(String name) {
        return ShiroSecurityConstants.SHIRO_SECURITY_TOKEN.equalsIgnoreCase(name)
                || ShiroSecurityConstants.SHIRO_SECURITY_USERNAME.equalsIgnoreCase(name)
                || ShiroSecurityConstants.SHIRO_SECURITY_PASSWORD.equalsIgnoreCase(name);
    }
}

jmsComponent.setHeaderFilterStrategy(new ShiroFriendlyJmsHeaderFilterStrategy());

A worked example is in ShiroOverJmsTest in the camel-itest module.

camel-web3j - potential breaking change

The Exchange header constants in Web3jConstants have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

Web3jConstants.ID

ID

CamelWeb3jId

Web3jConstants.OPERATION

OPERATION

CamelWeb3jOperation

Web3jConstants.AT_BLOCK

AT_BLOCK

CamelWeb3jAtBlock

Web3jConstants.ADDRESS

ADDRESS

CamelWeb3jAddress

Web3jConstants.ADDRESSES

ADDRESSES

CamelWeb3jAddresses

Web3jConstants.FROM_ADDRESS

FROM_ADDRESS

CamelWeb3jFromAddress

Web3jConstants.TO_ADDRESS

TO_ADDRESS

CamelWeb3jToAddress

Web3jConstants.POSITION

POSITION

CamelWeb3jPosition

Web3jConstants.BLOCK_HASH

BLOCK_HASH

CamelWeb3jBlockHash

Web3jConstants.TRANSACTION_HASH

TRANSACTION_HASH

CamelWeb3jTransactionHash

Web3jConstants.SHA3_HASH_OF_DATA_TO_SIGN

SHA3_HASH_OF_DATA_TO_SIGN

CamelWeb3jSha3HashOfDataToSign

Web3jConstants.SIGNED_TRANSACTION_DATA

SIGNED_TRANSACTION_DATA

CamelWeb3jSignedTransactionData

Web3jConstants.FULL_TRANSACTION_OBJECTS

FULL_TRANSACTION_OBJECTS

CamelWeb3jFullTransactionObjects

Web3jConstants.INDEX

INDEX

CamelWeb3jIndex

Web3jConstants.SOURCE_CODE

SOURCE_CODE

CamelWeb3jSourceCode

Web3jConstants.FILTER_ID

FILTER_ID

CamelWeb3jFilterId

Web3jConstants.DATABASE_NAME

DATABASE_NAME

CamelWeb3jDatabaseName

Web3jConstants.KEY_NAME

KEY_NAME

CamelWeb3jKeyName

Web3jConstants.NONCE

NONCE

CamelWeb3jNonce

Web3jConstants.HEADER_POW_HASH

HEADER_POW_HASH

CamelWeb3jHeaderPowHash

Web3jConstants.MIX_DIGEST

MIX_DIGEST

CamelWeb3jMixDigest

Web3jConstants.CLIENT_ID

CLIENT_ID

CamelWeb3jClientId

Web3jConstants.GAS_PRICE

GAS_PRICE

CamelWeb3jGasPrice

Web3jConstants.GAS_LIMIT

GAS_LIMIT

CamelWeb3jGasLimit

Web3jConstants.VALUE

VALUE

CamelWeb3jValue

Web3jConstants.DATA

DATA

CamelWeb3jData

Web3jConstants.FROM_BLOCK

FROM_BLOCK

CamelWeb3jFromBlock

Web3jConstants.TO_BLOCK

TO_BLOCK

CamelWeb3jToBlock

Web3jConstants.TOPICS

TOPICS

CamelWeb3jTopics

Web3jConstants.PRIORITY

PRIORITY

CamelWeb3jPriority

Web3jConstants.TTL

TTL

CamelWeb3jTtl

Web3jConstants.PRIVATE_FOR

PRIVATE_FOR

CamelWeb3jPrivateFor

Web3jConstants.PRIVATE_FROM

PRIVATE_FROM

CamelWeb3jPrivateFrom

Web3jConstants.ERROR_CODE

ERROR_CODE

CamelWeb3jErrorCode

Web3jConstants.ERROR_DATA

ERROR_DATA

CamelWeb3jErrorData

Web3jConstants.ERROR_MESSAGE

ERROR_MESSAGE

CamelWeb3jErrorMessage

Web3jConstants.HEADER_STATUS

status

CamelWeb3jStatus

Web3jConstants.HEADER_OPERATION

operation

CamelWeb3jHeaderOperation

Web3jConstants.ETH_HASHRATE

ETH_HASHRATE

CamelWeb3jEthHashrate

Routes that reference the constants symbolically (for example setHeader(Web3jConstants.FROM_ADDRESS, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("FROM_ADDRESS", …​)) must be updated to use the new value (setHeader("CamelWeb3jFromAddress", …​)).

The Web3jConstants.ETH_HASHRATE constant is dual-purpose: it is both the CamelWeb3jOperation value that dispatches the ethHashrate RPC and the header name read by the ETH_SUBMIT_HASHRATE operation. Routes that referenced the literal string "ETH_HASHRATE" (in either role) must be updated to "CamelWeb3jEthHashrate". Routes using the symbolic constant reference are unaffected. The other producer-dispatch operation identifiers (WEB3_CLIENT_VERSION, ETH_GAS_PRICE, ETH_SEND_TRANSACTION, …​) keep their previous string values because they are operation enum values rather than Exchange header names.

As a consequence, the generated Endpoint DSL header accessors on Web3jHeaderNameBuilder have been renamed accordingly:

  • iD()web3jId()

  • atBlock()web3jAtBlock()

  • aDDRESS()web3jAddress()

  • aDDRESSES()web3jAddresses()

  • fromAddress()web3jFromAddress()

  • toAddress()web3jToAddress()

  • pOSITION()web3jPosition()

  • blockHash()web3jBlockHash()

  • transactionHash()web3jTransactionHash()

  • sha3HashOfDataToSign()web3jSha3HashOfDataToSign()

  • signedTransactionData()web3jSignedTransactionData()

  • fullTransactionObjects()web3jFullTransactionObjects()

  • iNDEX()web3jIndex()

  • sourceCode()web3jSourceCode()

  • filterId()web3jFilterId()

  • databaseName()web3jDatabaseName()

  • keyName()web3jKeyName()

  • nONCE()web3jNonce()

  • headerPowHash()web3jHeaderPowHash()

  • mixDigest()web3jMixDigest()

  • clientId()web3jClientId()

  • gasPrice()web3jGasPrice()

  • gasLimit()web3jGasLimit()

  • vALUE()web3jValue()

  • dATA()web3jData()

  • fromBlock()web3jFromBlock()

  • toBlock()web3jToBlock()

  • tOPICS()web3jTopics()

  • pRIORITY()web3jPriority()

  • tTL()web3jTtl()

  • privateFor()web3jPrivateFor()

  • privateFrom()web3jPrivateFrom()

  • errorCode()web3jErrorCode()

  • errorData()web3jErrorData()

  • errorMessage()web3jErrorMessage()

  • status()web3jStatus()

  • operation()web3jHeaderOperation()

  • ethHashrate()web3jEthHashrate()

A new accessor web3jOperation() is also generated for Web3jConstants.OPERATION (the producer dispatch header). This constant did not appear in the catalog previously, so no DSL accessor renaming applies to it.

camel-milo - potential breaking change

The MiloConstants.HEADER_AWAIT constant, which controls whether milo-client writes are awaited, used the header value await — outside the Camel namespace and therefore not filtered by the default HeaderFilterStrategy. It has been renamed to follow the Camel naming convention. The Java field name is unchanged; only the header string value has changed:

Constant Previous value New value

MiloConstants.HEADER_AWAIT

await

CamelMiloAwait

MiloConstants.HEADER_NODE_IDS was already Camel-prefixed (CamelMiloNodeIds) and is unchanged.

Routes that reference the constant symbolically (for example setHeader(MiloConstants.HEADER_AWAIT, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("await", …​)) must be updated to use the new value (setHeader("CamelMiloAwait", …​)).

As a consequence, the generated Endpoint DSL header accessor await() on MiloClientHeaderNameBuilder has been renamed to miloAwait().

camel-mongodb-gridfs

The Exchange header values exposed by GridFsConstants have been renamed to follow the standard Camel naming convention, bringing camel-mongodb-gridfs in line with the parent camel-mongodb component (MongoDbConstants.OPERATION_HEADER = "CamelMongoDbOperation"). The Java field names are unchanged, so routes referencing the constants symbolically (e.g. GridFsConstants.GRIDFS_OPERATION, GridFsConstants.GRIDFS_OBJECT_ID) continue to work without modification. However, routes that set or read these headers using the raw string values must be updated:

  • gridfs.operationCamelGridFsOperation

  • gridfs.metadataCamelGridFsMetadata

  • gridfs.chunksizeCamelGridFsChunkSize

  • gridfs.objectidCamelGridFsObjectId

  • gridfs.fileidCamelGridFsFileId

As a consequence, the generated Endpoint DSL header accessors on GridFsHeaderNameBuilder have been renamed accordingly:

  • gridfsOperation()gridFsOperation()

  • gridfsMetadata()gridFsMetadata()

  • gridfsChunksize()gridFsChunkSize()

  • gridfsObjectid()gridFsObjectId()

  • gridfsFileid()gridFsFileId()

camel-solr

The two Exchange header prefix constants in SolrConstants have been renamed to follow the Camel naming convention already used by the other constants in the same file (which were renamed in 4.10 under CAMEL-21697). The Java field names are unchanged; only the prefix string values have changed:

Constant Previous value New value

SolrConstants.HEADER_FIELD_PREFIX

SolrField.

CamelSolrField.

SolrConstants.HEADER_PARAM_PREFIX

SolrParam.

CamelSolrParam.

Routes that reference the constants symbolically (for example setHeader(SolrConstants.HEADER_FIELD_PREFIX + "id", …​)) continue to work without changes. Routes that set the headers by their literal string value (for example setHeader("SolrField.id", …​) or setHeader("SolrParam.commit", …​)) must be updated to use the new prefix (CamelSolrField.id, CamelSolrParam.commit).

Because the renamed prefixes now begin with Camel, they are stripped by the standard transport HeaderFilterStrategy (HttpHeaderFilterStrategy, etc.) when crossing a transport boundary, by design — Camel* headers are framework-internal and are not propagated over the wire. Routes that bridge an external transport (HTTP, JMS, …​) into a solr: producer and want to drive Solr document fields or query parameters from a header supplied by the sender must therefore carry the value in a non-Camel-prefixed application header and map it to the appropriate CamelSolrField. / CamelSolrParam. header in the route between the transport from and the solr: to.

Upgrading from 4.18.0 to 4.18.1

camel-bom

The camel-test module has been removed from camel-bom. This module was included by mistake, as since Camel 4, this is not a JAR but a pom.xml file. Camel end users should use the camel-test-junit5 / camel-test-junit6 JARs and the others directly.

camel-yaml-io / camel-xml-io

In the YAML DSL we have renamed routePolicy to routePolicyRef on the route node, as that is the correct name.

Saga EIP

The Saga EIP has fixed the model for how to configure completion and compensation URIs.

For Java DSL there is no changes, but XML and YAML DSL is affected. Here the <compensation> and <completion> tags has been changed to be an attribute on <saga> instead as shown below:

Before:

<route>
    <from uri="direct:start"/>
    <saga sagaService="mySagaService">
        <compensation uri="mock:compensation"/>
        <completion uri="mock:completion"/>
        <option key="myOptionKey">
            <constant>myOptionValue</constant>
        </option>
        <option key="myOptionKey2">
            <constant>myOptionValue2</constant>
        </option>
    </saga>
    <choice>
        <when>
            <simple>${body} == 'fail'</simple>
            <throwException exceptionType="java.lang.RuntimeException" message="fail"/>
        </when>
    </choice>
    <to uri="mock:end"/>
</route>

In YAML DSL the changes are even simpler as the endpoint is moved from uri to the value of completion or compensation.

- route:
    from:
      uri: direct:start
      steps:
        - saga:
            sagaService: mySagaService
            compensation:
              uri: mock:compensation
            completion:
              uri: mock:completion
            key: myOptionKey2
        - choice:
            when:
              - expression:
                  simple:
                    expression: "${body} == 'fail'"
                steps:
                  - throwException:
                      message: fail
                      exceptionType: java.lang.RuntimeException
        - to:
            uri: mock:end

After:

<route>
    <from uri="direct:start"/>
    <saga sagaService="mySagaService" compensation="mock:compensation" completion="mock:completion">
        <option key="myOptionKey">
            <constant>myOptionValue</constant>
        </option>
        <option key="myOptionKey2">
            <constant>myOptionValue2</constant>
        </option>
    </saga>
    <choice>
        <when>
            <simple>${body} == 'fail'</simple>
            <throwException exceptionType="java.lang.RuntimeException" message="fail"/>
        </when>
    </choice>
    <to uri="mock:end"/>
</route>
- route:
    from:
      uri: direct:start
      steps:
        - saga:
            sagaService: mySagaService
            compensation: mock:compensation
            completion: mock:completion
            key: myOptionKey2
        - choice:
            when:
              - expression:
                  simple:
                    expression: "${body} == 'fail'"
                steps:
                  - throwException:
                      message: fail
                      exceptionType: java.lang.RuntimeException
        - to:
            uri: mock:end

camel-simple

In the simple language then init blocks syntax has changed to require that each variable ends with a semicolon and new line (no trailing comments etc is allowed)

For example

    - setBody:
        simple:
          expression: |-
            $init{
              // this is a java like comment
              $sum := ${sum(${header.lines},100)}

              $sku := ${iif(${body} contains 'Camel',123,999)}
            }init$
            orderId=$sku,total=$sum

Should be changed to have semicolons as shown below:

    - setBody:
        simple:
          expression: |-
            $init{
              // this is a java like comment
              $sum := ${sum(${header.lines},100)};

              $sku := ${iif(${body} contains 'Camel',123,999)};
            }init$
            orderId=$sku,total=$sum

camel-mail

When configured a custom IdempotentRepository on camel-mail endpoint, then Camel will now auto-start the bean which is similar to what camel-file do as well.

camel-json-patch

The camel-json-patch is now deprecated - the library it uses is not active maintained and this module does not work with Jackon 3.

camel-openapi-java

When using code first Rest DSL and have configured base.path then this will now be exclusively used for the returned server url in the API specification.

For example here we set base.path=cheese:

restConfiguration().component("jetty").host("localhost").port(getPort())
        .contextPath("myapp")
        .apiContextPath("/api-doc")
        .apiProperty("cors", "true").apiProperty("base.path", "cheese")
        .apiProperty("api.title", "The hello rest thing").apiProperty("api.version", "1.2.3");

Then the generated API specification now returns:

  "servers" : [ {
    "url" : "http://localhost:58678/cheese"
  } ],

Previously the context-path would always be used:

  "servers" : [ {
    "url" : "http://localhost:58678/myapp"
  } ],

The intention is to allow to configure the base.path as is in the return API specification.

Upgrading Camel 4.17 to 4.18

camel-simple

The simple language has deprecated binary operators that uses space in the name:

  • not contains use !contains instead

  • not regex use !regex instead

  • not range use !range instead

  • starts with use startsWith instead

  • ends with use endsWith instead

camel-file

The org.apache.camel.component.file.GenericFileOperations has added method storeFileDirectly.

camel-docling

All not working metadata headers have been removed. The option extractAllMetadata has been removed. Using includeRawMetadata will have the same effect given that there is no more customMetadata available.

It corresponds to the removal of functionality no more working since 4.17. Given that this functionality was never available in a LTS version,that the next LST version is the next one and the fix requires important change in upstream dependency; it is not going through a deprecation phase and removed directly.

DoclingDocument return type

The CONVERT_TO_JSON and EXTRACT_STRUCTURED_DATA operations now return a DoclingDocument object (ai.docling.core.DoclingDocument) in the exchange body instead of a raw JSON string. This applies to both docling-serve API mode and CLI mode (where the JSON output is parsed into DoclingDocument via Jackson).

Code that previously received a String and manually deserialized it should be updated:

// Before (4.17)
String result = template.requestBody("direct:convert", filePath, String.class);
DoclingDocument doc = mapper.readValue(result, DoclingDocument.class);

// After (4.18)
DoclingDocument doc = template.requestBody("direct:convert", filePath, DoclingDocument.class);

The EXTRACT_METADATA operation also now uses DoclingDocument internally instead of re-parsing a JSON string, though the exchange body type (DocumentMetadata) is unchanged.

EXTRACT_STRUCTURED_DATA differentiation

The EXTRACT_STRUCTURED_DATA operation is now differentiated from CONVERT_TO_JSON when using the docling-serve API. It uses a dedicated request builder that enables table structure recognition (doTableStructure=true) by default. Additional enrichment features (code enrichment, formula enrichment, picture classification) can be enabled via the new configuration properties. Previously, both operations produced identical requests to the server.

The BATCH_EXTRACT_STRUCTURED_DATA operation now has its own dedicated implementation (processBatchStructuredData) that sends structured data requests with table structure recognition enabled, matching its single-document counterpart. Previously, it was handled as a plain batch JSON conversion.

processTimeout and HTTP read timeout

The processTimeout configuration property (default: 30000ms) now also controls the HTTP read timeout when using docling-serve API mode. Previously, the HTTP read timeout was not configurable and used the docling-java client library default. For complex PDF documents that require OCR or enrichment processing, increase processTimeout (e.g., to 120000 for 2 minutes).

OCR bridging to API mode

The enableOCR configuration property is now bridged to the docling-serve API mode when explicitly set to false: it sends doOcr(false) to the server to disable OCR. When left at its default value (true), the server uses its own defaults to preserve backward compatibility. For explicit API-mode OCR control, use the new doOcr property instead.

New advanced configuration properties

18 new configuration properties have been added to expose the full ConvertDocumentOptions from the docling-serve SDK: doOcr, forceOcr, ocrEngine, pdfBackend, tableMode, tableCellMatching, doTableStructure, pipeline, doCodeEnrichment, doFormulaEnrichment, doPictureClassification, doPictureDescription, includeImages, imageExportMode, abortOnError, documentTimeout, imagesScale, and mdPageBreakPlaceholder. All default to null and only take effect when explicitly set. These options are applied to every docling-serve API request via the applyConfigurationToOptions method.

camel-qdrant

The class org.apache.camel.component.qdrant.Qdrant.Headers has been removed. It was deprecated since 4.15. It is replaced by org.apache.camel.component.qdrant.QdrantHeaders.

camel-tahu

The upgrade of Tahu from 1.0.17 to 1.0.18 introduced an API break. HostApplicationEventHandler has been renamed to MultiHostApplicationEventHandler and introduced one more parameter on all methods.

Even if the interface HostApplicationEventHandler is public, I do not expect Camel users to use the implementation TahuHostApplicationEventHandler from Camel. Also the change would be relatively trivial. So replacing it without deprecating it first in order to be able to use the latest Tahu version right away.

Consequently, there is an API break org.apache.camel.tahu.handlers.TahuHostApplicationEventHandler has been removed. It is replaced by org.apache.camel.tahu.handlers.MultiTahuHostApplicationEventHandler.

camel-platform-http-vertx and Rest DSL contract-first

When using Rest DSL in contract first style, then the HTTP engine (vertx-web) instead of a single router to handle all incoming Rest API calls, is now one unique router per API endpoint. This change can affect HTTP request validation as vertx/Quarkus is now also performing this per API endpoint according to the API specification.

All together this would make Camel behave similar for Rest DSL for both code first and contract first style.

camel-nats

The default headerFilterStrategy is now a new NatsHeaderFilterStrategy that filters headers starting with Camel / camel (case-insensitive) in both the inbound and outbound directions, aligning the component with the rest of the Camel component catalog (camel-kafka, camel-mail, camel-coap, camel-google-pubsub, …​). Routes that relied on passing through these header names from NATS messages can supply a custom headerFilterStrategy to restore the previous behaviour.

camel-xmpp

The default headerFilterStrategy is now a new XmppHeaderFilterStrategy that filters headers starting with Camel / camel (case-insensitive) in both the inbound and outbound directions, aligning the component with the rest of the Camel component catalog (camel-kafka, camel-mail, camel-coap, camel-google-pubsub, …​). Routes that relied on passing through these header names from XMPP messages can supply a custom headerFilterStrategy to restore the previous behaviour.

Component deprecation

The camel-olingo2 and camel-olingo4 component are deprecated. This is due the Apache Olingo project is EOL and has been moved to the attic and is no longer maintained.

camel-vertx-websocket

The vertx-websocket consumer now applies a HeaderFilterStrategy to the WebSocket query and path parameters before mapping them into the Camel message headers. The new default VertxWebsocketHeaderFilterStrategy filters headers starting with Camel / camel (case-insensitive) in both the inbound and outbound directions, aligning the component with the rest of the Camel component catalog (camel-coap, camel-kafka, camel-nats, …​). A new headerFilterStrategy endpoint option is available; routes that relied on receiving Camel-prefixed header names from WebSocket query or path parameters can supply a custom headerFilterStrategy to restore the previous behaviour.

camel-atmosphere-websocket

The atmosphere-websocket consumer now applies the endpoint HeaderFilterStrategy to the WebSocket query parameters before mapping them into the Camel message headers. The inherited default HttpHeaderFilterStrategy filters headers starting with Camel / camel (case-insensitive). Routes that relied on receiving Camel-prefixed header names from WebSocket query parameters can supply a custom headerFilterStrategy to restore the previous behaviour.

camel-iggy

The iggy consumer now applies a HeaderFilterStrategy to the Iggy message user-headers before mapping them into the Camel message headers. The new default IggyHeaderFilterStrategy filters headers starting with Camel / camel (case-insensitive) in both the inbound and outbound directions, aligning the component with the rest of the Camel component catalog. A new headerFilterStrategy endpoint option is available; routes that relied on receiving Camel-prefixed user-header names from Iggy messages can supply a custom headerFilterStrategy to restore the previous behaviour.

camel-aws2-sqs

Sqs2HeaderFilterStrategy now also configures an inbound filter aligned with the existing outbound regex. Headers starting with Camel / camel (case-insensitive), breadcrumbId and org.apache.camel.* are now filtered in both the inbound and outbound directions, aligning the component with the rest of the Camel component catalog (camel-kafka, camel-mail, camel-coap, camel-google-pubsub, …​). Routes that relied on receiving these header names from inbound SQS messages can supply a custom headerFilterStrategy to restore the previous behaviour.

camel-aws2-sns

Sns2HeaderFilterStrategy now also configures an inbound filter aligned with the existing outbound regex. Headers starting with Camel / camel (case-insensitive), breadcrumbId and org.apache.camel.* are now filtered in both the inbound and outbound directions, aligning the component with the rest of the Camel component catalog. Routes that relied on receiving these header names on inbound SNS messages can supply a custom headerFilterStrategy to restore the previous behaviour.

camel-cxf - potential breaking change

The Exchange header constants in CxfConstants (module camel-cxf-common, shared by camel-cxf and camel-cxfrs) have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

CxfConstants.OPERATION_NAME

operationName

CamelCxfOperationName

CxfConstants.OPERATION_NAMESPACE

operationNamespace

CamelCxfOperationNamespace

Routes that reference the constant symbolically (for example setHeader(CxfConstants.OPERATION_NAME, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("operationName", …​)) must be updated to use the new value (setHeader("CamelCxfOperationName", …​)).

In particular, the documented cxfrs SimpleConsumer dispatch idiom that routes on the operation name by its literal header name must be updated:

// before
from("cxfrs:bean:rsServer?bindingStyle=SimpleConsumer")
    .recipientList(simple("direct:${header.operationName}"));

// after
from("cxfrs:bean:rsServer?bindingStyle=SimpleConsumer")
    .recipientList(simple("direct:${header.CamelCxfOperationName}"));

Behaviour change: cross-transport propagation of the operation header

Because the renamed header value now begins with Camel, it is filtered by the standard transport HeaderFilterStrategy (JmsHeaderFilterStrategy, HttpHeaderFilterStrategy, etc.) when crossing a transport boundary, by design — Camel* headers are framework-internal and are not propagated over the wire.

Routes that bridge an external transport (JMS, HTTP, …​) into a cxf: producer and select the SOAP operation from a header supplied by the sender must therefore carry the operation in a non-Camel-prefixed application header and map it to CxfConstants.OPERATION_NAME (CamelCxfOperationName) in the route between the transport from and the cxf: to:

<!-- before -->
<route>
    <from uri="jms:queue:bridge.cxf"/>
    <to uri="cxf://bean:serviceEndpoint"/>
</route>
<!-- caller sets the header keyed by the pre-rename value:
     setHeader("operationName", "greetMe") -->

<!-- after -->
<route>
    <from uri="jms:queue:bridge.cxf"/>
    <setHeader name="CamelCxfOperationName">
        <simple>${header.operationName}</simple>
    </setHeader>
    <to uri="cxf://bean:serviceEndpoint"/>
</route>
<!-- caller sets a non-Camel-prefixed application carrier header (any name
     that is not stripped by the transport HeaderFilterStrategy works);
     the route restores the CXF operation header after the transport hop. -->

The same pattern applies to HTTP-based bridges (platform-http/jetty/netty -http/httpcxf:) and any other transport whose default HeaderFilterStrategy filters Camel* headers.

camel-dns - potential breaking change

The Exchange header constants in DnsConstants have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

DnsConstants.DNS_CLASS

dns.class

CamelDnsClass

DnsConstants.DNS_NAME

dns.name

CamelDnsName

DnsConstants.DNS_DOMAIN

dns.domain

CamelDnsDomain

DnsConstants.DNS_SERVER

dns.server

CamelDnsServer

DnsConstants.DNS_TYPE

dns.type

CamelDnsType

DnsConstants.TERM

term

CamelDnsTerm

Routes that reference the constant symbolically (for example setHeader(DnsConstants.DNS_SERVER, …​)) continue to work without changes. Routes that set the header by its literal string value (for example setHeader("dns.server", …​) or setHeader("term", …​)) must be updated to use the new value:

// before
from("direct:start")
    .setHeader("dns.name", constant("www.example.com"))
    .setHeader("dns.type", constant("A"))
    .to("dns:lookup");

// after
from("direct:start")
    .setHeader("CamelDnsName", constant("www.example.com"))
    .setHeader("CamelDnsType", constant("A"))
    .to("dns:lookup");

Behaviour change: cross-transport propagation of dns.* headers

Because the renamed header values now begin with Camel, they are filtered by the standard transport HeaderFilterStrategy (JmsHeaderFilterStrategy, HttpHeaderFilterStrategy, etc.) when crossing a transport boundary, by design — Camel* headers are framework-internal and are not propagated over the wire.

Routes that bridge an external transport (HTTP, JMS, …​) into a dns: producer and let the sender choose the DNS operation parameters via headers must therefore carry those parameters in non-Camel-prefixed application headers and map them to the corresponding DnsConstants value in the route between the transport from and the dns: to. Allowing untrusted senders to drive DnsConstants.DNS_SERVER (the recursive resolver target in dns:dig) without such a mapping step is not the intended use of the component.

camel-kafka - potential breaking change

The Exchange header constants in KafkaConstants used header values in the lowercase / dotted kafka.* namespace, outside the Camel namespace, and were therefore not filtered by the default HeaderFilterStrategy on upstream HTTP / REST consumers. They have been renamed to follow the Camel naming convention used across the rest of the component catalog. The Java field names are unchanged; only the header string values have changed:

Constant Previous value New value

KafkaConstants.PARTITION_KEY

kafka.PARTITION_KEY

CamelKafkaPartitionKey

KafkaConstants.PARTITION

kafka.PARTITION

CamelKafkaPartition

KafkaConstants.KEY

kafka.KEY

CamelKafkaKey

KafkaConstants.TOPIC

kafka.TOPIC

CamelKafkaTopic

KafkaConstants.OVERRIDE_TOPIC

kafka.OVERRIDE_TOPIC

CamelKafkaOverrideTopic

KafkaConstants.OFFSET

kafka.OFFSET

CamelKafkaOffset

KafkaConstants.HEADERS

kafka.HEADERS

CamelKafkaHeaders

KafkaConstants.LAST_RECORD_BEFORE_COMMIT

kafka.LAST_RECORD_BEFORE_COMMIT

CamelKafkaLastRecordBeforeCommit

KafkaConstants.LAST_POLL_RECORD

kafka.LAST_POLL_RECORD

CamelKafkaLastPollRecord

KafkaConstants.TIMESTAMP

kafka.TIMESTAMP

CamelKafkaTimestamp

KafkaConstants.OVERRIDE_TIMESTAMP

kafka.OVERRIDE_TIMESTAMP

CamelKafkaOverrideTimestamp

KafkaConstants.KAFKA_RECORD_META

kafka.RECORD_META

CamelKafkaRecordMeta

KafkaConstants.MANUAL_COMMIT was already Camel-prefixed (CamelKafkaManualCommit) and is unchanged.

Routes that reference the constants symbolically (for example setHeader(KafkaConstants.OVERRIDE_TOPIC, …​)) continue to work without changes. Routes that set or read the headers by their literal string values (for example setHeader("kafka.OVERRIDE_TOPIC", …​) or Simple expressions such as ${headers[kafka.TOPIC]}) must be updated to use the new values:

// before
from("platform-http:/api/events")
    .setHeader("kafka.OVERRIDE_TOPIC", constant("events.topic"))
    .to("kafka:default?brokers=localhost:9092");

// after
from("platform-http:/api/events")
    .setHeader(KafkaConstants.OVERRIDE_TOPIC, constant("events.topic"))
    .to("kafka:default?brokers=localhost:9092");

The generated Endpoint DSL header accessors on KafkaEndpointBuilderFactory keep their method names (kafkaOverrideTopic(), kafkaTopic(), kafkaPartitionKey(), …​); only the returned string value reflects the new CamelKafka* convention.

Behaviour change: cross-transport propagation of kafka.* headers

Because the renamed header values now begin with Camel, they are filtered by the standard transport HeaderFilterStrategy (HttpHeaderFilterStrategy, JmsHeaderFilterStrategy, etc.) when crossing a transport boundary, by design — Camel* headers are framework-internal and are not propagated over the wire.

Routes that bridge an external transport (HTTP, JMS, …​) into a kafka: producer and let the sender choose the destination topic via the kafka.OVERRIDE_TOPIC header must therefore carry that value in a non-Camel-prefixed application header and map it to KafkaConstants.OVERRIDE_TOPIC in the route between the transport from and the kafka: to. Allowing untrusted senders to drive KafkaConstants.OVERRIDE_TOPIC (which redirects the producer’s target topic) without such a mapping step is not the intended use of the component.