This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 3ef68e407da3 CAMEL-25895: camel-openstack - align the remaining Swift 
header constants with the Camel naming convention (#28231)
3ef68e407da3 is described below

commit 3ef68e407da3396fe9312a4303cd9654033e921c
Author: Zineb BENDHIBA <[email protected]>
AuthorDate: Wed Oct 21 21:28:48 2026 +0200

    CAMEL-25895: camel-openstack - align the remaining Swift header constants 
with the Camel naming convention (#28231)
    
    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 <[email protected]>
    Signed-off-by: Zineb Bendhiba <[email protected]>
---
 .../camel/catalog/components/openstack-swift.json  |   8 +-
 .../component/openstack/swift/openstack-swift.json |   8 +-
 .../component/openstack/swift/SwiftConstants.java  |  16 +--
 .../openstack/swift/ContainerProducerTest.java     | 111 +++++++++++++++++++++
 design/headers.adoc                                |  17 ++--
 .../ROOT/pages/camel-4x-upgrade-guide-4_18.adoc    |  15 +--
 .../ROOT/pages/camel-4x-upgrade-guide-4_21.adoc    |  15 +--
 .../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc    |  30 ++++++
 .../endpoint/dsl/SwiftEndpointBuilderFactory.java  |  28 +++---
 9 files changed, 198 insertions(+), 50 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openstack-swift.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openstack-swift.json
index 8ebaeac1b5f1..4563b934a010 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openstack-swift.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openstack-swift.json
@@ -30,10 +30,10 @@
   "headers": {
     "CamelOpenstackSwiftContainerName": { "index": 0, "kind": "header", 
"displayName": "", "group": "object container", "label": "object container", 
"required": false, "javaType": "String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
container name.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_NAME" },
     "CamelOpenstackSwiftObjectName": { "index": 1, "kind": "header", 
"displayName": "", "group": "object", "label": "object", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The object name.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#OBJECT_NAME" },
-    "X-Container-Meta-": { "index": 2, "kind": "header", "displayName": "", 
"group": "container", "label": "container", "required": false, "javaType": 
"Map<String, String>", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Container metadata prefix.", 
"constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_METADATA_PREFIX"
 },
-    "X-Versions-Location": { "index": 3, "kind": "header", "displayName": "", 
"group": "container", "label": "container", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Versions location.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#VERSIONS_LOCATION" },
-    "X-Container-Read": { "index": 4, "kind": "header", "displayName": "", 
"group": "container", "label": "container", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "ACL - container read.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_READ" },
-    "X-Container-Write": { "index": 5, "kind": "header", "displayName": "", 
"group": "container", "label": "container", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "ACL - container write.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_WRITE" },
+    "CamelOpenstackSwiftContainerMetadata": { "index": 2, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "Map<String, String>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
container metadata.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_METADATA_PREFIX"
 },
+    "CamelOpenstackSwiftVersionsLocation": { "index": 3, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Versions location.", 
"constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#VERSIONS_LOCATION" },
+    "CamelOpenstackSwiftContainerRead": { "index": 4, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "ACL - container read.", 
"constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_READ" },
+    "CamelOpenstackSwiftContainerWrite": { "index": 5, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "ACL - container write.", 
"constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_WRITE" },
     "CamelOpenstackSwiftLimit": { "index": 6, "kind": "header", "displayName": 
"", "group": "container", "label": "container", "required": false, "javaType": 
"Integer", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "List options - limit.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#LIMIT" },
     "CamelOpenstackSwiftMarker": { "index": 7, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "List options - marker.", 
"constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#MARKER" },
     "CamelOpenstackSwiftEndMarker": { "index": 8, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "List options - end 
marker.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#END_MARKER" },
diff --git 
a/components/camel-openstack/src/generated/resources/META-INF/org/apache/camel/component/openstack/swift/openstack-swift.json
 
b/components/camel-openstack/src/generated/resources/META-INF/org/apache/camel/component/openstack/swift/openstack-swift.json
index 8ebaeac1b5f1..4563b934a010 100644
--- 
a/components/camel-openstack/src/generated/resources/META-INF/org/apache/camel/component/openstack/swift/openstack-swift.json
+++ 
b/components/camel-openstack/src/generated/resources/META-INF/org/apache/camel/component/openstack/swift/openstack-swift.json
@@ -30,10 +30,10 @@
   "headers": {
     "CamelOpenstackSwiftContainerName": { "index": 0, "kind": "header", 
"displayName": "", "group": "object container", "label": "object container", 
"required": false, "javaType": "String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
container name.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_NAME" },
     "CamelOpenstackSwiftObjectName": { "index": 1, "kind": "header", 
"displayName": "", "group": "object", "label": "object", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The object name.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#OBJECT_NAME" },
-    "X-Container-Meta-": { "index": 2, "kind": "header", "displayName": "", 
"group": "container", "label": "container", "required": false, "javaType": 
"Map<String, String>", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Container metadata prefix.", 
"constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_METADATA_PREFIX"
 },
-    "X-Versions-Location": { "index": 3, "kind": "header", "displayName": "", 
"group": "container", "label": "container", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Versions location.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#VERSIONS_LOCATION" },
-    "X-Container-Read": { "index": 4, "kind": "header", "displayName": "", 
"group": "container", "label": "container", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "ACL - container read.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_READ" },
-    "X-Container-Write": { "index": 5, "kind": "header", "displayName": "", 
"group": "container", "label": "container", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "ACL - container write.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_WRITE" },
+    "CamelOpenstackSwiftContainerMetadata": { "index": 2, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "Map<String, String>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
container metadata.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_METADATA_PREFIX"
 },
+    "CamelOpenstackSwiftVersionsLocation": { "index": 3, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Versions location.", 
"constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#VERSIONS_LOCATION" },
+    "CamelOpenstackSwiftContainerRead": { "index": 4, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "ACL - container read.", 
"constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_READ" },
+    "CamelOpenstackSwiftContainerWrite": { "index": 5, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "ACL - container write.", 
"constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#CONTAINER_WRITE" },
     "CamelOpenstackSwiftLimit": { "index": 6, "kind": "header", "displayName": 
"", "group": "container", "label": "container", "required": false, "javaType": 
"Integer", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "List options - limit.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#LIMIT" },
     "CamelOpenstackSwiftMarker": { "index": 7, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "List options - marker.", 
"constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#MARKER" },
     "CamelOpenstackSwiftEndMarker": { "index": 8, "kind": "header", 
"displayName": "", "group": "container", "label": "container", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "List options - end 
marker.", "constantName": 
"org.apache.camel.component.openstack.swift.SwiftConstants#END_MARKER" },
diff --git 
a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/swift/SwiftConstants.java
 
b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/swift/SwiftConstants.java
index c532c4cada24..66946c1319a9 100644
--- 
a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/swift/SwiftConstants.java
+++ 
b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/swift/SwiftConstants.java
@@ -18,7 +18,6 @@ package org.apache.camel.component.openstack.swift;
 
 import org.apache.camel.component.openstack.common.OpenstackConstants;
 import org.apache.camel.spi.Metadata;
-import org.openstack4j.model.storage.object.SwiftHeaders;
 
 public final class SwiftConstants extends OpenstackConstants {
 
@@ -30,19 +29,14 @@ public final class SwiftConstants extends 
OpenstackConstants {
     @Metadata(label = "object", description = "The object name.", javaType = 
"String")
     public static final String OBJECT_NAME = "CamelOpenstackSwiftObjectName";
 
-    // The following four constants intentionally keep the openstack4j-defined 
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 metadata and ACL headers to the Swift backend. Renaming them 
would
-    // 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;
+    @Metadata(label = "container", description = "The container metadata.", 
javaType = "Map<String, String>")
+    public static final String CONTAINER_METADATA_PREFIX = 
"CamelOpenstackSwiftContainerMetadata";
     @Metadata(label = "container", description = "Versions location.", 
javaType = "String")
-    public static final String VERSIONS_LOCATION = 
SwiftHeaders.VERSIONS_LOCATION;
+    public static final String VERSIONS_LOCATION = 
"CamelOpenstackSwiftVersionsLocation";
     @Metadata(label = "container", description = "ACL - container read.", 
javaType = "String")
-    public static final String CONTAINER_READ = SwiftHeaders.CONTAINER_READ;
+    public static final String CONTAINER_READ = 
"CamelOpenstackSwiftContainerRead";
     @Metadata(label = "container", description = "ACL - container write.", 
javaType = "String")
-    public static final String CONTAINER_WRITE = SwiftHeaders.CONTAINER_WRITE;
+    public static final String CONTAINER_WRITE = 
"CamelOpenstackSwiftContainerWrite";
 
     @Metadata(label = "container", description = "List options - limit.", 
javaType = "Integer")
     public static final String LIMIT = "CamelOpenstackSwiftLimit";
diff --git 
a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/swift/ContainerProducerTest.java
 
b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/swift/ContainerProducerTest.java
index 3554ff5ac6f6..fe684d7d75e2 100644
--- 
a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/swift/ContainerProducerTest.java
+++ 
b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/swift/ContainerProducerTest.java
@@ -37,6 +37,7 @@ import 
org.openstack4j.model.storage.object.options.ContainerListOptions;
 import 
org.openstack4j.model.storage.object.options.CreateUpdateContainerOptions;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -49,6 +50,19 @@ import static org.mockito.Mockito.when;
 public class ContainerProducerTest extends SwiftProducerTestSupport {
 
     private static final String CONTAINER_NAME = "containerName";
+    private static final String READ_ACCESS = "read-access-value";
+    private static final String WRITE_ACCESS = "write-access-value";
+    private static final String VERSIONS_CONTAINER = "versionsContainer";
+    private static final String BODY_READ_ACCESS = "body-read-access-value";
+
+    // openstack4j stores the CreateUpdateContainerOptions values under the 
Swift
+    // wire header names, independent of the Camel header constant values 
(which
+    // follow the CamelOpenstack* naming convention).
+    private static final String SWIFT_READ_OPTION = "X-Container-Read";
+    private static final String SWIFT_WRITE_OPTION = "X-Container-Write";
+    private static final String SWIFT_VERSIONS_OPTION = "X-Versions-Location";
+    // openstack4j lowercases the metadata keys it appends to this prefix.
+    private static final String SWIFT_METADATA_OPTION_PREFIX = 
"X-Container-Meta-";
 
     @Mock
     private SwiftContainer mockOsContainer;
@@ -182,4 +196,101 @@ public class ContainerProducerTest extends 
SwiftProducerTestSupport {
 
         assertEquals(md, msg.getBody(Map.class));
     }
+
+    @Test
+    public void containerCreateReadsAccessControlFromCamelNamespacedHeaders() 
throws Exception {
+        when(containerService.create(anyString(), 
any())).thenReturn(ActionResponse.actionSuccess());
+        msg.setHeader(OpenstackConstants.OPERATION, OpenstackConstants.CREATE);
+        msg.setHeader(SwiftConstants.CONTAINER_NAME, CONTAINER_NAME);
+        msg.setHeader(SwiftConstants.CONTAINER_READ, READ_ACCESS);
+        msg.setHeader(SwiftConstants.CONTAINER_WRITE, WRITE_ACCESS);
+
+        producer.process(exchange);
+
+        verify(containerService).create(containerNameCaptor.capture(), 
optionsCaptor.capture());
+        assertEquals(CONTAINER_NAME, containerNameCaptor.getValue());
+        assertNotNull(optionsCaptor.getValue());
+        final Map<String, String> options = 
optionsCaptor.getValue().getOptions();
+        assertEquals(READ_ACCESS, options.get(SWIFT_READ_OPTION));
+        assertEquals(WRITE_ACCESS, options.get(SWIFT_WRITE_OPTION));
+    }
+
+    @Test
+    public void containerUpdateReadsAccessControlFromCamelNamespacedHeaders() 
throws Exception {
+        when(containerService.update(anyString(), 
any())).thenReturn(ActionResponse.actionSuccess());
+        msg.setHeader(OpenstackConstants.OPERATION, OpenstackConstants.UPDATE);
+        msg.setHeader(SwiftConstants.CONTAINER_NAME, CONTAINER_NAME);
+        msg.setHeader(SwiftConstants.CONTAINER_READ, READ_ACCESS);
+        msg.setHeader(SwiftConstants.CONTAINER_WRITE, WRITE_ACCESS);
+
+        producer.process(exchange);
+
+        verify(containerService).update(containerNameCaptor.capture(), 
optionsCaptor.capture());
+        assertEquals(CONTAINER_NAME, containerNameCaptor.getValue());
+        assertNotNull(optionsCaptor.getValue());
+        final Map<String, String> options = 
optionsCaptor.getValue().getOptions();
+        assertEquals(READ_ACCESS, options.get(SWIFT_READ_OPTION));
+        assertEquals(WRITE_ACCESS, options.get(SWIFT_WRITE_OPTION));
+    }
+
+    @Test
+    public void 
containerUpdateReadsVersionsLocationAndMetadataFromCamelNamespacedHeaders() 
throws Exception {
+        final Map<String, String> md = new HashMap<>();
+        md.put("year", "2000");
+
+        when(containerService.update(anyString(), 
any())).thenReturn(ActionResponse.actionSuccess());
+        msg.setHeader(OpenstackConstants.OPERATION, OpenstackConstants.UPDATE);
+        msg.setHeader(SwiftConstants.CONTAINER_NAME, CONTAINER_NAME);
+        msg.setHeader(SwiftConstants.VERSIONS_LOCATION, VERSIONS_CONTAINER);
+        msg.setHeader(SwiftConstants.CONTAINER_METADATA_PREFIX, md);
+
+        producer.process(exchange);
+
+        verify(containerService).update(containerNameCaptor.capture(), 
optionsCaptor.capture());
+        assertNotNull(optionsCaptor.getValue());
+        final Map<String, String> options = 
optionsCaptor.getValue().getOptions();
+        assertEquals(VERSIONS_CONTAINER, options.get(SWIFT_VERSIONS_OPTION));
+        assertEquals("2000", options.get(SWIFT_METADATA_OPTION_PREFIX + 
"year"));
+    }
+
+    @Test
+    public void containerUpdateIgnoresThePreviousSwiftHeaderNames() throws 
Exception {
+        when(containerService.update(anyString(), 
any())).thenReturn(ActionResponse.actionSuccess());
+        msg.setHeader(OpenstackConstants.OPERATION, OpenstackConstants.UPDATE);
+        msg.setHeader(SwiftConstants.CONTAINER_NAME, CONTAINER_NAME);
+        msg.setHeader(SWIFT_READ_OPTION, READ_ACCESS);
+        msg.setHeader(SWIFT_WRITE_OPTION, WRITE_ACCESS);
+        msg.setHeader(SWIFT_VERSIONS_OPTION, VERSIONS_CONTAINER);
+        msg.setHeader(SWIFT_METADATA_OPTION_PREFIX, Map.of("year", "2000"));
+
+        producer.process(exchange);
+
+        verify(containerService).update(containerNameCaptor.capture(), 
optionsCaptor.capture());
+        assertEquals(CONTAINER_NAME, containerNameCaptor.getValue());
+        assertNull(optionsCaptor.getValue());
+    }
+
+    @Test
+    public void containerUpdatePrefersTheOptionsFromTheBodyOverTheHeaders() 
throws Exception {
+        when(containerService.update(anyString(), 
any())).thenReturn(ActionResponse.actionSuccess());
+        msg.setHeader(OpenstackConstants.OPERATION, OpenstackConstants.UPDATE);
+        msg.setHeader(SwiftConstants.CONTAINER_NAME, CONTAINER_NAME);
+        msg.setHeader(SwiftConstants.CONTAINER_READ, READ_ACCESS);
+        final CreateUpdateContainerOptions body = 
CreateUpdateContainerOptions.create().accessRead(BODY_READ_ACCESS);
+        msg.setBody(body);
+
+        producer.process(exchange);
+
+        verify(containerService).update(containerNameCaptor.capture(), 
optionsCaptor.capture());
+        assertEquals(body, optionsCaptor.getValue());
+        assertEquals(BODY_READ_ACCESS, 
optionsCaptor.getValue().getOptions().get(SWIFT_READ_OPTION));
+    }
+
+    @Test
+    public void containerOptionHeaderNamesFollowTheCamelNamingConvention() {
+        assertEquals("CamelOpenstackSwiftContainerMetadata", 
SwiftConstants.CONTAINER_METADATA_PREFIX);
+        assertEquals("CamelOpenstackSwiftVersionsLocation", 
SwiftConstants.VERSIONS_LOCATION);
+        assertEquals("CamelOpenstackSwiftContainerRead", 
SwiftConstants.CONTAINER_READ);
+        assertEquals("CamelOpenstackSwiftContainerWrite", 
SwiftConstants.CONTAINER_WRITE);
+    }
 }
diff --git a/design/headers.adoc b/design/headers.adoc
index 686564afbd8c..2b69d5011c85 100644
--- a/design/headers.adoc
+++ b/design/headers.adoc
@@ -128,19 +128,24 @@ public static final String HEADER_FIELD_PREFIX = 
"CamelSolrField.";
 === Protocol and standard headers
 
 Headers that are part of an external wire protocol or standard (HTTP headers,
-JMS properties, Swift API headers, etc.) are *exempt* from the `Camel` prefix
-rule. They use the standard's own name because the framework passes them
-through to the underlying transport.
+JMS properties, etc.) are *exempt* from the `Camel` prefix rule. They use the
+standard's own name because the framework passes them through to the underlying
+transport.
 
 Examples:
 
-* Swift: `X-Container-Meta-`, `X-Versions-Location`
 * HTTP: `Content-Type`, `Accept`
 * JMS: standard JMS property names
 
+The exemption applies only when the header name the route sets is the name that
+goes on the wire. When the component hands the value to a client library that
+builds the wire name itself - as `camel-openstack` does for the Swift container
+options, where openstack4j maps `accessRead`, `accessWrite`, `versionsLocation`
+and `metadata` onto the `X-...` names - the Exchange header name never reaches
+the protocol, so it follows the `Camel` convention like any other header.
+
 When a component has both Camel-convention headers and protocol pass-through
-headers, document the distinction clearly (see `camel-openstack` Swift
-constants for an example).
+headers, document the distinction clearly.
 
 === Exchange properties
 
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
index 878db8a7b44e..f6992a399a64 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
@@ -1657,12 +1657,15 @@ Swift (`SwiftConstants`):
 |===
 
 `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.
+`SwiftConstants.CONTAINER_READ`, and `SwiftConstants.CONTAINER_WRITE` keep
+their previous values (`X-Container-Meta-`, `X-Versions-Location`,
+`X-Container-Read`, `X-Container-Write`) in this release.
+
+NOTE: These four constants have since been renamed to follow the Camel naming
+convention; see CAMEL-25895 for the releases that carry the change. They are
+Exchange header keys only: openstack4j builds the `X-Container-*` wire headers
+itself from `CreateUpdateContainerOptions`, so the Camel header name never
+reaches Swift.
 
 Routes that reference the constants symbolically (for example
 `setHeader(OpenstackConstants.OPERATION, ...)`) continue to work without
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
index ed522d0008c1..ce69b6289e00 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
@@ -1788,12 +1788,15 @@ Swift (`SwiftConstants`):
 |===
 
 `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.
+`SwiftConstants.CONTAINER_READ`, and `SwiftConstants.CONTAINER_WRITE` keep
+their previous values (`X-Container-Meta-`, `X-Versions-Location`,
+`X-Container-Read`, `X-Container-Write`) in this release.
+
+NOTE: These four constants have since been renamed to follow the Camel naming
+convention; see CAMEL-25895 for the releases that carry the change. They are
+Exchange header keys only: openstack4j builds the `X-Container-*` wire headers
+itself from `CreateUpdateContainerOptions`, so the Camel header name never
+reaches Swift.
 
 Routes that reference the constants symbolically (for example
 `setHeader(OpenstackConstants.OPERATION, ...)`) continue to work without
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 273f5d2b8a8e..d90829087638 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -267,6 +267,36 @@ as the body, so `+${body}+` was the file found. A 
`fileName` that uses the file
 before. A `fileName` that read the file found through its headers, such as 
`${header.CamelFileName}`, must use the file
 functions instead (`${file:name}`).
 
+=== camel-openstack - potential breaking change
+
+The four remaining Exchange header constants of `SwiftConstants` have been 
renamed to follow the Camel naming
+convention used by the rest of the component, completing the rename done in 
4.21. The Java field names are unchanged;
+only the header string values have changed.
+
+[options="header"]
+|===
+| Constant | Previous value | New value
+| `SwiftConstants.CONTAINER_METADATA_PREFIX` | `X-Container-Meta-` | 
`CamelOpenstackSwiftContainerMetadata`
+| `SwiftConstants.VERSIONS_LOCATION` | `X-Versions-Location` | 
`CamelOpenstackSwiftVersionsLocation`
+| `SwiftConstants.CONTAINER_READ` | `X-Container-Read` | 
`CamelOpenstackSwiftContainerRead`
+| `SwiftConstants.CONTAINER_WRITE` | `X-Container-Write` | 
`CamelOpenstackSwiftContainerWrite`
+|===
+
+The previous values were kept in 4.21 on the understanding that they were part 
of the Swift HTTP contract. They are
+not: the container producer 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. The request Camel sends to Swift is therefore unchanged by this rename.
+
+Routes that reference the constants symbolically (for example 
`setHeader(SwiftConstants.CONTAINER_READ, ...)`)
+continue to work without changes. Routes that set one of these headers by its 
literal string value (for example
+`setHeader("X-Container-Read", ...)` in an XML or YAML route) must be updated 
to the new value
+(`setHeader("CamelOpenstackSwiftContainerRead", ...)`); the previous names are 
no longer read.
+
+The generated Endpoint DSL header accessors on the Swift `HeaderNameBuilder` 
are renamed accordingly
+(`xContainerMeta()` -> `openstackSwiftContainerMetadata()`, 
`xVersionsLocation()` ->
+`openstackSwiftVersionsLocation()`, `xContainerRead()` -> 
`openstackSwiftContainerRead()`, `xContainerWrite()` ->
+`openstackSwiftContainerWrite()`).
+
 === camel-pqc - an unknown hybridKdfAlgorithm is rejected
 
 The hybrid KEM operations now fail with an `IllegalArgumentException` when 
`hybridKdfAlgorithm` is not one of
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SwiftEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SwiftEndpointBuilderFactory.java
index 9cb32b59604a..a7f1c0c938d3 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SwiftEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SwiftEndpointBuilderFactory.java
@@ -329,16 +329,17 @@ public interface SwiftEndpointBuilderFactory {
             return "CamelOpenstackSwiftObjectName";
         }
         /**
-         * Container metadata prefix.
+         * The container metadata.
          * 
          * The option is a: {@code Map<String, String>} type.
          * 
          * Group: container
          * 
-         * @return the name of the header {@code X-Container-Meta-}.
+         * @return the name of the header {@code
+         * OpenstackSwiftContainerMetadata}.
          */
-        public String xContainerMeta() {
-            return "X-Container-Meta-";
+        public String openstackSwiftContainerMetadata() {
+            return "CamelOpenstackSwiftContainerMetadata";
         }
         /**
          * Versions location.
@@ -347,10 +348,11 @@ public interface SwiftEndpointBuilderFactory {
          * 
          * Group: container
          * 
-         * @return the name of the header {@code X-Versions-Location}.
+         * @return the name of the header {@code
+         * OpenstackSwiftVersionsLocation}.
          */
-        public String xVersionsLocation() {
-            return "X-Versions-Location";
+        public String openstackSwiftVersionsLocation() {
+            return "CamelOpenstackSwiftVersionsLocation";
         }
         /**
          * ACL - container read.
@@ -359,10 +361,10 @@ public interface SwiftEndpointBuilderFactory {
          * 
          * Group: container
          * 
-         * @return the name of the header {@code X-Container-Read}.
+         * @return the name of the header {@code OpenstackSwiftContainerRead}.
          */
-        public String xContainerRead() {
-            return "X-Container-Read";
+        public String openstackSwiftContainerRead() {
+            return "CamelOpenstackSwiftContainerRead";
         }
         /**
          * ACL - container write.
@@ -371,10 +373,10 @@ public interface SwiftEndpointBuilderFactory {
          * 
          * Group: container
          * 
-         * @return the name of the header {@code X-Container-Write}.
+         * @return the name of the header {@code OpenstackSwiftContainerWrite}.
          */
-        public String xContainerWrite() {
-            return "X-Container-Write";
+        public String openstackSwiftContainerWrite() {
+            return "CamelOpenstackSwiftContainerWrite";
         }
         /**
          * List options - limit.

Reply via email to