Skip to content

CAMEL-25895: camel-openstack - align the remaining Swift header constants with the Camel naming convention - #28231

Open
zbendhiba wants to merge 1 commit into
apache:mainfrom
zbendhiba:fix/CAMEL-25895
Open

zbendhiba wants to merge 1 commit into
apache:mainfrom
zbendhiba:fix/CAMEL-25895

Conversation

@zbendhiba

Copy link
Copy Markdown
Contributor

CAMEL-25895: camel-openstack - align the remaining Swift header constants with the Camel naming convention

Problem

CAMEL-23580 (Camel 4.21) renamed the Exchange header constants of camel-openstack to the
CamelOpenstack* convention used across the component catalog, but left four constants in
SwiftConstants on their openstack4j values:

Constant Value
SwiftConstants.CONTAINER_METADATA_PREFIX X-Container-Meta-
SwiftConstants.VERSIONS_LOCATION X-Versions-Location
SwiftConstants.CONTAINER_READ X-Container-Read
SwiftConstants.CONTAINER_WRITE X-Container-Write

The reason recorded in the code and in the 4.21, 4.18 and 4.14 upgrade guides was that these names
"are part of the Swift HTTP protocol contract used by openstack4j" and that "renaming them would
break interoperability with the Swift API".

That reason does not hold. ContainerProducer.messageToCreateUpdateOptions never puts the Exchange
header name on the wire: it calls CreateUpdateContainerOptions.metadata(Map),
.versionsLocation(String), .accessRead(String) and .accessWrite(String), and openstack4j
builds the X-Container-Meta-, X-Versions-Location, X-Container-Read and X-Container-Write
names of the Swift request itself. Verified against openstack4j-core 3.12:
CreateUpdateContainerOptions.create().accessRead("r").accessWrite("w").versionsLocation("l").getOptions()
returns {X-Container-Read=r, X-Container-Write=w, X-Versions-Location=l} regardless of which Camel
header key the value came from.

So the four names bought nothing, while making openstack-swift the only component in its family
whose container options are driven by header keys outside the Camel* namespace that
DefaultHeaderFilterStrategy filters by default. camel-aws2-s3, for comparison, already uses
CamelAwsS3Acl / CamelAwsS3CannedAcl.

This PR partly reverses that deliberate decision from CAMEL-23580. The decision itself was
intentional and documented; what is corrected here is its stated premise, which is factually wrong.
Per the project's AI agent guidelines, this is called out explicitly rather than left implicit.

Change

components/camel-openstack/src/main/java/.../swift/SwiftConstants.java

Constant Previous value New value
CONTAINER_METADATA_PREFIX X-Container-Meta- CamelOpenstackSwiftContainerMetadata
VERSIONS_LOCATION X-Versions-Location CamelOpenstackSwiftVersionsLocation
CONTAINER_READ X-Container-Read CamelOpenstackSwiftContainerRead
CONTAINER_WRITE X-Container-Write CamelOpenstackSwiftContainerWrite
  • The Java field names are unchanged, so routes referencing the constants symbolically keep
    compiling and working. This matches the hard-break-with-stable-field-names policy in
    design/headers.adoc and what CAMEL-23580 did for the other constants.
  • The now-wrong rationale comment and the unused
    org.openstack4j.model.storage.object.SwiftHeaders import are removed.
  • ContainerProducer needed no change: it already reads the constants, never the literal strings.
  • design/headers.adoc listed Swift under the "protocol and standard headers" exemption and
    pointed at these constants as the worked example. Corrected: the exemption applies when the
    header name the route sets is the name that goes on the wire, which is not the case when a client
    library builds the wire name itself.
  • Upgrade note added to camel-4x-upgrade-guide-4_24.adoc with the value table, the note that the
    Swift request is unchanged, the migration for routes using literal header strings, and the
    renamed Endpoint DSL accessors (xContainerRead() -> openstackSwiftContainerRead(), etc.).
  • The 4.21 and 4.18 upgrade guides carried the same now-wrong rationale paragraph, stating that
    these names are part of the Swift HTTP contract and that renaming them would break
    interoperability. Both are corrected to record that openstack4j builds the X-Container-* wire
    names itself, with a pointer to CAMEL-25895 for the releases that carry the rename. Left as a
    pointer rather than a version so it stays correct across the maintenance lines.
    camel-4x-upgrade-guide-4_14.adoc is not touched: that line is EOL and receives no fix.
  • Regenerated: the component and catalog openstack-swift.json, the catalog doc mirror and
    SwiftEndpointBuilderFactory.

