This is an automated email from the ASF dual-hosted git repository.
chibenwa pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push:
new 20bf8083e3 [FIX] S3: Fallback bucket should not apply bucket prefix
(#3128)
20bf8083e3 is described below
commit 20bf8083e39be4a750f606e576a162087bb3f18a
Author: Benoit TELLIER <[email protected]>
AuthorDate: Sat Aug 22 13:44:35 2026 +0700
[FIX] S3: Fallback bucket should not apply bucket prefix (#3128)
---
.../servers/partials/configure/blobstore.adoc | 2 ++
.../helm-chart/james/configs/blob.properties | 4 +++-
.../sample-configuration/blob.properties | 4 +++-
.../sample-configuration/blob.properties | 4 +++-
.../blob.properties | 4 +++-
.../sample-configuration/blob.properties | 4 +++-
.../blob/objectstorage/aws/S3BlobStoreDAO.java | 6 ++----
.../blob/objectstorage/aws/S3BlobStoreDAOTest.java | 24 ++++++++++++++++++++++
8 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/docs/modules/servers/partials/configure/blobstore.adoc
b/docs/modules/servers/partials/configure/blobstore.adoc
index 8d0535ddc2..44d992c36e 100644
--- a/docs/modules/servers/partials/configure/blobstore.adoc
+++ b/docs/modules/servers/partials/configure/blobstore.adoc
@@ -166,6 +166,8 @@ Unless a special case like storing blobs of deleted
messages.
| objectstorage.namespace.read.fallback
| BlobStore fallback bucket name. Allows to fallback to a previous used bucket
when blob is missing from the default one.
It can be useful when migrating blobs to a new bucket for example.
+This is a read only fallback: James never writes to, nor deletes from, that
bucket.
+This bucket name is used as is: `objectstorage.bucketPrefix` is not applied to
it.
|===
==== SSE-C Configuration
diff --git
a/server/apps/distributed-app/helm-chart/james/configs/blob.properties
b/server/apps/distributed-app/helm-chart/james/configs/blob.properties
index 25cc5793e1..7de3823583 100644
--- a/server/apps/distributed-app/helm-chart/james/configs/blob.properties
+++ b/server/apps/distributed-app/helm-chart/james/configs/blob.properties
@@ -42,7 +42,9 @@ cache.sizeThresholdInBytes=16 KiB
objectstorage.namespace=james-${env:JAMES_BUCKET_SUFFIX}
# Fallback bucket name
-# Optional, read this bucket when default bukcket reads fails if configured
+# Optional, read this bucket when reads on the default bucket fail, if
configured.
+# This is a read only fallback: blobs are never written to nor deleted from
this bucket.
+# Note: this name is used as is, `objectstorage.bucketPrefix` is not applied
to it.
# objectstorage.namespace.read.fallback=james-fallback
# ========================================= ObjectStorage on S3
=============================================
diff --git a/server/apps/distributed-app/sample-configuration/blob.properties
b/server/apps/distributed-app/sample-configuration/blob.properties
index 9c21f6e8ce..f5d781b5a3 100644
--- a/server/apps/distributed-app/sample-configuration/blob.properties
+++ b/server/apps/distributed-app/sample-configuration/blob.properties
@@ -88,7 +88,9 @@ cache.enable=false
# objectstorage.namespace=james
# Fallback bucket name
-# Optional, read this bucket when default bukcket reads fails if configured
+# Optional, read this bucket when reads on the default bucket fail, if
configured.
+# This is a read only fallback: blobs are never written to nor deleted from
this bucket.
+# Note: this name is used as is, `objectstorage.bucketPrefix` is not applied
to it.
# objectstorage.namespace.read.fallback=james-fallback
# ========================================= ObjectStorage on S3
=============================================
diff --git
a/server/apps/distributed-pop3-app/sample-configuration/blob.properties
b/server/apps/distributed-pop3-app/sample-configuration/blob.properties
index 311103c4f4..b603700394 100644
--- a/server/apps/distributed-pop3-app/sample-configuration/blob.properties
+++ b/server/apps/distributed-pop3-app/sample-configuration/blob.properties
@@ -58,7 +58,9 @@ cache.enable=false
# objectstorage.namespace=james
# Fallback bucket name
-# Optional, read this bucket when default bukcket reads fails if configured
+# Optional, read this bucket when reads on the default bucket fail, if
configured.
+# This is a read only fallback: blobs are never written to nor deleted from
this bucket.
+# Note: this name is used as is, `objectstorage.bucketPrefix` is not applied
to it.
# objectstorage.namespace.read.fallback=james-fallback
# ========================================= ObjectStorage on S3
=============================================
diff --git
a/server/apps/postgres-app/sample-configuration-distributed/blob.properties
b/server/apps/postgres-app/sample-configuration-distributed/blob.properties
index 3f210e0acb..25c32dd582 100644
--- a/server/apps/postgres-app/sample-configuration-distributed/blob.properties
+++ b/server/apps/postgres-app/sample-configuration-distributed/blob.properties
@@ -50,7 +50,9 @@ encryption.aes.enable=false
# objectstorage.namespace=james
# Fallback bucket name
-# Optional, read this bucket when default bukcket reads fails if configured
+# Optional, read this bucket when reads on the default bucket fail, if
configured.
+# This is a read only fallback: blobs are never written to nor deleted from
this bucket.
+# Note: this name is used as is, `objectstorage.bucketPrefix` is not applied
to it.
# objectstorage.namespace.read.fallback=james-fallback
# ========================================= ObjectStorage on S3
=============================================
diff --git
a/server/apps/scaling-pulsar-smtp/sample-configuration/blob.properties
b/server/apps/scaling-pulsar-smtp/sample-configuration/blob.properties
index 15549d3285..4a1ed250ac 100644
--- a/server/apps/scaling-pulsar-smtp/sample-configuration/blob.properties
+++ b/server/apps/scaling-pulsar-smtp/sample-configuration/blob.properties
@@ -68,7 +68,9 @@ cache.enable=false
# objectstorage.namespace=james
# Fallback bucket name
-# Optional, read this bucket when default bukcket reads fails if configured
+# Optional, read this bucket when reads on the default bucket fail, if
configured.
+# This is a read only fallback: blobs are never written to nor deleted from
this bucket.
+# Note: this name is used as is, `objectstorage.bucketPrefix` is not applied
to it.
# objectstorage.namespace.read.fallback=james-fallback
# ========================================= ObjectStorage on S3
=============================================
diff --git
a/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAO.java
b/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAO.java
index 5176e47429..f6307d1590 100644
---
a/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAO.java
+++
b/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAO.java
@@ -173,8 +173,7 @@ public class S3BlobStoreDAO implements BlobStoreDAO {
return getObjectFromStore(bucketName, blobId)
.onErrorResume(e -> e instanceof NoSuchKeyException || e
instanceof NoSuchBucketException, e -> {
if (fallbackNamespace.isPresent() &&
bucketNameResolver.isNameSpace(bucketName)) {
- BucketName resolvedFallbackBucketName =
bucketNameResolver.resolve(fallbackNamespace.get());
- return getObjectFromStore(resolvedFallbackBucketName,
blobId);
+ return getObjectFromStore(fallbackNamespace.get(), blobId);
}
return Mono.error(e);
});
@@ -229,8 +228,7 @@ public class S3BlobStoreDAO implements BlobStoreDAO {
return getObjectBytesFromStore(bucketName, blobId)
.onErrorResume(e -> e instanceof NoSuchKeyException || e
instanceof NoSuchBucketException, e -> {
if (fallbackNamespace.isPresent() &&
bucketNameResolver.isNameSpace(bucketName)) {
- BucketName resolvedFallbackBucketName =
bucketNameResolver.resolve(fallbackNamespace.get());
- return
getObjectBytesFromStore(resolvedFallbackBucketName, blobId);
+ return
getObjectBytesFromStore(fallbackNamespace.get(), blobId);
}
return Mono.error(e);
});
diff --git
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAOTest.java
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAOTest.java
index 0c271a9e95..53c22c08a7 100644
---
a/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAOTest.java
+++
b/server/blob/blob-s3/src/test/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreDAOTest.java
@@ -162,6 +162,30 @@ public class S3BlobStoreDAOTest implements
BlobStoreDAOContract, MetadataAwareBl
assertThat(bytes).isEqualTo(ELEVEN_KILOBYTES);
}
+ @Test
+ void
fallbackBucketNameShouldNotBeAffectedByBucketPrefix(DockerAwsS3Container
dockerAwsS3) {
+ S3BlobStoreConfiguration prefixedConfiguration =
S3BlobStoreConfiguration.builder()
+ .authConfiguration(AwsS3AuthConfiguration.builder()
+ .endpoint(dockerAwsS3.getEndpoint())
+ .accessKeyId(DockerAwsS3Container.ACCESS_KEY_ID)
+ .secretKey(DockerAwsS3Container.SECRET_ACCESS_KEY)
+ .build())
+ .region(dockerAwsS3.dockerAwsS3().region())
+ .defaultBucketName(BucketName.DEFAULT)
+ .bucketPrefix("prefix-")
+ .fallbackBucketName(Optional.of(fallbackBucket))
+ .build();
+ S3BlobStoreDAO prefixedStore = new S3BlobStoreDAO(s3ClientFactory,
prefixedConfiguration, new TestBlobId.Factory(), S3RequestOption.DEFAULT);
+
+ TestBlobId blobId = new TestBlobId("id");
+ // Save in the un-prefixed fallback bucket
+ Mono.from(testee.save(fallbackBucket, blobId,
ELEVEN_KILOBYTES)).block();
+
+ InputStream read = prefixedStore.read(BucketName.DEFAULT,
blobId).payload();
+
+
assertThat(read).hasSameContentAs(ELEVEN_KILOBYTES.asInputStream().payload());
+ }
+
@Test
void shouldNotReadOnFallbackBucketWhenNotReadingOnDefaultOne() {
BlobStoreDAO store = testee();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]