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 5608bd54d0e3f..3c56d99074962 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", "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", "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 5608bd54d0e3f..3c56d99074962 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", "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", "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 c532c4cada24e..66946c1319a9f 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 @@ 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") - public static final String CONTAINER_METADATA_PREFIX = SwiftHeaders.CONTAINER_METADATA_PREFIX; + @Metadata(label = "container", description = "The container metadata.", javaType = "Map") + 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 3554ff5ac6f6d..fe684d7d75e21 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.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 @@ 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 void getMetadataTest() throws Exception { 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 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 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 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 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/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 9cb32b59604a4..a7f1c0c938d37 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 String openstackSwiftObjectName() { return "CamelOpenstackSwiftObjectName"; } /** - * Container metadata prefix. + * The container metadata. * * The option is a: {@code Map} 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 String xContainerMeta() { * * 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 String xVersionsLocation() { * * 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 String xContainerRead() { * * 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.