Tests

ContainerProducerTest had no coverage of the container options path at all. Six tests added,
in the module's existing style (JUnit 5 + Mockito via SwiftProducerTestSupport; the class is
JUnit-assertion based, so no AssertJ was introduced):

  • containerCreateReadsAccessControlFromCamelNamespacedHeaders
  • containerUpdateReadsAccessControlFromCamelNamespacedHeaders
  • containerUpdateReadsVersionsLocationAndMetadataFromCamelNamespacedHeaders
  • containerUpdateIgnoresThePreviousSwiftHeaderNames
  • containerUpdatePrefersTheOptionsFromTheBodyOverTheHeaders
  • containerOptionHeaderNamesFollowTheCamelNamingConvention

containerUpdateIgnoresThePreviousSwiftHeaderNames and
containerOptionHeaderNamesFollowTheCamelNamingConvention fail on the unfixed code
(expected: <null> but was: <CreateUpdateContainerOptions@...> and
expected: <CamelOpenstackSwiftContainerMetadata> but was: <X-Container-Meta->). They are the two
that pin the values; the three ...FromCamelNamespacedHeaders tests go through the Java constants,
so they cover the producer path but not the rename itself.
containerUpdatePrefersTheOptionsFromTheBodyOverTheHeaders locks in the existing precedence, which
the rename does not change: a CreateUpdateContainerOptions in the body makes the producer skip the
headers entirely.

mvn test -pl components/camel-openstack -Dtest=ContainerProducerTest: 13 tests, 0 failures.
mvn formatter:format impsort:sort -pl components/camel-openstack: nothing to change.

Backports

Targets camel-4.22.x and camel-4.18.x. SwiftConstants.java and ContainerProducer.java are
identical on all three lines, so the Java part is a straight cherry-pick; the generated artefacts
are regenerated per branch rather than cherry-picked. Per the project's backport upgrade-guide
policy, the matching notes go into camel-4x-upgrade-guide-4_22.adoc and
camel-4x-upgrade-guide-4_18.adoc on main. camel-4.14.x and camel-4.10.x are EOL and get
nothing.


Claude Code on behalf of zbendhiba

🤖 Generated with Claude Code

…ants with the Camel naming convention

CAMEL-23580 renamed the camel-openstack Exchange header constants to the
CamelOpenstack* convention, but left four of them in SwiftConstants on their
openstack4j values, on the understanding that those values are part of the
Swift HTTP contract:

  CONTAINER_METADATA_PREFIX  X-Container-Meta-    -> CamelOpenstackSwiftContainerMetadata
  VERSIONS_LOCATION          X-Versions-Location  -> CamelOpenstackSwiftVersionsLocation
  CONTAINER_READ             X-Container-Read     -> CamelOpenstackSwiftContainerRead
  CONTAINER_WRITE            X-Container-Write    -> CamelOpenstackSwiftContainerWrite

They are not. ContainerProducer passes the values to the openstack4j
CreateUpdateContainerOptions, which builds the X-Container-Meta-,
X-Versions-Location, X-Container-Read and X-Container-Write names of the Swift
request itself, so the Exchange header key never reaches Swift and the request
on the wire is unchanged by this rename. This commit therefore partly reverses
the decision taken in CAMEL-23580, because the reason recorded for it does not
hold.

