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 <[email protected]> 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: [email protected] For additional commands, e-mail: [email protected]
