You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/07/30 04:15:20 UTC
[james-project] 07/12: JAMES-3317 add deduplication propertie for
blobstore in configuration
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 986002b275ee7c3dc689c85dcd17c5db9f8503e8
Author: RĂ©mi Kowalski <rk...@linagora.com>
AuthorDate: Wed Jul 22 15:51:50 2020 +0200
JAMES-3317 add deduplication propertie for blobstore in configuration
---
.../destination/conf/blob.properties | 9 ++-
.../destination/conf/blob.properties | 7 ++
.../destination/conf/blob.properties | 7 ++
.../cassandra/destination/conf/blob.properties | 9 ++-
.../modules/blobstore/BlobStoreConfiguration.java | 87 +++++++++++++++++-----
.../james/CassandraRabbitMQAwsS3JmapTestRule.java | 5 +-
.../james/CassandraRabbitMQJamesServerFixture.java | 5 +-
.../james/CassandraRabbitMQSwiftJmapTestRule.java | 5 +-
.../java/org/apache/james/WithCacheExtension.java | 5 +-
.../org/apache/james/WithCassandraBlobStore.java | 5 +-
.../apache/james/WithScanningSearchExtension.java | 5 +-
.../BlobStoreCacheModulesChooserTest.java | 10 ++-
.../blobstore/BlobStoreConfigurationTest.java | 63 ++++++++++++++--
.../blobstore/BlobStoreModulesChooserTest.java | 14 +++-
.../CassandraRabbitMQLdapJmapJamesServerTest.java | 15 +++-
.../rabbitmq/RabbitMQAwsS3SendMDNMethodTest.java | 5 +-
.../RabbitMQAwsS3SpamAssassinContractTest.java | 5 +-
.../cucumber/awss3/RabbitMQAwsS3Stepdefs.java | 5 +-
.../distributed/DistributedAuthenticationTest.java | 5 +-
.../distributed/DistributedEchoMethodTest.java | 5 +-
.../DistributedMailboxGetMethodTest.java | 5 +-
.../distributed/DistributedSessionRouteTest.java | 2 +-
.../rabbitmq/ConsistencyTasksIntegrationTest.java | 5 +-
.../rabbitmq/FixingGhostMailboxTest.java | 5 +-
.../rabbitmq/RabbitMQAuthorizedEndpointsTest.java | 5 +-
.../RabbitMQEventDeadLettersIntegrationTest.java | 5 +-
...stViewProjectionHealthCheckIntegrationTest.java | 5 +-
.../rabbitmq/RabbitMQForwardIntegrationTest.java | 5 +-
.../rabbitmq/RabbitMQJmapExtension.java | 5 +-
.../rabbitmq/RabbitMQJwtFilterIntegrationTest.java | 5 +-
...RabbitMQReindexingWithEventDeadLettersTest.java | 5 +-
.../RabbitMQWebAdminServerIntegrationTest.java | 5 +-
...dminServerTaskSerializationIntegrationTest.java | 5 +-
...RabbitMQDeletedMessageVaultIntegrationTest.java | 5 +-
...LinshareBlobExportMechanismIntegrationTest.java | 5 +-
35 files changed, 287 insertions(+), 61 deletions(-)
diff --git a/dockerfiles/run/guice/cassandra-ldap/destination/conf/blob.properties b/dockerfiles/run/guice/cassandra-ldap/destination/conf/blob.properties
index 90c5135..2ec4035 100644
--- a/dockerfiles/run/guice/cassandra-ldap/destination/conf/blob.properties
+++ b/dockerfiles/run/guice/cassandra-ldap/destination/conf/blob.properties
@@ -6,6 +6,13 @@
# Optional, default is localFile
blob.export.implementation=localFile
+# ========================================= ObjectStorage deduplication ========================================
+# If you choose to enable deduplication, the mails with the same content will be stored only once.
+# Warning: Once this feature is enabled, there is no turning back as turning it off will lead to the deletion of all
+# the mails sharing the same content once one is deleted.
+# Mandatory, Allowed values are: true, false
+deduplication.enable=false
+
# ======================================= Local File Blobs Exporting ========================================
# Optional, directory to store exported blob, directory path follows James file system format
# default is file://var/blobExporting
@@ -23,4 +30,4 @@ blob.export.localFile.directory=file://var/blobExporting
# For Example: It will be formalized to 'Authorization: Basic {Credential of UUID/password}'
# blob.export.linshare.technical.account.uuid=Technical_Account_UUID
-# blob.export.linshare.technical.account.password=password
\ No newline at end of file
+# blob.export.linshare.technical.account.password=password
diff --git a/dockerfiles/run/guice/cassandra-rabbitmq-ldap/destination/conf/blob.properties b/dockerfiles/run/guice/cassandra-rabbitmq-ldap/destination/conf/blob.properties
index 40aee03..6e5e8f8 100644
--- a/dockerfiles/run/guice/cassandra-rabbitmq-ldap/destination/conf/blob.properties
+++ b/dockerfiles/run/guice/cassandra-rabbitmq-ldap/destination/conf/blob.properties
@@ -5,6 +5,13 @@
# Mandatory, allowed values are: cassandra, objectstorage
implementation=objectstorage
+# ========================================= ObjectStorage deduplication ========================================
+# If you choose to enable deduplication, the mails with the same content will be stored only once.
+# Warning: Once this feature is enabled, there is no turning back as turning it off will lead to the deletion of all
+# the mails sharing the same content once one is deleted.
+# Mandatory, Allowed values are: true, false
+deduplication.enable=false
+
# ========================================= Cassandra BlobStore Cache ======================================
# A cassandra cache can be enabled to reduce latency when reading small blobs frequently
# A dedicated keyspace with a replication factor of one is then used
diff --git a/dockerfiles/run/guice/cassandra-rabbitmq/destination/conf/blob.properties b/dockerfiles/run/guice/cassandra-rabbitmq/destination/conf/blob.properties
index 8c98913..c579d80 100644
--- a/dockerfiles/run/guice/cassandra-rabbitmq/destination/conf/blob.properties
+++ b/dockerfiles/run/guice/cassandra-rabbitmq/destination/conf/blob.properties
@@ -5,6 +5,13 @@
# Mandatory, allowed values are: cassandra, objectstorage
implementation=objectstorage
+# ========================================= ObjectStorage deduplication ========================================
+# If you choose to enable deduplication, the mails with the same content will be stored only once.
+# Warning: Once this feature is enabled, there is no turning back as turning it off will lead to the deletion of all
+# the mails sharing the same content once one is deleted.
+# Mandatory, Allowed values are: true, false
+deduplication.enable=false
+
# ========================================= Cassandra BlobStore Cache ======================================
# A cassandra cache can be enabled to reduce latency when reading small blobs frequently
# A dedicated keyspace with a replication factor of one is then used
diff --git a/dockerfiles/run/guice/cassandra/destination/conf/blob.properties b/dockerfiles/run/guice/cassandra/destination/conf/blob.properties
index 90c5135..2ec4035 100644
--- a/dockerfiles/run/guice/cassandra/destination/conf/blob.properties
+++ b/dockerfiles/run/guice/cassandra/destination/conf/blob.properties
@@ -6,6 +6,13 @@
# Optional, default is localFile
blob.export.implementation=localFile
+# ========================================= ObjectStorage deduplication ========================================
+# If you choose to enable deduplication, the mails with the same content will be stored only once.
+# Warning: Once this feature is enabled, there is no turning back as turning it off will lead to the deletion of all
+# the mails sharing the same content once one is deleted.
+# Mandatory, Allowed values are: true, false
+deduplication.enable=false
+
# ======================================= Local File Blobs Exporting ========================================
# Optional, directory to store exported blob, directory path follows James file system format
# default is file://var/blobExporting
@@ -23,4 +30,4 @@ blob.export.localFile.directory=file://var/blobExporting
# For Example: It will be formalized to 'Authorization: Basic {Credential of UUID/password}'
# blob.export.linshare.technical.account.uuid=Technical_Account_UUID
-# blob.export.linshare.technical.account.password=password
\ No newline at end of file
+# blob.export.linshare.technical.account.password=password
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/blobstore/BlobStoreConfiguration.java b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/blobstore/BlobStoreConfiguration.java
index 789813b..7507794 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/blobstore/BlobStoreConfiguration.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/blobstore/BlobStoreConfiguration.java
@@ -29,32 +29,63 @@ import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.apache.james.modules.mailbox.ConfigurationComponent;
+import org.apache.james.server.blob.deduplication.StorageStrategy;
import org.apache.james.server.core.filesystem.FileSystemImpl;
import org.apache.james.utils.PropertiesProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
+import io.vavr.control.Try;
+
public class BlobStoreConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(BlobStoreConfiguration.class);
- public static class CacheChoice {
- private final BlobStoreImplName implementation;
+ @FunctionalInterface
+ public interface RequireImplementation {
+ RequireCache implementation(BlobStoreImplName implementation);
+
+ default RequireCache cassandra() {
+ return implementation(BlobStoreImplName.CASSANDRA);
+ }
+
+ default RequireCache objectStorage() {
+ return implementation(BlobStoreImplName.OBJECTSTORAGE);
+ }
+ }
+
+ @FunctionalInterface
+ public interface RequireCache {
+ RequireStoringStrategy enableCache(boolean enable);
+
+ default RequireStoringStrategy enableCache() {
+ return enableCache(CACHE_ENABLED);
+ }
- private CacheChoice(BlobStoreImplName implementation) {
- this.implementation = implementation;
+ default RequireStoringStrategy disableCache() {
+ return enableCache(!CACHE_ENABLED);
}
+ }
+
+ @FunctionalInterface
+ public interface RequireStoringStrategy {
+ BlobStoreConfiguration strategy(StorageStrategy storageStrategy);
- public BlobStoreConfiguration enableCache() {
- return new BlobStoreConfiguration(implementation, CACHE_ENABLED);
+ default BlobStoreConfiguration passthrough() {
+ return strategy(StorageStrategy.PASSTHROUGH);
}
- public BlobStoreConfiguration disableCache() {
- return new BlobStoreConfiguration(implementation, !CACHE_ENABLED);
+ default BlobStoreConfiguration deduplication() {
+ return strategy(StorageStrategy.DEDUPLICATION);
}
}
+ public static RequireImplementation builder() {
+ return implementation -> enableCache -> storageStrategy -> new BlobStoreConfiguration(implementation, enableCache, storageStrategy);
+ }
+
public enum BlobStoreImplName {
CASSANDRA("cassandra"),
OBJECTSTORAGE("objectstorage");
@@ -87,6 +118,7 @@ public class BlobStoreConfiguration {
static final String BLOBSTORE_IMPLEMENTATION_PROPERTY = "implementation";
static final String CACHE_ENABLE_PROPERTY = "cache.enable";
static final boolean CACHE_ENABLED = true;
+ static final String DEDUPLICATION_ENABLE_PROPERTY = "deduplication.enable";
public static BlobStoreConfiguration parse(org.apache.james.server.core.configuration.Configuration configuration) throws ConfigurationException {
PropertiesProvider propertiesProvider = new PropertiesProvider(new FileSystemImpl(configuration.directories()),
@@ -101,7 +133,10 @@ public class BlobStoreConfiguration {
return BlobStoreConfiguration.from(configuration);
} catch (FileNotFoundException e) {
LOGGER.warn("Could not find " + ConfigurationComponent.NAME + " configuration file, using cassandra blobstore as the default");
- return BlobStoreConfiguration.cassandra();
+ return BlobStoreConfiguration.builder()
+ .cassandra()
+ .disableCache()
+ .passthrough();
}
}
@@ -114,30 +149,44 @@ public class BlobStoreConfiguration {
"supported values in: %s", BLOBSTORE_IMPLEMENTATION_PROPERTY, BlobStoreImplName.supportedImplNames())));
boolean cacheEnabled = configuration.getBoolean(CACHE_ENABLE_PROPERTY, false);
-
- return new BlobStoreConfiguration(blobStoreImplName, cacheEnabled);
+ boolean deduplicationEnabled = Try.ofCallable(() -> configuration.getBoolean(DEDUPLICATION_ENABLE_PROPERTY))
+ .getOrElseThrow(() -> new IllegalStateException("deduplication.enable property is missing please use one of the supported values in: true, false\n" +
+ "If you choose to enable deduplication, the mails with the same content will be stored only once.\n" +
+ "Warning: Once this feature is enabled, there is no turning back as turning it off will lead to the deletion of all\n" +
+ "the mails sharing the same content once one is deleted.\n" +
+ "Upgrade note: If you are upgrading from James 3.5 or older, the deduplication was enabled."));
+
+ if (deduplicationEnabled) {
+ return new BlobStoreConfiguration(blobStoreImplName, cacheEnabled, StorageStrategy.DEDUPLICATION);
+ } else {
+ return new BlobStoreConfiguration(blobStoreImplName, cacheEnabled, StorageStrategy.PASSTHROUGH);
+ }
}
+ @VisibleForTesting
public static BlobStoreConfiguration cassandra() {
- return new BlobStoreConfiguration(BlobStoreImplName.CASSANDRA, !CACHE_ENABLED);
+ return new BlobStoreConfiguration(BlobStoreImplName.CASSANDRA, !CACHE_ENABLED, StorageStrategy.PASSTHROUGH);
}
- public static CacheChoice objectStorage() {
- return new CacheChoice(BlobStoreImplName.OBJECTSTORAGE);
- }
private final BlobStoreImplName implementation;
private final boolean cacheEnabled;
+ private final StorageStrategy storageStrategy;
- BlobStoreConfiguration(BlobStoreImplName implementation, boolean cacheEnabled) {
+ BlobStoreConfiguration(BlobStoreImplName implementation, boolean cacheEnabled, StorageStrategy storageStrategy) {
this.implementation = implementation;
this.cacheEnabled = cacheEnabled;
+ this.storageStrategy = storageStrategy;
}
public boolean cacheEnabled() {
return cacheEnabled;
}
+ public StorageStrategy storageStrategy() {
+ return storageStrategy;
+ }
+
BlobStoreImplName getImplementation() {
return implementation;
}
@@ -148,14 +197,15 @@ public class BlobStoreConfiguration {
BlobStoreConfiguration that = (BlobStoreConfiguration) o;
return Objects.equals(this.implementation, that.implementation)
- && Objects.equals(this.cacheEnabled, that.cacheEnabled);
+ && Objects.equals(this.cacheEnabled, that.cacheEnabled)
+ && Objects.equals(this.storageStrategy, that.storageStrategy);
}
return false;
}
@Override
public final int hashCode() {
- return Objects.hash(implementation, cacheEnabled);
+ return Objects.hash(implementation, cacheEnabled, storageStrategy);
}
@Override
@@ -163,6 +213,7 @@ public class BlobStoreConfiguration {
return MoreObjects.toStringHelper(this)
.add("implementation", implementation)
.add("cacheEnabled", cacheEnabled)
+ .add("storageStrategy", storageStrategy.name())
.toString();
}
}
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQAwsS3JmapTestRule.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQAwsS3JmapTestRule.java
index 0fe2807..9986b37 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQAwsS3JmapTestRule.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQAwsS3JmapTestRule.java
@@ -62,7 +62,10 @@ public class CassandraRabbitMQAwsS3JmapTestRule implements TestRule {
CassandraRabbitMQJamesConfiguration configuration = CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(temporaryFolder.newFolder())
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build();
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerFixture.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerFixture.java
index 264faac..b9878db 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerFixture.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerFixture.java
@@ -40,7 +40,10 @@ public class CassandraRabbitMQJamesServerFixture {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQSwiftJmapTestRule.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQSwiftJmapTestRule.java
index ae2891a..c359987 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQSwiftJmapTestRule.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQSwiftJmapTestRule.java
@@ -61,7 +61,10 @@ public class CassandraRabbitMQSwiftJmapTestRule implements TestRule {
CassandraRabbitMQJamesConfiguration configuration = CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(temporaryFolder.newFolder())
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build();
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithCacheExtension.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithCacheExtension.java
index 0df288c..a971e3e 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithCacheExtension.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithCacheExtension.java
@@ -42,7 +42,10 @@ public class WithCacheExtension implements BeforeAllCallback, AfterAllCallback,
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().enableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .enableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithCassandraBlobStore.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithCassandraBlobStore.java
index 36f9889..98dd3a6 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithCassandraBlobStore.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithCassandraBlobStore.java
@@ -41,7 +41,10 @@ public class WithCassandraBlobStore implements BeforeAllCallback, AfterAllCallba
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.cassandra())
+ .blobStore(BlobStoreConfiguration.builder()
+ .cassandra()
+ .disableCache()
+ .passthrough())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithScanningSearchExtension.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithScanningSearchExtension.java
index 01088b7..ddeaabe 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithScanningSearchExtension.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/WithScanningSearchExtension.java
@@ -42,7 +42,10 @@ public class WithScanningSearchExtension implements BeforeAllCallback, AfterAllC
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.scanning())
.build())
.extension(new CassandraExtension())
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreCacheModulesChooserTest.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreCacheModulesChooserTest.java
index 5cb8c50..03fc807 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreCacheModulesChooserTest.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreCacheModulesChooserTest.java
@@ -27,7 +27,10 @@ import org.junit.jupiter.api.Test;
class BlobStoreCacheModulesChooserTest {
@Test
void chooseModulesShouldReturnCacheDisabledModuleWhenCacheDisabled() {
- assertThat(BlobStoreCacheModulesChooser.chooseModules(BlobStoreConfiguration.objectStorage().disableCache()))
+ assertThat(BlobStoreCacheModulesChooser.chooseModules(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication()))
.hasSize(1)
.first()
.isInstanceOf(BlobStoreCacheModulesChooser.CacheDisabledModule.class);
@@ -35,7 +38,10 @@ class BlobStoreCacheModulesChooserTest {
@Test
void chooseModulesShouldReturnCacheEnabledAndCassandraCacheModulesWhenCacheEnabled() {
- assertThat(BlobStoreCacheModulesChooser.chooseModules(BlobStoreConfiguration.objectStorage().enableCache()))
+ assertThat(BlobStoreCacheModulesChooser.chooseModules(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .enableCache()
+ .deduplication()))
.hasSize(2)
.allSatisfy(module ->
assertThat(module).isOfAnyClassIn(
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreConfigurationTest.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreConfigurationTest.java
index e870fb7..731d6a7 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreConfigurationTest.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreConfigurationTest.java
@@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.james.FakePropertiesProvider;
import org.apache.james.modules.mailbox.ConfigurationComponent;
+import org.apache.james.server.blob.deduplication.StorageStrategy;
import org.junit.jupiter.api.Test;
import nl.jqno.equalsverifier.EqualsVerifier;
@@ -84,34 +85,44 @@ class BlobStoreConfigurationTest {
.build();
assertThat(parse(propertyProvider))
- .isEqualTo(BlobStoreConfiguration.cassandra());
+ .isEqualTo(BlobStoreConfiguration.builder()
+ .cassandra()
+ .disableCache()
+ .passthrough());
}
@Test
void provideChoosingConfigurationShouldReturnObjectStorageFactoryWhenConfigurationImplIsObjectStorage() throws Exception {
PropertiesConfiguration configuration = new PropertiesConfiguration();
configuration.addProperty("implementation", BlobStoreConfiguration.BlobStoreImplName.OBJECTSTORAGE.getName());
+ configuration.addProperty("deduplication.enable", "true");
FakePropertiesProvider propertyProvider = FakePropertiesProvider.builder()
.register(ConfigurationComponent.NAME, configuration)
.build();
assertThat(parse(propertyProvider))
- .isEqualTo(BlobStoreConfiguration.objectStorage().disableCache());
+ .isEqualTo(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication());
}
@Test
void provideChoosingConfigurationShouldReturnCassandraFactoryWhenConfigurationImplIsCassandra() throws Exception {
PropertiesConfiguration configuration = new PropertiesConfiguration();
configuration.addProperty("implementation", BlobStoreConfiguration.BlobStoreImplName.CASSANDRA.getName());
+ configuration.addProperty("deduplication.enable", "false");
FakePropertiesProvider propertyProvider = FakePropertiesProvider.builder()
.register(ConfigurationComponent.NAME, configuration)
.build();
assertThat(parse(propertyProvider))
- .isEqualTo(BlobStoreConfiguration.cassandra());
+ .isEqualTo(BlobStoreConfiguration.builder()
+ .cassandra()
+ .disableCache()
+ .passthrough());
}
-
@Test
void fromShouldThrowWhenBlobStoreImplIsMissing() {
PropertiesConfiguration configuration = new PropertiesConfiguration();
@@ -155,6 +166,7 @@ class BlobStoreConfigurationTest {
void fromShouldReturnConfigurationWhenBlobStoreImplIsCassandra() {
PropertiesConfiguration configuration = new PropertiesConfiguration();
configuration.addProperty("implementation", CASSANDRA);
+ configuration.addProperty("deduplication.enable", "false");
assertThat(
BlobStoreConfiguration.from(configuration)
@@ -167,7 +179,7 @@ class BlobStoreConfigurationTest {
void fromShouldReturnConfigurationWhenBlobStoreImplIsObjectStorage() {
PropertiesConfiguration configuration = new PropertiesConfiguration();
configuration.addProperty("implementation", OBJECT_STORAGE);
-
+ configuration.addProperty("deduplication.enable", "true");
assertThat(
BlobStoreConfiguration.from(configuration)
.getImplementation()
@@ -179,6 +191,7 @@ class BlobStoreConfigurationTest {
void fromShouldReturnConfigurationWhenBlobStoreImplIsSupportedAndCaseInsensitive() {
PropertiesConfiguration configuration = new PropertiesConfiguration();
configuration.addProperty("implementation", "OBjecTStorAGE");
+ configuration.addProperty("deduplication.enable", "true");
assertThat(
BlobStoreConfiguration.from(configuration)
@@ -191,6 +204,7 @@ class BlobStoreConfigurationTest {
void fromShouldReturnConfigurationWhenBlobStoreImplIsSupportedAndHasExtraSpaces() {
PropertiesConfiguration configuration = new PropertiesConfiguration();
configuration.addProperty("implementation", " cassandra ");
+ configuration.addProperty("deduplication.enable", "false");
assertThat(
BlobStoreConfiguration.from(configuration)
@@ -204,6 +218,7 @@ class BlobStoreConfigurationTest {
PropertiesConfiguration configuration = new PropertiesConfiguration();
configuration.addProperty("implementation", BlobStoreConfiguration.BlobStoreImplName.OBJECTSTORAGE.getName());
configuration.addProperty("cache.enable", true);
+ configuration.addProperty("deduplication.enable", "true");
assertThat(BlobStoreConfiguration.from(configuration).cacheEnabled())
.isTrue();
@@ -214,6 +229,7 @@ class BlobStoreConfigurationTest {
PropertiesConfiguration configuration = new PropertiesConfiguration();
configuration.addProperty("implementation", BlobStoreConfiguration.BlobStoreImplName.OBJECTSTORAGE.getName());
configuration.addProperty("cache.enable", false);
+ configuration.addProperty("deduplication.enable", "true");
assertThat(BlobStoreConfiguration.from(configuration).cacheEnabled())
.isFalse();
@@ -223,8 +239,43 @@ class BlobStoreConfigurationTest {
void cacheEnabledShouldDefaultToFalse() {
PropertiesConfiguration configuration = new PropertiesConfiguration();
configuration.addProperty("implementation", BlobStoreConfiguration.BlobStoreImplName.OBJECTSTORAGE.getName());
+ configuration.addProperty("deduplication.enable", "true");
assertThat(BlobStoreConfiguration.from(configuration).cacheEnabled())
.isFalse();
}
-}
\ No newline at end of file
+
+ @Test
+ void storageStrategyShouldBePassthroughWhenDeduplicationDisabled() {
+ PropertiesConfiguration configuration = new PropertiesConfiguration();
+ configuration.addProperty("implementation", BlobStoreConfiguration.BlobStoreImplName.OBJECTSTORAGE.getName());
+ configuration.addProperty("deduplication.enable", "false");
+
+ assertThat(BlobStoreConfiguration.from(configuration).storageStrategy())
+ .isEqualTo(StorageStrategy.PASSTHROUGH);
+ }
+
+ @Test
+ void storageStrategyShouldBeDeduplicationWhenDeduplicationEnabled() {
+ PropertiesConfiguration configuration = new PropertiesConfiguration();
+ configuration.addProperty("implementation", BlobStoreConfiguration.BlobStoreImplName.OBJECTSTORAGE.getName());
+ configuration.addProperty("deduplication.enable", "true");
+
+ assertThat(BlobStoreConfiguration.from(configuration).storageStrategy())
+ .isEqualTo(StorageStrategy.DEDUPLICATION);
+ }
+
+ @Test
+ void buildingConfigurationShouldThrowWhenDeduplicationPropertieIsOmitted() {
+ PropertiesConfiguration configuration = new PropertiesConfiguration();
+ configuration.addProperty("implementation", BlobStoreConfiguration.BlobStoreImplName.OBJECTSTORAGE.getName());
+
+ assertThatThrownBy(() -> BlobStoreConfiguration.from(configuration)).isInstanceOf(IllegalStateException.class)
+ .hasMessage("deduplication.enable property is missing please use one of the supported values in: true, false\n" +
+ "If you choose to enable deduplication, the mails with the same content will be stored only once.\n" +
+ "Warning: Once this feature is enabled, there is no turning back as turning it off will lead to the deletion of all\n" +
+ "the mails sharing the same content once one is deleted.\n" +
+ "Upgrade note: If you are upgrading from James 3.5 or older, the deduplication was enabled.");
+ }
+
+}
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreModulesChooserTest.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreModulesChooserTest.java
index da99509..65735b5 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreModulesChooserTest.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/blobstore/BlobStoreModulesChooserTest.java
@@ -27,15 +27,21 @@ class BlobStoreModulesChooserTest {
@Test
void provideBlobStoreShouldReturnObjectStoreBlobStoreWhenObjectStoreConfigured() {
- assertThat(BlobStoreModulesChooser.chooseModules(BlobStoreConfiguration.objectStorage().disableCache()))
+ assertThat(BlobStoreModulesChooser.chooseModules(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication()))
.first()
- .isInstanceOf(BlobStoreModulesChooser.ObjectStorageDeclarationModule.class);
+ .isInstanceOf(BlobStoreModulesChooser.ObjectStorageDumdBlobStoreDeclarationModule.class);
}
@Test
void provideBlobStoreShouldReturnCassandraBlobStoreWhenCassandraConfigured() {
- assertThat(BlobStoreModulesChooser.chooseModules(BlobStoreConfiguration.cassandra()))
+ assertThat(BlobStoreModulesChooser.chooseModules(BlobStoreConfiguration.builder()
+ .cassandra()
+ .disableCache()
+ .passthrough()))
.first()
- .isInstanceOf(BlobStoreModulesChooser.CassandraDeclarationModule.class);
+ .isInstanceOf(BlobStoreModulesChooser.CassandraDumbBlobStoreDeclarationModule.class);
}
}
\ No newline at end of file
diff --git a/server/container/guice/cassandra-rabbitmq-ldap-guice/src/test/java/org/apache/james/CassandraRabbitMQLdapJmapJamesServerTest.java b/server/container/guice/cassandra-rabbitmq-ldap-guice/src/test/java/org/apache/james/CassandraRabbitMQLdapJmapJamesServerTest.java
index ae150ca..91c8934 100644
--- a/server/container/guice/cassandra-rabbitmq-ldap-guice/src/test/java/org/apache/james/CassandraRabbitMQLdapJmapJamesServerTest.java
+++ b/server/container/guice/cassandra-rabbitmq-ldap-guice/src/test/java/org/apache/james/CassandraRabbitMQLdapJmapJamesServerTest.java
@@ -57,7 +57,10 @@ class CassandraRabbitMQLdapJmapJamesServerTest {
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class WithSwift implements ContractSuite {
@RegisterExtension
- JamesServerExtension testExtension = baseJamesServerExtensionBuilder(BlobStoreConfiguration.objectStorage().disableCache())
+ JamesServerExtension testExtension = baseJamesServerExtensionBuilder(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.extension(new SwiftBlobStoreExtension())
.build();
}
@@ -66,7 +69,10 @@ class CassandraRabbitMQLdapJmapJamesServerTest {
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class WithAwsS3 implements ContractSuite {
@RegisterExtension
- JamesServerExtension testExtension = baseJamesServerExtensionBuilder(BlobStoreConfiguration.objectStorage().disableCache())
+ JamesServerExtension testExtension = baseJamesServerExtensionBuilder(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.extension(new AwsS3BlobStoreExtension())
.build();
}
@@ -75,7 +81,10 @@ class CassandraRabbitMQLdapJmapJamesServerTest {
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class WithoutSwiftOrAwsS3 implements ContractSuite {
@RegisterExtension
- JamesServerExtension testExtension = baseJamesServerExtensionBuilder(BlobStoreConfiguration.cassandra())
+ JamesServerExtension testExtension = baseJamesServerExtensionBuilder(BlobStoreConfiguration.builder()
+ .cassandra()
+ .disableCache()
+ .passthrough())
.build();
}
diff --git a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SendMDNMethodTest.java b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SendMDNMethodTest.java
index 93506b8..cecf617 100644
--- a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SendMDNMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SendMDNMethodTest.java
@@ -42,7 +42,10 @@ public class RabbitMQAwsS3SendMDNMethodTest extends SendMDNMethodTest {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SpamAssassinContractTest.java b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SpamAssassinContractTest.java
index b74ddc7..97a9793 100644
--- a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SpamAssassinContractTest.java
+++ b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SpamAssassinContractTest.java
@@ -41,7 +41,10 @@ class RabbitMQAwsS3SpamAssassinContractTest implements SpamAssassinContract {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/awss3/RabbitMQAwsS3Stepdefs.java b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/awss3/RabbitMQAwsS3Stepdefs.java
index 19bdf2e..f9f60e9 100644
--- a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/awss3/RabbitMQAwsS3Stepdefs.java
+++ b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/cucumber/awss3/RabbitMQAwsS3Stepdefs.java
@@ -81,7 +81,10 @@ public class RabbitMQAwsS3Stepdefs {
CassandraRabbitMQJamesConfiguration configuration = CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(temporaryFolder.newFolder())
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build();
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedAuthenticationTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedAuthenticationTest.java
index 52f9764..219ff54 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedAuthenticationTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedAuthenticationTest.java
@@ -39,7 +39,10 @@ class DistributedAuthenticationTest implements AuthenticationContract {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEchoMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEchoMethodTest.java
index 9827396..79ff634 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEchoMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEchoMethodTest.java
@@ -40,7 +40,10 @@ public class DistributedEchoMethodTest implements EchoMethodContract {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java
index 1e34353..2ccd522 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java
@@ -42,7 +42,10 @@ public class DistributedMailboxGetMethodTest implements MailboxGetMethodContract
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.build())
.extension(new DockerElasticSearchExtension())
.extension(new CassandraExtension())
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedSessionRouteTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedSessionRouteTest.java
index ef34f84..27d9664 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedSessionRouteTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedSessionRouteTest.java
@@ -39,7 +39,7 @@ public class DistributedSessionRouteTest implements SessionRoutesContract {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder().objectStorage().disableCache().passthrough())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/ConsistencyTasksIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/ConsistencyTasksIntegrationTest.java
index 3a5c87a..bdcfa96 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/ConsistencyTasksIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/ConsistencyTasksIntegrationTest.java
@@ -128,7 +128,10 @@ class ConsistencyTasksIntegrationTest {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/FixingGhostMailboxTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/FixingGhostMailboxTest.java
index cd59cd5..603e008 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/FixingGhostMailboxTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/FixingGhostMailboxTest.java
@@ -116,7 +116,10 @@ class FixingGhostMailboxTest {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQAuthorizedEndpointsTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQAuthorizedEndpointsTest.java
index afca267..bebfaa3 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQAuthorizedEndpointsTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQAuthorizedEndpointsTest.java
@@ -44,7 +44,10 @@ class RabbitMQAuthorizedEndpointsTest extends AuthorizedEndpointsTest {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQEventDeadLettersIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQEventDeadLettersIntegrationTest.java
index 70ec14c..29ca1ab 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQEventDeadLettersIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQEventDeadLettersIntegrationTest.java
@@ -205,7 +205,10 @@ class RabbitMQEventDeadLettersIntegrationTest {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQFastViewProjectionHealthCheckIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQFastViewProjectionHealthCheckIntegrationTest.java
index 45416a9..3ecfa00 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQFastViewProjectionHealthCheckIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQFastViewProjectionHealthCheckIntegrationTest.java
@@ -40,7 +40,10 @@ class RabbitMQFastViewProjectionHealthCheckIntegrationTest extends FastViewProje
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQForwardIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQForwardIntegrationTest.java
index e72de6d..cdf1848 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQForwardIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQForwardIntegrationTest.java
@@ -40,7 +40,10 @@ class RabbitMQForwardIntegrationTest extends ForwardIntegrationTest {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJmapExtension.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJmapExtension.java
index da86d14..aaa763f 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJmapExtension.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJmapExtension.java
@@ -150,7 +150,10 @@ public class RabbitMQJmapExtension implements BeforeAllCallback, AfterAllCallbac
CassandraRabbitMQJamesConfiguration configuration = CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(temporaryFolder.newFolder())
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build();
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJwtFilterIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJwtFilterIntegrationTest.java
index fca871b..1a96a6a 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJwtFilterIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQJwtFilterIntegrationTest.java
@@ -42,7 +42,10 @@ class RabbitMQJwtFilterIntegrationTest extends JwtFilterIntegrationTest {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQReindexingWithEventDeadLettersTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQReindexingWithEventDeadLettersTest.java
index fd3168a..df2390a 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQReindexingWithEventDeadLettersTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQReindexingWithEventDeadLettersTest.java
@@ -87,7 +87,10 @@ class RabbitMQReindexingWithEventDeadLettersTest {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(dockerElasticSearch)
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java
index 7162cb3..5f8a1fa 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerIntegrationTest.java
@@ -64,7 +64,10 @@ class RabbitMQWebAdminServerIntegrationTest extends WebAdminServerIntegrationTes
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java
index 3d5e3ed..6ef4410 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/RabbitMQWebAdminServerTaskSerializationIntegrationTest.java
@@ -103,7 +103,10 @@ class RabbitMQWebAdminServerTaskSerializationIntegrationTest {
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/vault/RabbitMQDeletedMessageVaultIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/vault/RabbitMQDeletedMessageVaultIntegrationTest.java
index d4f94d9..df878ac 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/vault/RabbitMQDeletedMessageVaultIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/vault/RabbitMQDeletedMessageVaultIntegrationTest.java
@@ -49,7 +49,10 @@ class RabbitMQDeletedMessageVaultIntegrationTest extends DeletedMessageVaultInte
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(ES_EXTENSION)
diff --git a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/vault/RabbitMQLinshareBlobExportMechanismIntegrationTest.java b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/vault/RabbitMQLinshareBlobExportMechanismIntegrationTest.java
index ed82af5..43136e1 100644
--- a/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/vault/RabbitMQLinshareBlobExportMechanismIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/distributed-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/rabbitmq/vault/RabbitMQLinshareBlobExportMechanismIntegrationTest.java
@@ -46,7 +46,10 @@ class RabbitMQLinshareBlobExportMechanismIntegrationTest extends LinshareBlobExp
CassandraRabbitMQJamesConfiguration.builder()
.workingDirectory(tmpDir)
.configurationFromClasspath()
- .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+ .blobStore(BlobStoreConfiguration.builder()
+ .objectStorage()
+ .disableCache()
+ .deduplication())
.searchConfiguration(SearchConfiguration.elasticSearch())
.build())
.extension(new DockerElasticSearchExtension())
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org