The Java field names are unchanged, so routes that reference the constants
symbolically keep working. Routes that set one of these headers by its literal
string value must move to the new value; the 4.24 upgrade guide carries the
table, the note that the Swift request is unchanged, and the renamed Endpoint
DSL accessors.

design/headers.adoc listed Swift under the protocol-header exemption and
pointed at these four constants as the worked example. It now states that the
exemption applies only when the header name the route sets is the name that
goes on the wire, which is not the case when a client library builds the wire
name itself.

ContainerProducerTest had no coverage of the container options path at all;
six tests are added for it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Zineb Bendhiba <bendhiba.zineb@gmail.com>
@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.

@gnodet-bot gnodet-bot 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.

Good cleanup — renaming the constants to the Camel naming convention is the right call. One small item on the stale description:

This review was generated by an AI agent, Hermès on behalf of @gnodet.

// break interoperability with the Swift API.
@Metadata(label = "container", description = "Container metadata prefix.", javaType = "Map<String, String>")
public static final String CONTAINER_METADATA_PREFIX = SwiftHeaders.CONTAINER_METADATA_PREFIX;
public static final String CONTAINER_METADATA_PREFIX = "CamelOpenstackSwiftContainerMetadata";

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.

⚠️ Stale description: Now that CONTAINER_METADATA_PREFIX holds the Camel Exchange header name "CamelOpenstackSwiftContainerMetadata" (a Map<String, String> header key), the @Metadata description "Container metadata prefix." is no longer accurate — the word "prefix" referred to the old wire-level HTTP header prefix (X-Container-Meta-). Consider updating it to "Container metadata." (or a more descriptive wording).

Suggested change
public static final String CONTAINER_METADATA_PREFIX = "CamelOpenstackSwiftContainerMetadata";
public static final String CONTAINER_METADATA_PREFIX = "CamelOpenstackSwiftContainerMetadata";

@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.

Thanks Zineb, this looks good. The premise checks out: ContainerProducer.messageToCreateUpdateOptions only hands the values to openstack4j's CreateUpdateContainerOptions (metadata(...), versionsLocation(...), accessRead(...), accessWrite(...)), and in openstack4j-core 3.12 those methods put the X-Container-Meta-*, X-Versions-Location, X-Container-Read and X-Container-Write names on the request themselves. So the Exchange header key never reaches Swift and the rename does not change the wire request. Calling out explicitly that this partly reverses CAMEL-23580, and why, is appreciated.

Conventions check: the commit, branch and JIRA linkage follow the project guidelines. The 4.24 upgrade-guide entry covers what design/headers.adoc asks for on a header rename: the old -> new table, the renamed Endpoint DSL accessors, that code using the Java constants is unaffected, and that literal header strings must be updated. The generated artefacts are in the PR (component and catalog openstack-swift.json, SwiftEndpointBuilderFactory); the component doc only pulls the headers in through component-endpoint-headers.adoc, so the catalog doc mirror has nothing to change. No other references to the old values remain outside the upgrade guides and the test. The new tests stay in the module's JUnit + Mockito style, and the two that pin the values fail on the old code.

Non-blocking notes:

  • gnodet-bot's open thread on SwiftConstants.CONTAINER_METADATA_PREFIX is still valid: the description Container metadata prefix. described the old X-Container-Meta- prefix, while the header now holds a Map<String, String> of metadata. A hint: Container metadata. (or something like The container metadata, as a map of name to value.). Changing it means regenerating the two JSON files and the Endpoint DSL again.
  • For the backports, per the backport upgrade-guide policy: camel-4x-upgrade-guide-4_22.adoc on main has nothing about this yet, and the 4.18 note currently points to CAMEL-25895. When the 4.22.x and 4.18.x ports land, the rename table with the exact patch version should go into both guides on main as well.

CI: the build jobs are still running.

This review covers project rules and conventions only. It does not replace CodeRabbit, Sourcery or SonarCloud.

Claude Code on behalf of Claus Ibsen

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

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants