This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 0c49996fe01084c570b231ab68dcf660cf36c85a Author: Matthieu Baechler <[email protected]> AuthorDate: Tue Feb 11 16:44:03 2020 +0100 JAMES-3065 exclude Reactor Mono/Flux from API projects --- .../src/main/java/org/apache/james/util/Host.java | 0 .../src/main/java/org/apache/james/util/Port.java | 0 .../test/java/org/apache/james/util/HostTest.java | 0 .../test/java/org/apache/james/util/PortTest.java | 0 mailbox/api/pom.xml | 8 +- .../james/mailbox/model/MailboxAnnotationKey.java | 3 +- .../java/org/apache/james/mailbox/model/Quota.java | 6 ++ .../james/mailbox/quota/MaxQuotaManager.java | 41 ++++++--- .../cassandra/mail/CassandraAttachmentMapper.java | 6 +- .../cassandra/mail/CassandraMessageDAO.java | 6 +- .../mail/migration/AttachmentV2Migration.java | 2 +- .../cassandra/mail/CassandraMailboxMapperTest.java | 5 +- mailbox/event/event-memory/pom.xml | 4 + .../vault/blob/BlobStoreDeletedMessageVault.java | 15 +-- .../james/mailbox/store/PreDeletionHooks.java | 5 +- metrics/metrics-api/pom.xml | 8 +- .../apache/james/metrics/api/MetricFactory.java | 13 +-- metrics/metrics-dropwizard/pom.xml | 4 + .../dropwizard/DropWizardMetricFactory.java | 9 ++ metrics/metrics-logger/pom.xml | 4 + .../james/metrics/logger/DefaultMetricFactory.java | 9 ++ .../metrics/tests/RecordingMetricFactory.java | 9 ++ pom.xml | 5 + protocols/api/pom.xml | 8 -- server/blob/blob-api/pom.xml | 9 ++ .../org/apache/james/blob/api/BlobPartsId.java | 4 +- .../java/org/apache/james/blob/api/BlobStore.java | 14 +-- .../blob/api/{BlobPartsId.java => BlobType.java} | 29 +++++- .../org/apache/james/blob/api/DumbBlobStore.java | 20 ++-- .../apache/james/blob/api/MetricableBlobStore.java | 29 +++--- .../apache/james/blob/api/BlobStoreContract.java | 46 +++++----- .../org/apache/james/blob/api/BlobTypeTest.java} | 20 ++-- .../james/blob/api/BucketBlobStoreContract.java | 46 +++++----- .../blob/api/BucketDumbBlobStoreContract.java | 46 +++++----- .../james/blob/api/DeleteBlobStoreContract.java | 48 +++++----- .../blob/api/DeleteDumbBlobStoreContract.java | 52 +++++------ .../blob/api/MetricableBlobStoreContract.java | 36 ++++---- .../blob/api/ReadSaveDumbBlobStoreContract.java | 101 ++++++++++----------- .../blob/cassandra/CassandraBlobStoreTest.java | 12 +-- .../blob/blob-common}/pom.xml | 19 ++-- .../main/java/org/apache/james/blob/api/Store.java | 32 +------ .../file/LocalFileBlobExportMechanismTest.java | 11 ++- server/blob/blob-memory/pom.xml | 9 ++ .../ObjectStorageBlobStoreContract.java | 4 +- .../objectstorage/ObjectStorageBlobStoreTest.java | 22 ++--- .../apache/james/blob/union/HybridBlobStore.java | 12 +-- server/blob/mail-store/pom.xml | 8 ++ .../apache/james/blob/mail/MimeMessagePartsId.java | 10 +- .../apache/james/blob/mail/MimeMessageStore.java | 2 +- .../james/blob/mail/MimeMessageStoreTest.java | 6 +- server/blob/pom.xml | 1 + server/container/jetty/pom.xml | 4 + server/container/lifecycle-api/pom.xml | 8 -- .../container/metrics/metrics-es-reporter/pom.xml | 4 +- server/data/data-api/pom.xml | 4 - .../org/apache/james/jmap/draft/model/Keyword.java | 11 +-- server/protocols/webadmin/webadmin-core/pom.xml | 5 + .../james/webadmin/vault/routes/ExportService.java | 2 +- server/queue/queue-api/pom.xml | 5 + server/queue/queue-jms/pom.xml | 4 + server/task/task-api/pom.xml | 15 ++- server/task/task-json/pom.xml | 4 + .../linshare/LinshareBlobExportMechanismTest.java | 10 +- 63 files changed, 490 insertions(+), 404 deletions(-) diff --git a/server/container/util/src/main/java/org/apache/james/util/Host.java b/core/src/main/java/org/apache/james/util/Host.java similarity index 100% rename from server/container/util/src/main/java/org/apache/james/util/Host.java rename to core/src/main/java/org/apache/james/util/Host.java diff --git a/server/container/util/src/main/java/org/apache/james/util/Port.java b/core/src/main/java/org/apache/james/util/Port.java similarity index 100% rename from server/container/util/src/main/java/org/apache/james/util/Port.java rename to core/src/main/java/org/apache/james/util/Port.java diff --git a/server/container/util/src/test/java/org/apache/james/util/HostTest.java b/core/src/test/java/org/apache/james/util/HostTest.java similarity index 100% rename from server/container/util/src/test/java/org/apache/james/util/HostTest.java rename to core/src/test/java/org/apache/james/util/HostTest.java diff --git a/server/container/util/src/test/java/org/apache/james/util/PortTest.java b/core/src/test/java/org/apache/james/util/PortTest.java similarity index 100% rename from server/container/util/src/test/java/org/apache/james/util/PortTest.java rename to core/src/test/java/org/apache/james/util/PortTest.java diff --git a/mailbox/api/pom.xml b/mailbox/api/pom.xml index 118cc9a..1440ed3 100644 --- a/mailbox/api/pom.xml +++ b/mailbox/api/pom.xml @@ -47,10 +47,6 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> - <artifactId>james-server-util</artifactId> - </dependency> - <dependency> - <groupId>${james.groupId}</groupId> <artifactId>apache-mime4j-dom</artifactId> </dependency> <dependency> @@ -89,8 +85,8 @@ <scope>test</scope> </dependency> <dependency> - <groupId>io.projectreactor</groupId> - <artifactId>reactor-core</artifactId> + <groupId>javax.inject</groupId> + <artifactId>javax.inject</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxAnnotationKey.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxAnnotationKey.java index a4ac543..810308b 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxAnnotationKey.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxAnnotationKey.java @@ -22,7 +22,6 @@ package org.apache.james.mailbox.model; import java.util.Locale; import org.apache.commons.lang3.StringUtils; -import org.apache.james.util.UnicodeSetUtils; import com.google.common.base.Objects; import com.google.common.base.Preconditions; @@ -33,7 +32,7 @@ public class MailboxAnnotationKey { public static final String SLASH_CHARACTER = "/"; public static final String TWO_SLASH_CHARACTER = "//"; - private static final UnicodeSet NAME_ANNOTATION_PATTERN = UnicodeSetUtils.letterOrDigitUnicodeSet() + private static final UnicodeSet NAME_ANNOTATION_PATTERN = new UnicodeSet("[[a-z][A-Z][0-9]]") .add(SLASH_CHARACTER) .freeze(); public static final int MINIMUM_COMPONENTS = 2; diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java index 0cbfe2e..565f12e 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Quota.java @@ -18,6 +18,8 @@ ****************************************************************/ package org.apache.james.mailbox.model; +import java.util.Arrays; +import java.util.List; import java.util.Map; import org.apache.james.core.quota.QuotaLimitValue; @@ -35,6 +37,10 @@ public class Quota<T extends QuotaLimitValue<T>, U extends QuotaUsageValue<U, T> User } + public static List<Scope> allScopes() { + return Arrays.asList(Quota.Scope.User, Quota.Scope.Domain, Quota.Scope.Global); + } + public static <T extends QuotaLimitValue<T>, U extends QuotaUsageValue<U, T>> Builder<T, U> builder() { return new Builder<>(); } diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java index 76afb3f..1030620 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java @@ -20,7 +20,10 @@ package org.apache.james.mailbox.quota; import java.util.Map; +import java.util.Objects; import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Stream; import org.apache.james.core.Domain; import org.apache.james.core.quota.QuotaCountLimit; @@ -29,7 +32,6 @@ import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.Quota; import org.apache.james.mailbox.model.Quota.Scope; import org.apache.james.mailbox.model.QuotaRoot; -import org.apache.james.util.OptionalUtils; import com.github.fge.lambdas.Throwing; @@ -121,10 +123,11 @@ public interface MaxQuotaManager { } default Optional<QuotaSizeLimit> getMaxStorage(Map<Quota.Scope, QuotaSizeLimit> maxStorageDetails) { - return OptionalUtils.or( - Optional.ofNullable(maxStorageDetails.get(Quota.Scope.User)), - Optional.ofNullable(maxStorageDetails.get(Quota.Scope.Domain)), - Optional.ofNullable(maxStorageDetails.get(Quota.Scope.Global))); + return Quota.allScopes() + .stream() + .map(maxStorageDetails::get) + .filter(Objects::nonNull) + .findFirst(); } /** @@ -139,10 +142,10 @@ public interface MaxQuotaManager { } default Optional<QuotaCountLimit> getMaxMessage(Map<Quota.Scope, QuotaCountLimit> maxMessagesDetails) { - return OptionalUtils.or( - Optional.ofNullable(maxMessagesDetails.get(Quota.Scope.User)), - Optional.ofNullable(maxMessagesDetails.get(Quota.Scope.Domain)), - Optional.ofNullable(maxMessagesDetails.get(Quota.Scope.Global))); + return Stream.of(Quota.Scope.User, Quota.Scope.Domain, Quota.Scope.Global) + .map(maxMessagesDetails::get) + .filter(Objects::nonNull) + .findFirst(); } Map<Quota.Scope, QuotaCountLimit> listMaxMessagesDetails(QuotaRoot quotaRoot); @@ -162,14 +165,22 @@ public interface MaxQuotaManager { void removeDomainMaxStorage(Domain domain) throws MailboxException; default Optional<QuotaCountLimit> getComputedMaxMessage(Domain domain) throws MailboxException { - return OptionalUtils.orSuppliers( - Throwing.supplier(() -> getDomainMaxMessage(domain)).sneakyThrow(), - Throwing.supplier(this::getGlobalMaxMessage).sneakyThrow()); + return Stream.of( + Throwing.supplier(() -> getDomainMaxMessage(domain)).sneakyThrow(), + Throwing.supplier(this::getGlobalMaxMessage).sneakyThrow()) + .map(Supplier::get) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst(); } default Optional<QuotaSizeLimit> getComputedMaxStorage(Domain domain) throws MailboxException { - return OptionalUtils.orSuppliers( - Throwing.supplier(() -> getDomainMaxStorage(domain)).sneakyThrow(), - Throwing.supplier(this::getGlobalMaxStorage).sneakyThrow()); + return Stream.of( + Throwing.supplier(() -> getDomainMaxStorage(domain)).sneakyThrow(), + Throwing.supplier(this::getGlobalMaxStorage).sneakyThrow()) + .map(Supplier::get) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst(); } } \ No newline at end of file diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java index 867a002..adf1c3f 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java @@ -81,7 +81,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper { } private Mono<Attachment> retrievePayload(DAOAttachment daoAttachment) { - return blobStore.readBytes(blobStore.getDefaultBucketName(), daoAttachment.getBlobId()) + return Mono.from(blobStore.readBytes(blobStore.getDefaultBucketName(), daoAttachment.getBlobId())) .map(daoAttachment::toAttachment); } @@ -112,7 +112,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper { @Override public void storeAttachmentForOwner(Attachment attachment, Username owner) throws MailboxException { ownerDAO.addOwner(attachment.getAttachmentId(), owner) - .then(blobStore.save(blobStore.getDefaultBucketName(), attachment.getBytes(), LOW_COST)) + .then(Mono.from(blobStore.save(blobStore.getDefaultBucketName(), attachment.getBytes(), LOW_COST))) .map(blobId -> CassandraAttachmentDAOV2.from(attachment, blobId)) .flatMap(attachmentDAOV2::storeAttachment) .block(); @@ -139,7 +139,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper { } public Mono<Void> storeAttachmentAsync(Attachment attachment, MessageId ownerMessageId) { - return blobStore.save(blobStore.getDefaultBucketName(), attachment.getBytes(), LOW_COST) + return Mono.from(blobStore.save(blobStore.getDefaultBucketName(), attachment.getBytes(), LOW_COST)) .map(blobId -> CassandraAttachmentDAOV2.from(attachment, blobId)) .flatMap(daoAttachment -> storeAttachmentWithIndex(daoAttachment, ownerMessageId)); } diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java index 16f81fd..0bfce81 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java @@ -184,8 +184,8 @@ public class CassandraMessageDAO { byte[] headerContent = IOUtils.toByteArray(message.getHeaderContent()); byte[] bodyContent = IOUtils.toByteArray(message.getBodyContent()); - Mono<BlobId> bodyFuture = blobStore.save(blobStore.getDefaultBucketName(), bodyContent, LOW_COST); - Mono<BlobId> headerFuture = blobStore.save(blobStore.getDefaultBucketName(), headerContent, SIZE_BASED); + Mono<BlobId> bodyFuture = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), bodyContent, LOW_COST)); + Mono<BlobId> headerFuture = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), headerContent, SIZE_BASED)); return headerFuture.zipWith(bodyFuture); } catch (IOException e) { @@ -365,7 +365,7 @@ public class CassandraMessageDAO { } private Mono<byte[]> getFieldContent(String field, Row row) { - return blobStore.readBytes(blobStore.getDefaultBucketName(), blobIdFactory.from(row.getString(field))); + return Mono.from(blobStore.readBytes(blobStore.getDefaultBucketName(), blobIdFactory.from(row.getString(field)))); } public static MessageResult notFound(ComposedMessageIdWithMetaData id) { diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2Migration.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2Migration.java index 25474f5..020a8d5 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2Migration.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/migration/AttachmentV2Migration.java @@ -57,7 +57,7 @@ public class AttachmentV2Migration implements Migration { } private Mono<Void> migrateAttachment(Attachment attachment) { - return blobStore.save(blobStore.getDefaultBucketName(), attachment.getBytes(), LOW_COST) + return Mono.from(blobStore.save(blobStore.getDefaultBucketName(), attachment.getBytes(), LOW_COST)) .map(blobId -> CassandraAttachmentDAOV2.from(attachment, blobId)) .flatMap(attachmentDAOV2::storeAttachment) .then(attachmentDAOV1.deleteAttachment(attachment.getAttachmentId())); diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java index 986fe8b..2a044ec 100644 --- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java +++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java @@ -23,6 +23,8 @@ import static org.apache.james.backends.cassandra.Scenario.Builder.fail; import static org.apache.james.mailbox.model.MailboxAssertingTool.softly; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; import java.util.List; @@ -57,6 +59,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import com.github.fge.lambdas.Throwing; import com.github.fge.lambdas.runnable.ThrowingRunnable; +import reactor.core.publisher.Mono; class CassandraMailboxMapperTest { private static final UidValidity UID_VALIDITY = UidValidity.ofValid(52); @@ -446,7 +449,7 @@ class CassandraMailboxMapperTest { .isNotEqualTo(testee.findMailboxById(inboxId).getName()); } - @Disabled("JAMES-3057 org.apache.james.mailbox.exception.MailboxNotFoundException: INBOX can not be found") + @Disabled("JAMES-3056 org.apache.james.mailbox.exception.MailboxNotFoundException: 'mailboxId' can not be found") @Test void createAfterPreviousFailedCreateShouldCreateAMailbox(CassandraCluster cassandra) throws MailboxException { cassandra.getConf() diff --git a/mailbox/event/event-memory/pom.xml b/mailbox/event/event-memory/pom.xml index 72d32d0..943a479 100644 --- a/mailbox/event/event-memory/pom.xml +++ b/mailbox/event/event-memory/pom.xml @@ -44,6 +44,10 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> + <artifactId>james-server-util</artifactId> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>metrics-api</artifactId> </dependency> <dependency> diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java index e545e53..a7bf391 100644 --- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java +++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java @@ -98,7 +98,7 @@ public class BlobStoreDeletedMessageVault implements DeletedMessageVault { } private Mono<Void> appendMessage(DeletedMessage deletedMessage, InputStream mimeMessage, BucketName bucketName) { - return blobStore.save(bucketName, mimeMessage, LOW_COST) + return Mono.from(blobStore.save(bucketName, mimeMessage, LOW_COST)) .map(blobId -> StorageInformation.builder() .bucketName(bucketName) .blobId(blobId)) @@ -156,7 +156,7 @@ public class BlobStoreDeletedMessageVault implements DeletedMessageVault { return Mono.from(messageMetadataVault.retrieveStorageInformation(username, messageId)) .flatMap(storageInformation -> Mono.from(messageMetadataVault.remove(storageInformation.getBucketName(), username, messageId)) .thenReturn(storageInformation)) - .flatMap(storageInformation -> blobStore.delete(storageInformation.getBucketName(), storageInformation.getBlobId())) + .flatMap(storageInformation -> Mono.from(blobStore.delete(storageInformation.getBucketName(), storageInformation.getBlobId()))) .subscribeOn(Schedulers.elastic()); } @@ -167,10 +167,11 @@ public class BlobStoreDeletedMessageVault implements DeletedMessageVault { Flux<BucketName> deleteExpiredMessages(ZonedDateTime beginningOfRetentionPeriod) { - return metricFactory.runPublishingTimerMetric( - DELETE_EXPIRED_MESSAGES_METRIC_NAME, - retentionQualifiedBuckets(beginningOfRetentionPeriod) - .flatMap(bucketName -> deleteBucketData(bucketName).then(Mono.just(bucketName)))); + return Flux.from( + metricFactory.runPublishingTimerMetric( + DELETE_EXPIRED_MESSAGES_METRIC_NAME, + retentionQualifiedBuckets(beginningOfRetentionPeriod) + .flatMap(bucketName -> deleteBucketData(bucketName).then(Mono.just(bucketName))))); } @@ -196,7 +197,7 @@ public class BlobStoreDeletedMessageVault implements DeletedMessageVault { } private Mono<Void> deleteBucketData(BucketName bucketName) { - return blobStore.deleteBucket(bucketName) + return Mono.from(blobStore.deleteBucket(bucketName)) .then(Mono.from(messageMetadataVault.removeMetadataRelatedToBucket(bucketName))); } } diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/PreDeletionHooks.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/PreDeletionHooks.java index 46f6e7a..b53e039 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/PreDeletionHooks.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/PreDeletionHooks.java @@ -62,8 +62,7 @@ public class PreDeletionHooks { } private Mono<Void> publishMetric(PreDeletionHook.DeleteOperation deleteOperation, PreDeletionHook hook, MetricFactory factory) { - return factory.runPublishingTimerMetric( - PRE_DELETION_HOOK_METRIC_NAME, - Mono.from(hook.notifyDelete(deleteOperation))); + return Mono.from( + factory.runPublishingTimerMetric(PRE_DELETION_HOOK_METRIC_NAME, hook.notifyDelete(deleteOperation))); } } diff --git a/metrics/metrics-api/pom.xml b/metrics/metrics-api/pom.xml index 3212965..8e066b1 100644 --- a/metrics/metrics-api/pom.xml +++ b/metrics/metrics-api/pom.xml @@ -36,13 +36,13 @@ <scope>test</scope> </dependency> <dependency> - <groupId>io.projectreactor</groupId> - <artifactId>reactor-core</artifactId> - </dependency> - <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> + <dependency> + <groupId>org.reactivestreams</groupId> + <artifactId>reactive-streams</artifactId> + </dependency> </dependencies> </project> diff --git a/metrics/metrics-api/src/main/java/org/apache/james/metrics/api/MetricFactory.java b/metrics/metrics-api/src/main/java/org/apache/james/metrics/api/MetricFactory.java index 670c637..a689b44 100644 --- a/metrics/metrics-api/src/main/java/org/apache/james/metrics/api/MetricFactory.java +++ b/metrics/metrics-api/src/main/java/org/apache/james/metrics/api/MetricFactory.java @@ -21,8 +21,7 @@ package org.apache.james.metrics.api; import java.util.function.Supplier; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; +import org.reactivestreams.Publisher; public interface MetricFactory { @@ -39,15 +38,7 @@ public interface MetricFactory { } } - default <T> Mono<T> runPublishingTimerMetric(String name, Mono<T> mono) { - TimeMetric timer = timer(name); - return mono.doOnSuccess(success -> timer.stopAndPublish()); - } - - default <T> Flux<T> runPublishingTimerMetric(String name, Flux<T> flux) { - TimeMetric timer = timer(name); - return flux.doOnComplete(timer::stopAndPublish); - } + <T> Publisher<T> runPublishingTimerMetric(String name, Publisher<T> publisher); default void runPublishingTimerMetric(String name, Runnable runnable) { runPublishingTimerMetric(name, () -> { diff --git a/metrics/metrics-dropwizard/pom.xml b/metrics/metrics-dropwizard/pom.xml index d0be914..624d2fe 100644 --- a/metrics/metrics-dropwizard/pom.xml +++ b/metrics/metrics-dropwizard/pom.xml @@ -62,6 +62,10 @@ <artifactId>metrics-jvm</artifactId> </dependency> <dependency> + <groupId>io.projectreactor</groupId> + <artifactId>reactor-core</artifactId> + </dependency> + <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> </dependency> diff --git a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java index 2d040d4..8defd20 100644 --- a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java +++ b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java @@ -27,10 +27,13 @@ import org.apache.james.lifecycle.api.Startable; import org.apache.james.metrics.api.Metric; import org.apache.james.metrics.api.MetricFactory; import org.apache.james.metrics.api.TimeMetric; +import org.reactivestreams.Publisher; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.jmx.JmxReporter; +import reactor.core.publisher.Flux; + public class DropWizardMetricFactory implements MetricFactory, Startable { private final MetricRegistry metricRegistry; @@ -53,6 +56,12 @@ public class DropWizardMetricFactory implements MetricFactory, Startable { return new DropWizardTimeMetric(name, metricRegistry.timer(name).time()); } + @Override + public <T> Publisher<T> runPublishingTimerMetric(String name, Publisher<T> publisher) { + TimeMetric timer = timer(name); + return Flux.from(publisher).doOnComplete(timer::stopAndPublish); + } + @PostConstruct public void start() { jmxReporter.start(); diff --git a/metrics/metrics-logger/pom.xml b/metrics/metrics-logger/pom.xml index c843ac1..4857038 100644 --- a/metrics/metrics-logger/pom.xml +++ b/metrics/metrics-logger/pom.xml @@ -50,6 +50,10 @@ <artifactId>guava</artifactId> </dependency> <dependency> + <groupId>io.projectreactor</groupId> + <artifactId>reactor-core</artifactId> + </dependency> + <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> diff --git a/metrics/metrics-logger/src/main/java/org/apache/james/metrics/logger/DefaultMetricFactory.java b/metrics/metrics-logger/src/main/java/org/apache/james/metrics/logger/DefaultMetricFactory.java index db64916..c603c71 100644 --- a/metrics/metrics-logger/src/main/java/org/apache/james/metrics/logger/DefaultMetricFactory.java +++ b/metrics/metrics-logger/src/main/java/org/apache/james/metrics/logger/DefaultMetricFactory.java @@ -21,9 +21,12 @@ package org.apache.james.metrics.logger; import org.apache.james.metrics.api.Metric; import org.apache.james.metrics.api.MetricFactory; import org.apache.james.metrics.api.TimeMetric; +import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; + public class DefaultMetricFactory implements MetricFactory { public static final Logger LOGGER = LoggerFactory.getLogger(DefaultMetricFactory.class); @@ -38,4 +41,10 @@ public class DefaultMetricFactory implements MetricFactory { return new DefaultTimeMetric(name); } + @Override + public <T> Publisher<T> runPublishingTimerMetric(String name, Publisher<T> publisher) { + TimeMetric timer = timer(name); + return Flux.from(publisher).doOnComplete(timer::stopAndPublish); + } + } diff --git a/metrics/metrics-tests/src/main/java/org/apache/james/metrics/tests/RecordingMetricFactory.java b/metrics/metrics-tests/src/main/java/org/apache/james/metrics/tests/RecordingMetricFactory.java index 24438d5..6009e54 100644 --- a/metrics/metrics-tests/src/main/java/org/apache/james/metrics/tests/RecordingMetricFactory.java +++ b/metrics/metrics-tests/src/main/java/org/apache/james/metrics/tests/RecordingMetricFactory.java @@ -28,12 +28,15 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.james.metrics.api.Metric; import org.apache.james.metrics.api.MetricFactory; import org.apache.james.metrics.api.TimeMetric; +import org.reactivestreams.Publisher; import com.github.steveash.guavate.Guavate; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; +import reactor.core.publisher.Flux; + public class RecordingMetricFactory implements MetricFactory { private final Multimap<String, Duration> executionTimes = Multimaps.synchronizedListMultimap(ArrayListMultimap.create()); private final ConcurrentHashMap<String, AtomicInteger> counters = new ConcurrentHashMap<>(); @@ -56,6 +59,12 @@ public class RecordingMetricFactory implements MetricFactory { }); } + @Override + public <T> Publisher<T> runPublishingTimerMetric(String name, Publisher<T> publisher) { + TimeMetric timer = timer(name); + return Flux.from(publisher).doOnComplete(timer::stopAndPublish); + } + public Collection<Duration> executionTimesFor(String name) { synchronized (executionTimes) { return executionTimes.get(name); diff --git a/pom.xml b/pom.xml index 1018e28..7bee095 100644 --- a/pom.xml +++ b/pom.xml @@ -1110,6 +1110,11 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> + <artifactId>blob-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${james.groupId}</groupId> <artifactId>blob-export-api</artifactId> <version>${project.version}</version> </dependency> diff --git a/protocols/api/pom.xml b/protocols/api/pom.xml index e1b8b49..9ac0dce 100644 --- a/protocols/api/pom.xml +++ b/protocols/api/pom.xml @@ -56,14 +56,6 @@ </dependency> <dependency> <groupId>org.slf4j</groupId> - <artifactId>jcl-over-slf4j</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>log4j-over-slf4j</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> </dependencies> diff --git a/server/blob/blob-api/pom.xml b/server/blob/blob-api/pom.xml index f4ebecc..cbe5c0e 100644 --- a/server/blob/blob-api/pom.xml +++ b/server/blob/blob-api/pom.xml @@ -36,6 +36,7 @@ <dependency> <groupId>${james.groupId}</groupId> <artifactId>james-server-util</artifactId> + <scope>test</scope> </dependency> <dependency> <groupId>${james.groupId}</groupId> @@ -61,6 +62,10 @@ <artifactId>guava</artifactId> </dependency> <dependency> + <groupId>javax.inject</groupId> + <artifactId>javax.inject</artifactId> + </dependency> + <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> @@ -69,5 +74,9 @@ <artifactId>mockito-core</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.reactivestreams</groupId> + <artifactId>reactive-streams</artifactId> + </dependency> </dependencies> </project> diff --git a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobPartsId.java b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobPartsId.java index a6a9412..96867c6 100644 --- a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobPartsId.java +++ b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobPartsId.java @@ -23,8 +23,8 @@ import java.util.Map; public interface BlobPartsId { interface Factory<I extends BlobPartsId> { - I generate(Map<Store.BlobType, BlobId> map); + I generate(Map<BlobType, BlobId> map); } - Map<Store.BlobType, BlobId> asMap(); + Map<BlobType, BlobId> asMap(); } diff --git a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobStore.java b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobStore.java index 458b354..a887a32 100644 --- a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobStore.java +++ b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobStore.java @@ -21,7 +21,7 @@ package org.apache.james.blob.api; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import reactor.core.publisher.Mono; +import org.reactivestreams.Publisher; public interface BlobStore { @@ -31,21 +31,21 @@ public interface BlobStore { HIGH_PERFORMANCE } - Mono<BlobId> save(BucketName bucketName, byte[] data, StoragePolicy storagePolicy); + Publisher<BlobId> save(BucketName bucketName, byte[] data, StoragePolicy storagePolicy); - Mono<BlobId> save(BucketName bucketName, InputStream data, StoragePolicy storagePolicy); + Publisher<BlobId> save(BucketName bucketName, InputStream data, StoragePolicy storagePolicy); - default Mono<BlobId> save(BucketName bucketName, String data, StoragePolicy storagePolicy) { + default Publisher<BlobId> save(BucketName bucketName, String data, StoragePolicy storagePolicy) { return save(bucketName, data.getBytes(StandardCharsets.UTF_8), storagePolicy); } - Mono<byte[]> readBytes(BucketName bucketName, BlobId blobId); + Publisher<byte[]> readBytes(BucketName bucketName, BlobId blobId); InputStream read(BucketName bucketName, BlobId blobId); BucketName getDefaultBucketName(); - Mono<Void> deleteBucket(BucketName bucketName); + Publisher<Void> deleteBucket(BucketName bucketName); - Mono<Void> delete(BucketName bucketName, BlobId blobId); + Publisher<Void> delete(BucketName bucketName, BlobId blobId); } diff --git a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobPartsId.java b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobType.java similarity index 69% copy from server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobPartsId.java copy to server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobType.java index a6a9412..e068c68 100644 --- a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobPartsId.java +++ b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobType.java @@ -19,12 +19,31 @@ package org.apache.james.blob.api; -import java.util.Map; +import java.util.Objects; -public interface BlobPartsId { - interface Factory<I extends BlobPartsId> { - I generate(Map<Store.BlobType, BlobId> map); +public class BlobType { + private final String name; + + public BlobType(String name) { + this.name = name; + } + + public String getName() { + return name; } - Map<Store.BlobType, BlobId> asMap(); + @Override + public final boolean equals(Object o) { + if (o instanceof BlobType) { + BlobType blobType = (BlobType) o; + + return Objects.equals(this.name, blobType.name); + } + return false; + } + + @Override + public final int hashCode() { + return Objects.hash(name); + } } diff --git a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/DumbBlobStore.java b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/DumbBlobStore.java index 9f993c5..f2045fc 100644 --- a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/DumbBlobStore.java +++ b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/DumbBlobStore.java @@ -22,9 +22,9 @@ package org.apache.james.blob.api; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import com.google.common.io.ByteSource; +import org.reactivestreams.Publisher; -import reactor.core.publisher.Mono; +import com.google.common.io.ByteSource; public interface DumbBlobStore { @@ -44,7 +44,7 @@ public interface DumbBlobStore { * an ObjectNotFoundException in its error channel when the blobId or the bucket is not found * or an IOObjectStoreException when an unexpected IO error occurs */ - Mono<byte[]> readBytes(BucketName bucketName, BlobId blobId); + Publisher<byte[]> readBytes(BucketName bucketName, BlobId blobId); /** @@ -55,26 +55,26 @@ public interface DumbBlobStore { * @return an empty Mono when the save succeed, * otherwise an IOObjectStoreException in its error channel */ - Mono<Void> save(BucketName bucketName, BlobId blobId, byte[] data); + Publisher<Void> save(BucketName bucketName, BlobId blobId, byte[] data); /** * @see #save(BucketName, BlobId, byte[]) * * The InputStream should be closed after the call to this method */ - Mono<Void> save(BucketName bucketName, BlobId blobId, InputStream inputStream); + Publisher<Void> save(BucketName bucketName, BlobId blobId, InputStream inputStream); /** * @see #save(BucketName, BlobId, byte[]) */ - Mono<Void> save(BucketName bucketName, BlobId blobId, ByteSource content); + Publisher<Void> save(BucketName bucketName, BlobId blobId, ByteSource content); /** * @see #save(BucketName, BlobId, byte[]) * * The String is stored as UTF-8. */ - default Mono<Void> save(BucketName bucketName, BlobId blobId, String data) { + default Publisher<Void> save(BucketName bucketName, BlobId blobId, String data) { return save(bucketName, blobId, data.getBytes(StandardCharsets.UTF_8)); } @@ -86,7 +86,7 @@ public interface DumbBlobStore { * (either the blob doesn't exist in the bucket or the bucket itself doesn't exist) * otherwise an IOObjectStoreException in its error channel */ - Mono<Void> delete(BucketName bucketName, BlobId blobId); + Publisher<Void> delete(BucketName bucketName, BlobId blobId); /** * Remove a bucket based on its BucketName @@ -95,8 +95,8 @@ public interface DumbBlobStore { * Saving or reading blobs concurrently of bucket deletion can lead * to an inconsistent state. * - * @return a successful Mono if the bucket is deleted or did not exist + * @return a successful Publisher if the bucket is deleted or did not exist * otherwise an IOObjectStoreException in its error channel */ - Mono<Void> deleteBucket(BucketName bucketName); + Publisher<Void> deleteBucket(BucketName bucketName); } diff --git a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/MetricableBlobStore.java b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/MetricableBlobStore.java index a081cec..0e4e383 100644 --- a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/MetricableBlobStore.java +++ b/server/blob/blob-api/src/main/java/org/apache/james/blob/api/MetricableBlobStore.java @@ -24,8 +24,7 @@ import javax.inject.Inject; import javax.inject.Named; import org.apache.james.metrics.api.MetricFactory; - -import reactor.core.publisher.Mono; +import org.reactivestreams.Publisher; public class MetricableBlobStore implements BlobStore { @@ -50,21 +49,18 @@ public class MetricableBlobStore implements BlobStore { } @Override - public Mono<BlobId> save(BucketName bucketName, byte[] data, StoragePolicy storagePolicy) { - return metricFactory - .runPublishingTimerMetric(SAVE_BYTES_TIMER_NAME, blobStoreImpl.save(bucketName, data, storagePolicy)); + public Publisher<BlobId> save(BucketName bucketName, byte[] data, StoragePolicy storagePolicy) { + return metricFactory.runPublishingTimerMetric(SAVE_BYTES_TIMER_NAME, blobStoreImpl.save(bucketName, data, storagePolicy)); } @Override - public Mono<BlobId> save(BucketName bucketName, InputStream data, StoragePolicy storagePolicy) { - return metricFactory - .runPublishingTimerMetric(SAVE_INPUT_STREAM_TIMER_NAME, blobStoreImpl.save(bucketName, data, storagePolicy)); + public Publisher<BlobId> save(BucketName bucketName, InputStream data, StoragePolicy storagePolicy) { + return metricFactory.runPublishingTimerMetric(SAVE_INPUT_STREAM_TIMER_NAME, blobStoreImpl.save(bucketName, data, storagePolicy)); } @Override - public Mono<byte[]> readBytes(BucketName bucketName, BlobId blobId) { - return metricFactory - .runPublishingTimerMetric(READ_BYTES_TIMER_NAME, blobStoreImpl.readBytes(bucketName, blobId)); + public Publisher<byte[]> readBytes(BucketName bucketName, BlobId blobId) { + return metricFactory.runPublishingTimerMetric(READ_BYTES_TIMER_NAME, blobStoreImpl.readBytes(bucketName, blobId)); } @Override @@ -74,9 +70,8 @@ public class MetricableBlobStore implements BlobStore { } @Override - public Mono<Void> deleteBucket(BucketName bucketName) { - return metricFactory - .runPublishingTimerMetric(DELETE_BUCKET_TIMER_NAME, blobStoreImpl.deleteBucket(bucketName)); + public Publisher<Void> deleteBucket(BucketName bucketName) { + return metricFactory.runPublishingTimerMetric(DELETE_BUCKET_TIMER_NAME, blobStoreImpl.deleteBucket(bucketName)); } @Override @@ -85,8 +80,8 @@ public class MetricableBlobStore implements BlobStore { } @Override - public Mono<Void> delete(BucketName bucketName, BlobId blobId) { - return metricFactory - .runPublishingTimerMetric(DELETE_TIMER_NAME, blobStoreImpl.delete(bucketName, blobId)); + public Publisher<Void> delete(BucketName bucketName, BlobId blobId) { + return metricFactory.runPublishingTimerMetric(DELETE_TIMER_NAME, blobStoreImpl.delete(bucketName, blobId)); } + } diff --git a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BlobStoreContract.java b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BlobStoreContract.java index 0fd6961..c01e480 100644 --- a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BlobStoreContract.java +++ b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BlobStoreContract.java @@ -37,6 +37,8 @@ import org.junit.jupiter.params.provider.MethodSource; import com.google.common.base.Strings; +import reactor.core.publisher.Mono; + public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobStoreContract { static Stream<Arguments> storagePolicies() { @@ -62,7 +64,7 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - assertThatThrownBy(() -> store.save(defaultBucketName, (byte[]) null, storagePolicy).block()) + assertThatThrownBy(() -> Mono.from(store.save(defaultBucketName, (byte[]) null, storagePolicy)).block()) .isInstanceOf(NullPointerException.class); } @@ -72,7 +74,7 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - assertThatThrownBy(() -> store.save(defaultBucketName, (String) null, storagePolicy).block()) + assertThatThrownBy(() -> Mono.from(store.save(defaultBucketName, (String) null, storagePolicy)).block()) .isInstanceOf(NullPointerException.class); } @@ -82,7 +84,7 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - assertThatThrownBy(() -> store.save(defaultBucketName, (InputStream) null, storagePolicy).block()) + assertThatThrownBy(() -> Mono.from(store.save(defaultBucketName, (InputStream) null, storagePolicy)).block()) .isInstanceOf(NullPointerException.class); } @@ -92,9 +94,9 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, EMPTY_BYTEARRAY, storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, EMPTY_BYTEARRAY, storagePolicy)).block(); - byte[] bytes = store.readBytes(defaultBucketName, blobId).block(); + byte[] bytes = Mono.from(store.readBytes(defaultBucketName, blobId)).block(); assertThat(new String(bytes, StandardCharsets.UTF_8)).isEmpty(); } @@ -105,9 +107,9 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, new String(), storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, new String(), storagePolicy)).block(); - byte[] bytes = store.readBytes(defaultBucketName, blobId).block(); + byte[] bytes = Mono.from(store.readBytes(defaultBucketName, blobId)).block(); assertThat(new String(bytes, StandardCharsets.UTF_8)).isEmpty(); } @@ -118,9 +120,9 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, new ByteArrayInputStream(EMPTY_BYTEARRAY), storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, new ByteArrayInputStream(EMPTY_BYTEARRAY), storagePolicy)).block(); - byte[] bytes = store.readBytes(defaultBucketName, blobId).block(); + byte[] bytes = Mono.from(store.readBytes(defaultBucketName, blobId)).block(); assertThat(new String(bytes, StandardCharsets.UTF_8)).isEmpty(); } @@ -131,7 +133,7 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, SHORT_BYTEARRAY, storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, SHORT_BYTEARRAY, storagePolicy)).block(); assertThat(blobId).isEqualTo(blobIdFactory().from("31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66")); } @@ -142,7 +144,7 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, SHORT_STRING, storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, SHORT_STRING, storagePolicy)).block(); assertThat(blobId).isEqualTo(blobIdFactory().from("31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66")); } @@ -153,7 +155,7 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, new ByteArrayInputStream(SHORT_BYTEARRAY), storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, new ByteArrayInputStream(SHORT_BYTEARRAY), storagePolicy)).block(); assertThat(blobId).isEqualTo(blobIdFactory().from("31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66")); } @@ -163,7 +165,7 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - assertThatThrownBy(() -> store.readBytes(defaultBucketName, blobIdFactory().from("unknown")).block()) + assertThatThrownBy(() -> Mono.from(store.readBytes(defaultBucketName, blobIdFactory().from("unknown"))).block()) .isExactlyInstanceOf(ObjectNotFoundException.class); } @@ -173,9 +175,9 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, SHORT_BYTEARRAY, storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, SHORT_BYTEARRAY, storagePolicy)).block(); - byte[] bytes = store.readBytes(defaultBucketName, blobId).block(); + byte[] bytes = Mono.from(store.readBytes(defaultBucketName, blobId)).block(); assertThat(bytes).isEqualTo(SHORT_BYTEARRAY); } @@ -186,9 +188,9 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, ELEVEN_KILOBYTES, storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, ELEVEN_KILOBYTES, storagePolicy)).block(); - byte[] bytes = store.readBytes(defaultBucketName, blobId).block(); + byte[] bytes = Mono.from(store.readBytes(defaultBucketName, blobId)).block(); assertThat(bytes).isEqualTo(ELEVEN_KILOBYTES); } @@ -199,9 +201,9 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, TWELVE_MEGABYTES, storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, TWELVE_MEGABYTES, storagePolicy)).block(); - byte[] bytes = store.readBytes(defaultBucketName, blobId).block(); + byte[] bytes = Mono.from(store.readBytes(defaultBucketName, blobId)).block(); assertThat(bytes).isEqualTo(TWELVE_MEGABYTES); } @@ -221,7 +223,7 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, SHORT_BYTEARRAY, storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, SHORT_BYTEARRAY, storagePolicy)).block(); InputStream read = store.read(defaultBucketName, blobId); @@ -234,7 +236,7 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, ELEVEN_KILOBYTES, storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, ELEVEN_KILOBYTES, storagePolicy)).block(); InputStream read = store.read(defaultBucketName, blobId); @@ -248,7 +250,7 @@ public interface BlobStoreContract extends DeleteBlobStoreContract, BucketBlobSt BucketName defaultBucketName = store.getDefaultBucketName(); // 12 MB of text - BlobId blobId = store.save(defaultBucketName, TWELVE_MEGABYTES, storagePolicy).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, TWELVE_MEGABYTES, storagePolicy)).block(); InputStream read = store.read(defaultBucketName, blobId); diff --git a/server/container/util/src/main/java/org/apache/james/util/UnicodeSetUtils.java b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BlobTypeTest.java similarity index 75% rename from server/container/util/src/main/java/org/apache/james/util/UnicodeSetUtils.java rename to server/blob/blob-api/src/test/java/org/apache/james/blob/api/BlobTypeTest.java index 26b05a0..2af6748 100644 --- a/server/container/util/src/main/java/org/apache/james/util/UnicodeSetUtils.java +++ b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BlobTypeTest.java @@ -7,7 +7,7 @@ * "License"); you may not use this file except in compliance * * with the License. You may obtain a copy of the License at * * * - * http://www.apache.org/licenses/LICENSE-2.0 * + * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, * * software distributed under the License is distributed on an * @@ -15,16 +15,18 @@ * KIND, either express or implied. See the License for the * * specific language governing permissions and limitations * * under the License. * - ****************************************************************/ -package org.apache.james.util; + ***************************************************************/ -import com.ibm.icu.text.UnicodeSet; +package org.apache.james.blob.api; -public class UnicodeSetUtils { +import org.junit.jupiter.api.Test; - private static final String LETTER_OR_DIGIT_PATTERN = "[[a-z][A-Z][0-9]]"; +import nl.jqno.equalsverifier.EqualsVerifier; - public static UnicodeSet letterOrDigitUnicodeSet() { - return new UnicodeSet(LETTER_OR_DIGIT_PATTERN); +class BlobTypeTest { + + @Test + void shouldRespectBeanContract() { + EqualsVerifier.forClass(BlobType.class).verify(); } -} +} \ No newline at end of file diff --git a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BucketBlobStoreContract.java b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BucketBlobStoreContract.java index 0d993bd..75b0706 100644 --- a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BucketBlobStoreContract.java +++ b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BucketBlobStoreContract.java @@ -31,6 +31,8 @@ import java.time.Duration; import org.apache.james.util.concurrency.ConcurrentTestRunner; import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + public interface BucketBlobStoreContract { String SHORT_STRING = "toto"; byte[] SHORT_BYTEARRAY = SHORT_STRING.getBytes(StandardCharsets.UTF_8); @@ -44,7 +46,7 @@ public interface BucketBlobStoreContract { default void deleteBucketShouldThrowWhenNullBucketName() { BlobStore store = testee(); - assertThatThrownBy(() -> store.deleteBucket(null).block()) + assertThatThrownBy(() -> Mono.from(store.deleteBucket(null)).block()) .isInstanceOf(NullPointerException.class); } @@ -52,8 +54,8 @@ public interface BucketBlobStoreContract { default void deleteBucketShouldDeleteExistingBucketWithItsData() { BlobStore store = testee(); - BlobId blobId = store.save(CUSTOM, SHORT_BYTEARRAY, LOW_COST).block(); - store.deleteBucket(CUSTOM).block(); + BlobId blobId = Mono.from(store.save(CUSTOM, SHORT_BYTEARRAY, LOW_COST)).block(); + Mono.from(store.deleteBucket(CUSTOM)).block(); assertThatThrownBy(() -> store.read(CUSTOM, blobId).read()) .isInstanceOf(ObjectStoreException.class); @@ -63,10 +65,10 @@ public interface BucketBlobStoreContract { default void deleteBucketShouldBeIdempotent() { BlobStore store = testee(); - store.save(CUSTOM, SHORT_BYTEARRAY, LOW_COST).block(); - store.deleteBucket(CUSTOM).block(); + Mono.from(store.save(CUSTOM, SHORT_BYTEARRAY, LOW_COST)).block(); + Mono.from(store.deleteBucket(CUSTOM)).block(); - assertThatCode(() -> store.deleteBucket(CUSTOM).block()) + assertThatCode(() -> Mono.from(store.deleteBucket(CUSTOM)).block()) .doesNotThrowAnyException(); } @@ -74,7 +76,7 @@ public interface BucketBlobStoreContract { default void saveBytesShouldThrowWhenNullBucketName() { BlobStore store = testee(); - assertThatThrownBy(() -> store.save(null, SHORT_BYTEARRAY, LOW_COST).block()) + assertThatThrownBy(() -> Mono.from(store.save(null, SHORT_BYTEARRAY, LOW_COST)).block()) .isInstanceOf(NullPointerException.class); } @@ -82,7 +84,7 @@ public interface BucketBlobStoreContract { default void saveStringShouldThrowWhenNullBucketName() { BlobStore store = testee(); - assertThatThrownBy(() -> store.save(null, SHORT_STRING, LOW_COST).block()) + assertThatThrownBy(() -> Mono.from(store.save(null, SHORT_STRING, LOW_COST)).block()) .isInstanceOf(NullPointerException.class); } @@ -90,7 +92,7 @@ public interface BucketBlobStoreContract { default void saveInputStreamShouldThrowWhenNullBucketName() { BlobStore store = testee(); - assertThatThrownBy(() -> store.save(null, new ByteArrayInputStream(SHORT_BYTEARRAY), LOW_COST).block()) + assertThatThrownBy(() -> Mono.from(store.save(null, new ByteArrayInputStream(SHORT_BYTEARRAY), LOW_COST)).block()) .isInstanceOf(NullPointerException.class); } @@ -98,7 +100,7 @@ public interface BucketBlobStoreContract { default void readShouldThrowWhenNullBucketName() { BlobStore store = testee(); - BlobId blobId = store.save(BucketName.DEFAULT, SHORT_BYTEARRAY, LOW_COST).block(); + BlobId blobId = Mono.from(store.save(BucketName.DEFAULT, SHORT_BYTEARRAY, LOW_COST)).block(); assertThatThrownBy(() -> store.read(null, blobId)) .isInstanceOf(NullPointerException.class); } @@ -107,8 +109,8 @@ public interface BucketBlobStoreContract { default void readBytesStreamShouldThrowWhenNullBucketName() { BlobStore store = testee(); - BlobId blobId = store.save(BucketName.DEFAULT, SHORT_BYTEARRAY, LOW_COST).block(); - assertThatThrownBy(() -> store.readBytes(null, blobId).block()) + BlobId blobId = Mono.from(store.save(BucketName.DEFAULT, SHORT_BYTEARRAY, LOW_COST)).block(); + assertThatThrownBy(() -> Mono.from(store.readBytes(null, blobId)).block()) .isInstanceOf(NullPointerException.class); } @@ -116,7 +118,7 @@ public interface BucketBlobStoreContract { default void readStringShouldThrowWhenBucketDoesNotExist() { BlobStore store = testee(); - BlobId blobId = store.save(BucketName.DEFAULT, SHORT_BYTEARRAY, LOW_COST).block(); + BlobId blobId = Mono.from(store.save(BucketName.DEFAULT, SHORT_BYTEARRAY, LOW_COST)).block(); assertThatThrownBy(() -> store.read(CUSTOM, blobId).read()) .isInstanceOf(ObjectStoreException.class); } @@ -125,8 +127,8 @@ public interface BucketBlobStoreContract { default void readBytesStreamShouldThrowWhenBucketDoesNotExist() { BlobStore store = testee(); - BlobId blobId = store.save(BucketName.DEFAULT, SHORT_BYTEARRAY, LOW_COST).block(); - assertThatThrownBy(() -> store.readBytes(CUSTOM, blobId).block()) + BlobId blobId = Mono.from(store.save(BucketName.DEFAULT, SHORT_BYTEARRAY, LOW_COST)).block(); + assertThatThrownBy(() -> Mono.from(store.readBytes(CUSTOM, blobId)).block()) .isInstanceOf(ObjectStoreException.class); } @@ -134,11 +136,11 @@ public interface BucketBlobStoreContract { default void shouldBeAbleToSaveDataInMultipleBuckets() { BlobStore store = testee(); - BlobId blobIdDefault = store.save(BucketName.DEFAULT, SHORT_BYTEARRAY, LOW_COST).block(); - BlobId blobIdCustom = store.save(CUSTOM, SHORT_BYTEARRAY, LOW_COST).block(); + BlobId blobIdDefault = Mono.from(store.save(BucketName.DEFAULT, SHORT_BYTEARRAY, LOW_COST)).block(); + BlobId blobIdCustom = Mono.from(store.save(CUSTOM, SHORT_BYTEARRAY, LOW_COST)).block(); - byte[] bytesDefault = store.readBytes(BucketName.DEFAULT, blobIdDefault).block(); - byte[] bytesCustom = store.readBytes(CUSTOM, blobIdCustom).block(); + byte[] bytesDefault = Mono.from(store.readBytes(BucketName.DEFAULT, blobIdDefault)).block(); + byte[] bytesCustom = Mono.from(store.readBytes(CUSTOM, blobIdCustom)).block(); assertThat(bytesDefault).isEqualTo(bytesCustom); } @@ -148,7 +150,7 @@ public interface BucketBlobStoreContract { BlobStore store = testee(); ConcurrentTestRunner.builder() - .operation(((threadNumber, step) -> store.save(CUSTOM, SHORT_STRING + threadNumber + step, LOW_COST).block())) + .operation(((threadNumber, step) -> Mono.from(store.save(CUSTOM, SHORT_STRING + threadNumber + step, LOW_COST)).block())) .threadCount(10) .operationCount(10) .runSuccessfullyWithin(Duration.ofMinutes(1)); @@ -158,10 +160,10 @@ public interface BucketBlobStoreContract { default void deleteBucketConcurrentlyShouldNotFail() throws Exception { BlobStore store = testee(); - store.save(CUSTOM, SHORT_BYTEARRAY, LOW_COST).block(); + Mono.from(store.save(CUSTOM, SHORT_BYTEARRAY, LOW_COST)).block(); ConcurrentTestRunner.builder() - .operation(((threadNumber, step) -> store.deleteBucket(CUSTOM).block())) + .operation(((threadNumber, step) -> Mono.from(store.deleteBucket(CUSTOM)).block())) .threadCount(10) .operationCount(10) .runSuccessfullyWithin(Duration.ofMinutes(1)); diff --git a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BucketDumbBlobStoreContract.java b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BucketDumbBlobStoreContract.java index 49e2a7e..d560587 100644 --- a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BucketDumbBlobStoreContract.java +++ b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/BucketDumbBlobStoreContract.java @@ -35,6 +35,8 @@ import java.time.Duration; import org.apache.james.util.concurrency.ConcurrentTestRunner; import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + public interface BucketDumbBlobStoreContract { DumbBlobStore testee(); @@ -43,7 +45,7 @@ public interface BucketDumbBlobStoreContract { default void deleteBucketShouldThrowWhenNullBucketName() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.deleteBucket(null).block()) + assertThatThrownBy(() -> Mono.from(store.deleteBucket(null)).block()) .isInstanceOf(NullPointerException.class); } @@ -51,8 +53,8 @@ public interface BucketDumbBlobStoreContract { default void deleteBucketShouldDeleteExistingBucketWithItsData() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); - store.deleteBucket(TEST_BUCKET_NAME).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); + Mono.from(store.deleteBucket(TEST_BUCKET_NAME)).block(); assertThatThrownBy(() -> store.read(TEST_BUCKET_NAME, TEST_BLOB_ID).read()) .isInstanceOf(ObjectNotFoundException.class); @@ -62,10 +64,10 @@ public interface BucketDumbBlobStoreContract { default void deleteBucketShouldBeIdempotent() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); - store.deleteBucket(TEST_BUCKET_NAME).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); + Mono.from(store.deleteBucket(TEST_BUCKET_NAME)).block(); - assertThatCode(() -> store.deleteBucket(TEST_BUCKET_NAME).block()) + assertThatCode(() -> Mono.from(store.deleteBucket(TEST_BUCKET_NAME)).block()) .doesNotThrowAnyException(); } @@ -73,7 +75,7 @@ public interface BucketDumbBlobStoreContract { default void saveBytesShouldThrowWhenNullBucketName() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.save(null, TEST_BLOB_ID, SHORT_BYTEARRAY).block()) + assertThatThrownBy(() -> Mono.from(store.save(null, TEST_BLOB_ID, SHORT_BYTEARRAY)).block()) .isInstanceOf(NullPointerException.class); } @@ -81,7 +83,7 @@ public interface BucketDumbBlobStoreContract { default void saveStringShouldThrowWhenNullBucketName() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.save(null, TEST_BLOB_ID, SHORT_STRING).block()) + assertThatThrownBy(() -> Mono.from(store.save(null, TEST_BLOB_ID, SHORT_STRING)).block()) .isInstanceOf(NullPointerException.class); } @@ -89,7 +91,7 @@ public interface BucketDumbBlobStoreContract { default void saveInputStreamShouldThrowWhenNullBucketName() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.save(null, TEST_BLOB_ID, new ByteArrayInputStream(SHORT_BYTEARRAY)).block()) + assertThatThrownBy(() -> Mono.from(store.save(null, TEST_BLOB_ID, new ByteArrayInputStream(SHORT_BYTEARRAY))).block()) .isInstanceOf(NullPointerException.class); } @@ -97,7 +99,7 @@ public interface BucketDumbBlobStoreContract { default void readShouldThrowWhenNullBucketName() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); assertThatThrownBy(() -> store.read(null, TEST_BLOB_ID)) .isInstanceOf(NullPointerException.class); } @@ -106,8 +108,8 @@ public interface BucketDumbBlobStoreContract { default void readBytesShouldThrowWhenNullBucketName() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); - assertThatThrownBy(() -> store.readBytes(null, TEST_BLOB_ID).block()) + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); + assertThatThrownBy(() -> Mono.from(store.readBytes(null, TEST_BLOB_ID)).block()) .isInstanceOf(NullPointerException.class); } @@ -115,7 +117,7 @@ public interface BucketDumbBlobStoreContract { default void readStreamShouldThrowWhenBucketDoesNotExist() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); assertThatThrownBy(() -> store.read(CUSTOM_BUCKET_NAME, TEST_BLOB_ID).read()) .isInstanceOf(ObjectNotFoundException.class); } @@ -124,9 +126,9 @@ public interface BucketDumbBlobStoreContract { default void readBytesShouldThrowWhenBucketDoesNotExist() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); - assertThatThrownBy(() -> store.readBytes(CUSTOM_BUCKET_NAME, TEST_BLOB_ID).block()) + assertThatThrownBy(() -> Mono.from(store.readBytes(CUSTOM_BUCKET_NAME, TEST_BLOB_ID)).block()) .isInstanceOf(ObjectNotFoundException.class); } @@ -134,11 +136,11 @@ public interface BucketDumbBlobStoreContract { default void shouldBeAbleToSaveDataInMultipleBuckets() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); - store.save(CUSTOM_BUCKET_NAME, OTHER_TEST_BLOB_ID, SHORT_BYTEARRAY).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); + Mono.from(store.save(CUSTOM_BUCKET_NAME, OTHER_TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); - byte[] bytesDefault = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); - byte[] bytesCustom = store.readBytes(CUSTOM_BUCKET_NAME, OTHER_TEST_BLOB_ID).block(); + byte[] bytesDefault = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); + byte[] bytesCustom = Mono.from(store.readBytes(CUSTOM_BUCKET_NAME, OTHER_TEST_BLOB_ID)).block(); assertThat(bytesDefault).isEqualTo(bytesCustom); } @@ -149,10 +151,10 @@ public interface BucketDumbBlobStoreContract { ConcurrentTestRunner.builder() .operation(((threadNumber, step) -> - store.save( + Mono.from(store.save( TEST_BUCKET_NAME, new TestBlobId("id-" + threadNumber + step), - SHORT_STRING + threadNumber + step).block())) + SHORT_STRING + threadNumber + step)).block())) .threadCount(10) .operationCount(10) .runSuccessfullyWithin(Duration.ofMinutes(1)); @@ -162,7 +164,7 @@ public interface BucketDumbBlobStoreContract { default void deleteBucketConcurrentlyShouldNotFail() throws Exception { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); ConcurrentTestRunner.builder() .reactorOperation(((threadNumber, step) -> store.deleteBucket(TEST_BUCKET_NAME))) diff --git a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/DeleteBlobStoreContract.java b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/DeleteBlobStoreContract.java index b0cbeb9..a65362a 100644 --- a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/DeleteBlobStoreContract.java +++ b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/DeleteBlobStoreContract.java @@ -35,6 +35,8 @@ import org.junit.jupiter.api.Test; import com.google.common.base.Strings; +import reactor.core.publisher.Mono; + public interface DeleteBlobStoreContract { String SHORT_STRING = "toto"; @@ -53,7 +55,7 @@ public interface DeleteBlobStoreContract { BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - assertThatCode(() -> store.delete(defaultBucketName, blobIdFactory().randomId()).block()) + assertThatCode(() -> Mono.from(store.delete(defaultBucketName, blobIdFactory().randomId())).block()) .doesNotThrowAnyException(); } @@ -62,8 +64,8 @@ public interface DeleteBlobStoreContract { BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, SHORT_BYTEARRAY, LOW_COST).block(); - store.delete(defaultBucketName, blobId).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, SHORT_BYTEARRAY, LOW_COST)).block(); + Mono.from(store.delete(defaultBucketName, blobId)).block(); assertThatThrownBy(() -> store.read(defaultBucketName, blobId).read()) .isInstanceOf(ObjectStoreException.class); @@ -74,10 +76,10 @@ public interface DeleteBlobStoreContract { BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, SHORT_BYTEARRAY, LOW_COST).block(); - store.delete(defaultBucketName, blobId).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, SHORT_BYTEARRAY, LOW_COST)).block(); + Mono.from(store.delete(defaultBucketName, blobId)).block(); - assertThatCode(() -> store.delete(defaultBucketName, blobId).block()) + assertThatCode(() -> Mono.from(store.delete(defaultBucketName, blobId)).block()) .doesNotThrowAnyException(); } @@ -86,10 +88,10 @@ public interface DeleteBlobStoreContract { BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobIdToDelete = store.save(defaultBucketName, SHORT_BYTEARRAY, LOW_COST).block(); - BlobId otherBlobId = store.save(defaultBucketName, ELEVEN_KILOBYTES, LOW_COST).block(); + BlobId blobIdToDelete = Mono.from(store.save(defaultBucketName, SHORT_BYTEARRAY, LOW_COST)).block(); + BlobId otherBlobId = Mono.from(store.save(defaultBucketName, ELEVEN_KILOBYTES, LOW_COST)).block(); - store.delete(defaultBucketName, blobIdToDelete).block(); + Mono.from(store.delete(defaultBucketName, blobIdToDelete)).block(); InputStream read = store.read(defaultBucketName, otherBlobId); @@ -101,10 +103,10 @@ public interface DeleteBlobStoreContract { BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, TWELVE_MEGABYTES, LOW_COST).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, TWELVE_MEGABYTES, LOW_COST)).block(); ConcurrentTestRunner.builder() - .operation(((threadNumber, step) -> store.delete(defaultBucketName, blobId).block())) + .operation(((threadNumber, step) -> Mono.from(store.delete(defaultBucketName, blobId)).block())) .threadCount(10) .operationCount(10) .runSuccessfullyWithin(Duration.ofMinutes(1)); @@ -113,7 +115,7 @@ public interface DeleteBlobStoreContract { @Test default void deleteShouldThrowWhenNullBucketName() { BlobStore store = testee(); - assertThatThrownBy(() -> store.delete(null, blobIdFactory().randomId()).block()) + assertThatThrownBy(() -> Mono.from(store.delete(null, blobIdFactory().randomId())).block()) .isInstanceOf(NullPointerException.class); } @@ -122,10 +124,10 @@ public interface DeleteBlobStoreContract { BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId customBlobId = store.save(CUSTOM, "custom_string", LOW_COST).block(); - BlobId defaultBlobId = store.save(defaultBucketName, SHORT_BYTEARRAY, LOW_COST).block(); + BlobId customBlobId = Mono.from(store.save(CUSTOM, "custom_string", LOW_COST)).block(); + BlobId defaultBlobId = Mono.from(store.save(defaultBucketName, SHORT_BYTEARRAY, LOW_COST)).block(); - store.delete(CUSTOM, customBlobId).block(); + Mono.from(store.delete(CUSTOM, customBlobId)).block(); InputStream read = store.read(defaultBucketName, defaultBlobId); @@ -137,10 +139,10 @@ public interface DeleteBlobStoreContract { BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - store.save(CUSTOM, SHORT_BYTEARRAY, LOW_COST).block(); - BlobId blobId = store.save(defaultBucketName, SHORT_BYTEARRAY, LOW_COST).block(); + Mono.from(store.save(CUSTOM, SHORT_BYTEARRAY, LOW_COST)).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, SHORT_BYTEARRAY, LOW_COST)).block(); - store.delete(defaultBucketName, blobId).block(); + Mono.from(store.delete(defaultBucketName, blobId)).block(); InputStream read = store.read(CUSTOM, blobId); @@ -152,7 +154,7 @@ public interface DeleteBlobStoreContract { BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, TWELVE_MEGABYTES, LOW_COST).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, TWELVE_MEGABYTES, LOW_COST)).block(); ConcurrentTestRunner.builder() .operation(((threadNumber, step) -> { @@ -167,7 +169,7 @@ public interface DeleteBlobStoreContract { // normal behavior here } - store.delete(defaultBucketName, blobId).block(); + Mono.from(store.delete(defaultBucketName, blobId)).block(); })) .threadCount(10) .operationCount(10) @@ -179,12 +181,12 @@ public interface DeleteBlobStoreContract { BlobStore store = testee(); BucketName defaultBucketName = store.getDefaultBucketName(); - BlobId blobId = store.save(defaultBucketName, TWELVE_MEGABYTES, LOW_COST).block(); + BlobId blobId = Mono.from(store.save(defaultBucketName, TWELVE_MEGABYTES, LOW_COST)).block(); ConcurrentTestRunner.builder() .operation(((threadNumber, step) -> { try { - byte[] read = store.readBytes(defaultBucketName, blobId).block(); + byte[] read = Mono.from(store.readBytes(defaultBucketName, blobId)).block(); String string = IOUtils.toString(read, StandardCharsets.UTF_8.displayName()); if (!string.equals(TWELVE_MEGABYTES_STRING)) { throw new RuntimeException("Should not read partial blob when an other thread is deleting it. Size : " + string.length()); @@ -193,7 +195,7 @@ public interface DeleteBlobStoreContract { // normal behavior here } - store.delete(defaultBucketName, blobId).block(); + Mono.from(store.delete(defaultBucketName, blobId)).block(); })) .threadCount(10) .operationCount(10) diff --git a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/DeleteDumbBlobStoreContract.java b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/DeleteDumbBlobStoreContract.java index e537774..b501e51 100644 --- a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/DeleteDumbBlobStoreContract.java +++ b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/DeleteDumbBlobStoreContract.java @@ -52,7 +52,7 @@ public interface DeleteDumbBlobStoreContract { default void deleteShouldNotThrowWhenBlobDoesNotExist() { DumbBlobStore store = testee(); - assertThatCode(() -> store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID).block()) + assertThatCode(() -> Mono.from(store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID)).block()) .doesNotThrowAnyException(); } @@ -60,7 +60,7 @@ public interface DeleteDumbBlobStoreContract { default void deleteShouldNotThrowWhenBucketDoesNotExist() { DumbBlobStore store = testee(); - assertThatCode(() -> store.delete(BucketName.of("not_existing_bucket_name"), TEST_BLOB_ID).block()) + assertThatCode(() -> Mono.from(store.delete(BucketName.of("not_existing_bucket_name"), TEST_BLOB_ID)).block()) .doesNotThrowAnyException(); } @@ -68,8 +68,8 @@ public interface DeleteDumbBlobStoreContract { default void deleteShouldDeleteExistingBlobData() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); - store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); + Mono.from(store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThatThrownBy(() -> store.read(TEST_BUCKET_NAME, TEST_BLOB_ID).read()) .isInstanceOf(ObjectStoreException.class); @@ -79,10 +79,10 @@ public interface DeleteDumbBlobStoreContract { default void deleteShouldBeIdempotent() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); - store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); + Mono.from(store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); - assertThatCode(() -> store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID).block()) + assertThatCode(() -> Mono.from(store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID)).block()) .doesNotThrowAnyException(); } @@ -90,10 +90,10 @@ public interface DeleteDumbBlobStoreContract { default void deleteShouldNotDeleteOtherBlobs() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); - store.save(TEST_BUCKET_NAME, OTHER_TEST_BLOB_ID, ELEVEN_KILOBYTES).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); + Mono.from(store.save(TEST_BUCKET_NAME, OTHER_TEST_BLOB_ID, ELEVEN_KILOBYTES)).block(); - store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + Mono.from(store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); InputStream read = store.read(TEST_BUCKET_NAME, OTHER_TEST_BLOB_ID); @@ -104,10 +104,10 @@ public interface DeleteDumbBlobStoreContract { default void deleteConcurrentlyShouldNotFail() throws Exception { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES)).block(); ConcurrentTestRunner.builder() - .operation(((threadNumber, step) -> store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID).block())) + .operation(((threadNumber, step) -> Mono.from(store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID)).block())) .threadCount(10) .operationCount(10) .runSuccessfullyWithin(Duration.ofMinutes(1)); @@ -116,7 +116,7 @@ public interface DeleteDumbBlobStoreContract { @Test default void deleteShouldThrowWhenNullBucketName() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.delete(null, TEST_BLOB_ID).block()) + assertThatThrownBy(() -> Mono.from(store.delete(null, TEST_BLOB_ID)).block()) .isInstanceOf(NullPointerException.class); } @@ -124,10 +124,10 @@ public interface DeleteDumbBlobStoreContract { default void deleteShouldNotDeleteFromOtherBucket() { DumbBlobStore store = testee(); - store.save(CUSTOM_BUCKET_NAME, OTHER_TEST_BLOB_ID, "custom").block(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); + Mono.from(store.save(CUSTOM_BUCKET_NAME, OTHER_TEST_BLOB_ID, "custom")).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); - store.delete(CUSTOM_BUCKET_NAME, OTHER_TEST_BLOB_ID).block(); + Mono.from(store.delete(CUSTOM_BUCKET_NAME, OTHER_TEST_BLOB_ID)).block(); InputStream read = store.read(TEST_BUCKET_NAME, TEST_BLOB_ID); @@ -138,10 +138,10 @@ public interface DeleteDumbBlobStoreContract { default void deleteShouldNotDeleteFromOtherBucketWhenSameBlobId() { DumbBlobStore store = testee(); - store.save(CUSTOM_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); + Mono.from(store.save(CUSTOM_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); - store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + Mono.from(store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); InputStream read = store.read(CUSTOM_BUCKET_NAME, TEST_BLOB_ID); @@ -152,7 +152,7 @@ public interface DeleteDumbBlobStoreContract { default void readShouldNotReadPartiallyWhenDeletingConcurrentlyBigBlob() throws Exception { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES)).block(); ConcurrentTestRunner.builder() .operation(((threadNumber, step) -> { @@ -167,7 +167,7 @@ public interface DeleteDumbBlobStoreContract { // normal behavior here } - store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + Mono.from(store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); })) .threadCount(10) .operationCount(10) @@ -178,12 +178,12 @@ public interface DeleteDumbBlobStoreContract { default void readBytesShouldNotReadPartiallyWhenDeletingConcurrentlyBigBlob() throws Exception { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES)).block(); ConcurrentTestRunner.builder() .operation(((threadNumber, step) -> { try { - byte[] read = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] read = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); String string = IOUtils.toString(read, StandardCharsets.UTF_8.displayName()); if (!string.equals(TWELVE_MEGABYTES_STRING)) { throw new RuntimeException("Should not read partial blob when an other thread is deleting it. Size : " + string.length()); @@ -192,7 +192,7 @@ public interface DeleteDumbBlobStoreContract { // normal behavior here } - store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + Mono.from(store.delete(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); })) .threadCount(10) .operationCount(10) @@ -202,7 +202,7 @@ public interface DeleteDumbBlobStoreContract { @Test default void mixingSaveReadAndDeleteShouldReturnConsistentState() throws ExecutionException, InterruptedException { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES)).block(); ConcurrentTestRunner.builder() .randomlyDistributedReactorOperations( (thread, iteration) -> store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES), @@ -216,7 +216,7 @@ public interface DeleteDumbBlobStoreContract { default Mono<Void> checkConcurrentMixedOperation() { return - testee().readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID) + Mono.from(testee().readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)) //assertj is very cpu-intensive, let's compute the assertion only when arrays are different .filter(bytes -> !Arrays.equals(bytes, TWELVE_MEGABYTES)) .doOnNext(bytes -> assertThat(bytes).isEqualTo(TWELVE_MEGABYTES)) diff --git a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/MetricableBlobStoreContract.java b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/MetricableBlobStoreContract.java index a6aed4a..c11b117 100644 --- a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/MetricableBlobStoreContract.java +++ b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/MetricableBlobStoreContract.java @@ -37,6 +37,8 @@ import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.RegisterExtension; +import reactor.core.publisher.Mono; + public interface MetricableBlobStoreContract extends BlobStoreContract { @@ -62,8 +64,8 @@ public interface MetricableBlobStoreContract extends BlobStoreContract { default void saveBytesShouldPublishSaveBytesTimerMetrics() { BlobStore store = testee(); - store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST).block(); - store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST).block(); + Mono.from(store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST)).block(); + Mono.from(store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST)).block(); assertThat(metricsTestExtension.getMetricFactory().executionTimesFor(SAVE_BYTES_TIMER_NAME)) .hasSize(2); @@ -73,8 +75,8 @@ public interface MetricableBlobStoreContract extends BlobStoreContract { default void saveStringShouldPublishSaveBytesTimerMetrics() { BlobStore store = testee(); - store.save(store.getDefaultBucketName(), STRING_CONTENT, LOW_COST).block(); - store.save(store.getDefaultBucketName(), STRING_CONTENT, LOW_COST).block(); + Mono.from(store.save(store.getDefaultBucketName(), STRING_CONTENT, LOW_COST)).block(); + Mono.from(store.save(store.getDefaultBucketName(), STRING_CONTENT, LOW_COST)).block(); assertThat(metricsTestExtension.getMetricFactory().executionTimesFor(SAVE_BYTES_TIMER_NAME)) .hasSize(2); @@ -84,8 +86,8 @@ public interface MetricableBlobStoreContract extends BlobStoreContract { default void saveInputStreamShouldPublishSaveInputStreamTimerMetrics() { BlobStore store = testee(); - store.save(store.getDefaultBucketName(), new ByteArrayInputStream(BYTES_CONTENT), LOW_COST).block(); - store.save(store.getDefaultBucketName(), new ByteArrayInputStream(BYTES_CONTENT), LOW_COST).block(); + Mono.from(store.save(store.getDefaultBucketName(), new ByteArrayInputStream(BYTES_CONTENT), LOW_COST)).block(); + Mono.from(store.save(store.getDefaultBucketName(), new ByteArrayInputStream(BYTES_CONTENT), LOW_COST)).block(); assertThat(metricsTestExtension.getMetricFactory().executionTimesFor(SAVE_INPUT_STREAM_TIMER_NAME)) .hasSize(2); @@ -95,9 +97,9 @@ public interface MetricableBlobStoreContract extends BlobStoreContract { default void readBytesShouldPublishReadBytesTimerMetrics() { BlobStore store = testee(); - BlobId blobId = store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST).block(); - store.readBytes(store.getDefaultBucketName(), blobId).block(); - store.readBytes(store.getDefaultBucketName(), blobId).block(); + BlobId blobId = Mono.from(store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST)).block(); + Mono.from(store.readBytes(store.getDefaultBucketName(), blobId)).block(); + Mono.from(store.readBytes(store.getDefaultBucketName(), blobId)).block(); assertThat(metricsTestExtension.getMetricFactory().executionTimesFor(READ_BYTES_TIMER_NAME)) .hasSize(2); @@ -107,7 +109,7 @@ public interface MetricableBlobStoreContract extends BlobStoreContract { default void readShouldPublishReadTimerMetrics() { BlobStore store = testee(); - BlobId blobId = store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST).block(); + BlobId blobId = Mono.from(store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST)).block(); store.read(store.getDefaultBucketName(), blobId); store.read(store.getDefaultBucketName(), blobId); @@ -120,10 +122,10 @@ public interface MetricableBlobStoreContract extends BlobStoreContract { BlobStore store = testee(); BucketName bucketName = BucketName.of("custom"); - store.save(BucketName.DEFAULT, BYTES_CONTENT, LOW_COST).block(); - store.save(bucketName, BYTES_CONTENT, LOW_COST).block(); + Mono.from(store.save(BucketName.DEFAULT, BYTES_CONTENT, LOW_COST)).block(); + Mono.from(store.save(bucketName, BYTES_CONTENT, LOW_COST)).block(); - store.deleteBucket(bucketName).block(); + Mono.from(store.deleteBucket(bucketName)).block(); assertThat(metricsTestExtension.getMetricFactory().executionTimesFor(DELETE_BUCKET_TIMER_NAME)) .hasSize(1); @@ -133,11 +135,11 @@ public interface MetricableBlobStoreContract extends BlobStoreContract { default void deleteShouldPublishDeleteTimerMetrics() { BlobStore store = testee(); - BlobId blobId1 = store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST).block(); - BlobId blobId2 = store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST).block(); + BlobId blobId1 = Mono.from(store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST)).block(); + BlobId blobId2 = Mono.from(store.save(store.getDefaultBucketName(), BYTES_CONTENT, LOW_COST)).block(); - store.delete(BucketName.DEFAULT, blobId1).block(); - store.delete(BucketName.DEFAULT, blobId2).block(); + Mono.from(store.delete(BucketName.DEFAULT, blobId1)).block(); + Mono.from(store.delete(BucketName.DEFAULT, blobId2)).block(); assertThat(metricsTestExtension.getMetricFactory().executionTimesFor(DELETE_TIMER_NAME)) .hasSize(2); diff --git a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/ReadSaveDumbBlobStoreContract.java b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/ReadSaveDumbBlobStoreContract.java index 833dafd..dae10f6 100644 --- a/server/blob/blob-api/src/test/java/org/apache/james/blob/api/ReadSaveDumbBlobStoreContract.java +++ b/server/blob/blob-api/src/test/java/org/apache/james/blob/api/ReadSaveDumbBlobStoreContract.java @@ -46,6 +46,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import com.google.common.io.ByteSource; + import reactor.core.publisher.Mono; public interface ReadSaveDumbBlobStoreContract { @@ -56,7 +57,7 @@ public interface ReadSaveDumbBlobStoreContract { default void saveShouldThrowWhenNullData() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, (byte[]) null).block()) + assertThatThrownBy(() -> Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, (byte[]) null)).block()) .isInstanceOf(NullPointerException.class); } @@ -64,7 +65,7 @@ public interface ReadSaveDumbBlobStoreContract { default void saveShouldThrowWhenNullString() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, (String) null).block()) + assertThatThrownBy(() -> Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, (String) null)).block()) .isInstanceOf(NullPointerException.class); } @@ -72,7 +73,7 @@ public interface ReadSaveDumbBlobStoreContract { default void saveShouldThrowWhenNullInputStream() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, (InputStream) null).block()) + assertThatThrownBy(() -> Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, (InputStream) null)).block()) .isInstanceOf(NullPointerException.class); } @@ -80,7 +81,7 @@ public interface ReadSaveDumbBlobStoreContract { default void saveShouldThrowWhenNullByteSource() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, (ByteSource) null).block()) + assertThatThrownBy(() -> Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, (ByteSource) null)).block()) .isInstanceOf(NullPointerException.class); } @@ -88,8 +89,8 @@ public interface ReadSaveDumbBlobStoreContract { default void saveShouldSaveEmptyData() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, EMPTY_BYTEARRAY).block(); - byte[] bytes = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, EMPTY_BYTEARRAY)).block(); + byte[] bytes = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(bytes).isEmpty(); } @@ -98,9 +99,9 @@ public interface ReadSaveDumbBlobStoreContract { default void saveShouldSaveEmptyString() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, "").block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, "")).block(); - byte[] bytes = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] bytes = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(new String(bytes, StandardCharsets.UTF_8)).isEmpty(); } @@ -109,9 +110,9 @@ public interface ReadSaveDumbBlobStoreContract { default void saveShouldSaveEmptyInputStream() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, new ByteArrayInputStream(EMPTY_BYTEARRAY)).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, new ByteArrayInputStream(EMPTY_BYTEARRAY))).block(); - byte[] bytes = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] bytes = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(bytes).isEmpty(); } @@ -120,9 +121,9 @@ public interface ReadSaveDumbBlobStoreContract { default void saveShouldSaveEmptyByteSource() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.empty()).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.empty())).block(); - byte[] bytes = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] bytes = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(bytes).isEmpty(); } @@ -131,7 +132,7 @@ public interface ReadSaveDumbBlobStoreContract { default void readBytesShouldThrowWhenNotExisting() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.readBytes(TEST_BUCKET_NAME, new TestBlobId("unknown")).block()) + assertThatThrownBy(() -> Mono.from(store.readBytes(TEST_BUCKET_NAME, new TestBlobId("unknown"))).block()) .isExactlyInstanceOf(ObjectNotFoundException.class); } @@ -139,9 +140,9 @@ public interface ReadSaveDumbBlobStoreContract { default void readBytesShouldReturnSavedData() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); - byte[] bytes = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] bytes = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(bytes).isEqualTo(SHORT_BYTEARRAY); } @@ -150,9 +151,9 @@ public interface ReadSaveDumbBlobStoreContract { default void readBytesShouldReturnLongSavedData() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ELEVEN_KILOBYTES).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ELEVEN_KILOBYTES)).block(); - byte[] bytes = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] bytes = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(bytes).isEqualTo(ELEVEN_KILOBYTES); } @@ -161,9 +162,9 @@ public interface ReadSaveDumbBlobStoreContract { default void readBytesShouldReturnBigSavedData() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES)).block(); - byte[] bytes = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] bytes = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(bytes).isEqualTo(TWELVE_MEGABYTES); } @@ -180,7 +181,7 @@ public interface ReadSaveDumbBlobStoreContract { default void saveShouldCreateBucket() { DumbBlobStore store = testee(); BucketName nonExisting = BucketName.of("non-existing-bucket"); - store.save(nonExisting, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); + Mono.from(store.save(nonExisting, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); //read for a non-existing bucket would throw assertThatCode(() -> store.read(nonExisting, TEST_BLOB_ID)) @@ -190,7 +191,7 @@ public interface ReadSaveDumbBlobStoreContract { @Test default void readShouldReturnSavedData() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, SHORT_BYTEARRAY)).block(); InputStream read = store.read(TEST_BUCKET_NAME, TEST_BLOB_ID); @@ -200,7 +201,7 @@ public interface ReadSaveDumbBlobStoreContract { @Test default void readShouldReturnLongSavedData() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ELEVEN_KILOBYTES).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ELEVEN_KILOBYTES)).block(); InputStream read = store.read(TEST_BUCKET_NAME, TEST_BLOB_ID); @@ -210,7 +211,7 @@ public interface ReadSaveDumbBlobStoreContract { @Test default void readShouldReturnBigSavedData() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, TWELVE_MEGABYTES)).block(); InputStream read = store.read(TEST_BUCKET_NAME, TEST_BLOB_ID); @@ -221,10 +222,10 @@ public interface ReadSaveDumbBlobStoreContract { @MethodSource("blobs") default void saveBytesShouldBeIdempotent(String description, byte[] bytes) { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes).block(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes)).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes)).block(); - byte[] read = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] read = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(read).isEqualTo(bytes); } @@ -233,10 +234,10 @@ public interface ReadSaveDumbBlobStoreContract { @MethodSource("blobs") default void saveByteSourceShouldBeIdempotent(String description, byte[] bytes) { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(bytes)).block(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(bytes)).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(bytes))).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(bytes))).block(); - byte[] read = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] read = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(read).isEqualTo(bytes); } @@ -245,10 +246,10 @@ public interface ReadSaveDumbBlobStoreContract { @MethodSource("blobs") default void saveInputStreamShouldBeIdempotent(String description, byte[] bytes) { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(bytes)).block(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, new ByteArrayInputStream(bytes)).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(bytes))).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, new ByteArrayInputStream(bytes))).block(); - byte[] read = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] read = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(read).isEqualTo(bytes); } @@ -257,12 +258,11 @@ public interface ReadSaveDumbBlobStoreContract { default void saveInputStreamShouldNotOverwritePreviousDataOnFailingInputStream() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(ELEVEN_KILOBYTES)).block(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, getThrowingInputStream()) - .onErrorResume(throwable -> Mono.empty()) - .block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(ELEVEN_KILOBYTES))).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, getThrowingInputStream())) + .onErrorResume(throwable -> Mono.empty()).block(); - byte[] read = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] read = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(read).isEqualTo(ELEVEN_KILOBYTES); } @@ -271,17 +271,16 @@ public interface ReadSaveDumbBlobStoreContract { default void saveByteSourceShouldNotOverwritePreviousDataOnFailingInputStream() { DumbBlobStore store = testee(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(ELEVEN_KILOBYTES)).block(); - store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, new ByteSource() { + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(ELEVEN_KILOBYTES))).block(); + Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, new ByteSource() { @Override public InputStream openStream() throws IOException { return getThrowingInputStream(); } - }) - .onErrorResume(throwable -> Mono.empty()) - .block(); + })) + .onErrorResume(throwable -> Mono.empty()).block(); - byte[] read = store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID).block(); + byte[] read = Mono.from(store.readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)).block(); assertThat(read).isEqualTo(ELEVEN_KILOBYTES); } @@ -290,13 +289,12 @@ public interface ReadSaveDumbBlobStoreContract { default void saveByteSourceShouldThrowOnIOException() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, new ByteSource() { + assertThatThrownBy(() -> Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, new ByteSource() { @Override public InputStream openStream() throws IOException { return getThrowingInputStream(); } - }) - .block()) + })).block()) .isInstanceOf(ObjectStoreIOException.class); } @@ -304,8 +302,7 @@ public interface ReadSaveDumbBlobStoreContract { default void saveInputStreamShouldThrowOnIOException() { DumbBlobStore store = testee(); - assertThatThrownBy(() -> store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, getThrowingInputStream()) - .block()) + assertThatThrownBy(() -> Mono.from(store.save(TEST_BUCKET_NAME, TEST_BLOB_ID, getThrowingInputStream())).block()) .isInstanceOf(ObjectStoreIOException.class); } @@ -317,7 +314,7 @@ public interface ReadSaveDumbBlobStoreContract { @ParameterizedTest(name = "[{index}] {0}") @MethodSource(value = "blobs") default void concurrentSaveBytesShouldReturnConsistentValues(String description, byte[] bytes) throws ExecutionException, InterruptedException { - testee().save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes).block(); + Mono.from(testee().save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes)).block(); ConcurrentTestRunner.builder() .randomlyDistributedReactorOperations( (threadNumber, step) -> testee().save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes), @@ -331,7 +328,7 @@ public interface ReadSaveDumbBlobStoreContract { @ParameterizedTest(name = "[{index}] {0}") @MethodSource("blobs") default void concurrentSaveInputStreamShouldReturnConsistentValues(String description, byte[] bytes) throws ExecutionException, InterruptedException { - testee().save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes).block(); + Mono.from(testee().save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes)).block(); ConcurrentTestRunner.builder() .randomlyDistributedReactorOperations( (threadNumber, step) -> testee().save(TEST_BUCKET_NAME, TEST_BLOB_ID, new ByteArrayInputStream(bytes)), @@ -345,7 +342,7 @@ public interface ReadSaveDumbBlobStoreContract { @ParameterizedTest(name = "[{index}] {0}") @MethodSource("blobs") default void concurrentSaveByteSourceShouldReturnConsistentValues(String description, byte[] bytes) throws ExecutionException, InterruptedException { - testee().save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes).block(); + Mono.from(testee().save(TEST_BUCKET_NAME, TEST_BLOB_ID, bytes)).block(); ConcurrentTestRunner.builder() .randomlyDistributedReactorOperations( (threadNumber, step) -> testee().save(TEST_BUCKET_NAME, TEST_BLOB_ID, ByteSource.wrap(bytes)), @@ -357,7 +354,7 @@ public interface ReadSaveDumbBlobStoreContract { } default Mono<Void> checkConcurrentSaveOperation(byte[] expected) { - return testee().readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID) + return Mono.from(testee().readBytes(TEST_BUCKET_NAME, TEST_BLOB_ID)) //assertj is very cpu-intensive, let's compute the assertion only when arrays are different .filter(bytes -> !Arrays.equals(bytes, expected)) .doOnNext(bytes -> assertThat(bytes).isEqualTo(expected)) diff --git a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java index 51f6da8..e073231 100644 --- a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java +++ b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java @@ -89,9 +89,9 @@ public class CassandraBlobStoreTest implements MetricableBlobStoreContract { @Test void readBytesShouldReturnSplitSavedDataByChunk() { String longString = Strings.repeat("0123456789\n", MULTIPLE_CHUNK_SIZE); - BlobId blobId = testee.save(testee.getDefaultBucketName(), longString, LOW_COST).block(); + BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); - byte[] bytes = testee.readBytes(testee.getDefaultBucketName(), blobId).block(); + byte[] bytes = Mono.from(testee.readBytes(testee.getDefaultBucketName(), blobId)).block(); assertThat(new String(bytes, StandardCharsets.UTF_8)).isEqualTo(longString); } @@ -100,11 +100,11 @@ public class CassandraBlobStoreTest implements MetricableBlobStoreContract { void readBytesShouldNotReturnInvalidResultsWhenPartialDataPresent() { int repeatCount = MULTIPLE_CHUNK_SIZE * CHUNK_SIZE; String longString = Strings.repeat("0123456789\n", repeatCount); - BlobId blobId = testee.save(testee.getDefaultBucketName(), longString, LOW_COST).block(); + BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); when(defaultBucketDAO.readPart(blobId, 1)).thenReturn(Mono.empty()); - assertThatThrownBy(() -> testee.readBytes(testee.getDefaultBucketName(), blobId).block()) + assertThatThrownBy(() -> Mono.from(testee.readBytes(testee.getDefaultBucketName(), blobId)).block()) .isInstanceOf(ObjectStoreException.class) .hasMessageContaining("Missing blob part for blobId"); } @@ -113,7 +113,7 @@ public class CassandraBlobStoreTest implements MetricableBlobStoreContract { void readShouldNotReturnInvalidResultsWhenPartialDataPresent() { int repeatCount = MULTIPLE_CHUNK_SIZE * CHUNK_SIZE; String longString = Strings.repeat("0123456789\n", repeatCount); - BlobId blobId = testee.save(testee.getDefaultBucketName(), longString, LOW_COST).block(); + BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), longString, LOW_COST)).block(); when(defaultBucketDAO.readPart(blobId, 1)).thenReturn(Mono.empty()); @@ -133,7 +133,7 @@ public class CassandraBlobStoreTest implements MetricableBlobStoreContract { void blobStoreShouldSupport100MBBlob() throws IOException { ZeroedInputStream data = new ZeroedInputStream(100_000_000); HashingInputStream writeHash = new HashingInputStream(Hashing.sha256(), data); - BlobId blobId = testee.save(testee.getDefaultBucketName(), writeHash, LOW_COST).block(); + BlobId blobId = Mono.from(testee.save(testee.getDefaultBucketName(), writeHash, LOW_COST)).block(); InputStream bytes = testee.read(testee.getDefaultBucketName(), blobId); HashingInputStream readHash = new HashingInputStream(Hashing.sha256(), bytes); diff --git a/metrics/metrics-api/pom.xml b/server/blob/blob-common/pom.xml similarity index 76% copy from metrics/metrics-api/pom.xml copy to server/blob/blob-common/pom.xml index 3212965..57cf59d 100644 --- a/metrics/metrics-api/pom.xml +++ b/server/blob/blob-common/pom.xml @@ -17,32 +17,29 @@ specific language governing permissions and limitations under the License. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>james-server-blob</artifactId> <groupId>org.apache.james</groupId> - <artifactId>metrics</artifactId> <version>3.5.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> </parent> - <artifactId>metrics-api</artifactId> + <artifactId>blob-common</artifactId> + <packaging>jar</packaging> - <name>Apache James :: Metrics :: API</name> + <name>Apache James :: Server :: Blob :: Common</name> <dependencies> <dependency> <groupId>${james.groupId}</groupId> - <artifactId>testing-base</artifactId> - <scope>test</scope> + <artifactId>blob-api</artifactId> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-core</artifactId> </dependency> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - </dependency> </dependencies> - </project> diff --git a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/Store.java b/server/blob/blob-common/src/main/java/org/apache/james/blob/api/Store.java similarity index 83% rename from server/blob/blob-api/src/main/java/org/apache/james/blob/api/Store.java rename to server/blob/blob-common/src/main/java/org/apache/james/blob/api/Store.java index f37605c..0c51da6 100644 --- a/server/blob/blob-api/src/main/java/org/apache/james/blob/api/Store.java +++ b/server/blob/blob-common/src/main/java/org/apache/james/blob/api/Store.java @@ -20,7 +20,6 @@ package org.apache.james.blob.api; import java.util.Collection; -import java.util.Objects; import java.util.stream.Stream; import org.apache.commons.lang3.tuple.Pair; @@ -36,33 +35,6 @@ public interface Store<T, I> { Mono<T> read(I blobIds); - class BlobType { - private final String name; - - public BlobType(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public final boolean equals(Object o) { - if (o instanceof BlobType) { - BlobType blobType = (BlobType) o; - - return Objects.equals(this.name, blobType.name); - } - return false; - } - - @Override - public final int hashCode() { - return Objects.hash(name); - } - } - class Impl<T, I extends BlobPartsId> implements Store<T, I> { public interface ValueToSave { @@ -80,7 +52,7 @@ public interface Store<T, I> { @Override public Mono<BlobId> saveIn(BucketName bucketName, BlobStore blobStore) { - return blobStore.save(bucketName, bytes, storagePolicy); + return Mono.from(blobStore.save(bucketName, bytes, storagePolicy)); } } @@ -122,7 +94,7 @@ public interface Store<T, I> { return Flux.fromIterable(blobIds.asMap().entrySet()) .publishOn(Schedulers.elastic()) .flatMapSequential( - entry -> blobStore.readBytes(blobStore.getDefaultBucketName(), entry.getValue()) + entry -> Mono.from(blobStore.readBytes(blobStore.getDefaultBucketName(), entry.getValue())) .zipWith(Mono.just(entry.getKey()))) .map(entry -> Pair.of(entry.getT2(), entry.getT1())) .collectList() diff --git a/server/blob/blob-export-file/src/test/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanismTest.java b/server/blob/blob-export-file/src/test/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanismTest.java index 91a85a0..51c86bc 100644 --- a/server/blob/blob-export-file/src/test/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanismTest.java +++ b/server/blob/blob-export-file/src/test/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanismTest.java @@ -55,6 +55,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import nl.jqno.equalsverifier.EqualsVerifier; +import reactor.core.publisher.Mono; @ExtendWith(FileSystemExtension.class) class LocalFileBlobExportMechanismTest { @@ -81,7 +82,7 @@ class LocalFileBlobExportMechanismTest { @Test void exportingBlobShouldSendAMail() { - BlobId blobId = blobStore.save(blobStore.getDefaultBucketName(), BLOB_CONTENT, LOW_COST).block(); + BlobId blobId = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), BLOB_CONTENT, LOW_COST)).block(); String explanation = "The content of a deleted message vault had been shared with you."; testee.blobId(blobId) @@ -114,7 +115,7 @@ class LocalFileBlobExportMechanismTest { @Test void exportingBlobShouldCreateAFileWithTheCorrespondingContent(FileSystem fileSystem) { - BlobId blobId = blobStore.save(blobStore.getDefaultBucketName(), BLOB_CONTENT, LOW_COST).block(); + BlobId blobId = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), BLOB_CONTENT, LOW_COST)).block(); testee.blobId(blobId) .with(MailAddressFixture.RECIPIENT1) @@ -152,7 +153,7 @@ class LocalFileBlobExportMechanismTest { @Test void exportingBlobShouldCreateAFileWithoutExtensionWhenNotDeclaringExtension() { - BlobId blobId = blobStore.save(blobStore.getDefaultBucketName(), BLOB_CONTENT, LOW_COST).block(); + BlobId blobId = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), BLOB_CONTENT, LOW_COST)).block(); testee.blobId(blobId) .with(MailAddressFixture.RECIPIENT1) @@ -176,7 +177,7 @@ class LocalFileBlobExportMechanismTest { @Test void exportingBlobShouldCreateAFileWithExtensionWhenDeclaringExtension() { - BlobId blobId = blobStore.save(blobStore.getDefaultBucketName(), BLOB_CONTENT, LOW_COST).block(); + BlobId blobId = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), BLOB_CONTENT, LOW_COST)).block(); testee.blobId(blobId) .with(MailAddressFixture.RECIPIENT1) @@ -201,7 +202,7 @@ class LocalFileBlobExportMechanismTest { @Test void exportingBlobShouldCreateAFileWithPrefixWhenDeclaringPrefix() { - BlobId blobId = blobStore.save(blobStore.getDefaultBucketName(), BLOB_CONTENT, LOW_COST).block(); + BlobId blobId = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), BLOB_CONTENT, LOW_COST)).block(); String filePrefix = "[email protected]"; testee.blobId(blobId) diff --git a/server/blob/blob-memory/pom.xml b/server/blob/blob-memory/pom.xml index c28af44..6a6888c 100644 --- a/server/blob/blob-memory/pom.xml +++ b/server/blob/blob-memory/pom.xml @@ -44,6 +44,11 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> + <artifactId>james-server-util</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>${james.groupId}</groupId> <artifactId>metrics-tests</artifactId> <scope>test</scope> </dependency> @@ -57,6 +62,10 @@ <artifactId>commons-io</artifactId> </dependency> <dependency> + <groupId>io.projectreactor</groupId> + <artifactId>reactor-core</artifactId> + </dependency> + <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobStoreContract.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobStoreContract.java index a5b1fec..feb8046 100644 --- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobStoreContract.java +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobStoreContract.java @@ -29,6 +29,8 @@ import org.apache.commons.io.IOUtils; import org.apache.james.blob.api.BlobId; import org.apache.james.blob.api.BucketName; +import reactor.core.publisher.Mono; + public interface ObjectStorageBlobStoreContract { @@ -39,7 +41,7 @@ public interface ObjectStorageBlobStoreContract { default void assertBlobStoreCanStoreAndRetrieve(ObjectStorageBlobStoreBuilder.ReadyToBuild builder) { ObjectStorageBlobStore blobStore = builder.build(); - BlobId blobId = blobStore.save(blobStore.getDefaultBucketName(), CONTENT, LOW_COST).block(); + BlobId blobId = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), CONTENT, LOW_COST)).block(); InputStream inputStream = blobStore.read(blobStore.getDefaultBucketName(), blobId); assertThat(inputStream).hasSameContentAs(IOUtils.toInputStream(CONTENT, StandardCharsets.UTF_8)); diff --git a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobStoreTest.java b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobStoreTest.java index 263e105..10fb3c9 100644 --- a/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobStoreTest.java +++ b/server/blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/ObjectStorageBlobStoreTest.java @@ -120,7 +120,7 @@ public class ObjectStorageBlobStoreTest implements MetricableBlobStoreContract { .namespace(defaultBucketName) .build(); String content = "James is the best!"; - BlobId blobId = encryptedBlobStore.save(encryptedBlobStore.getDefaultBucketName(), content, LOW_COST).block(); + BlobId blobId = Mono.from(encryptedBlobStore.save(encryptedBlobStore.getDefaultBucketName(), content, LOW_COST)).block(); InputStream read = encryptedBlobStore.read(encryptedBlobStore.getDefaultBucketName(), blobId); String expectedContent = IOUtils.toString(read, Charsets.UTF_8); @@ -136,7 +136,7 @@ public class ObjectStorageBlobStoreTest implements MetricableBlobStoreContract { .namespace(defaultBucketName) .build(); String content = "James is the best!"; - BlobId blobId = encryptedBlobStore.save(encryptedBlobStore.getDefaultBucketName(), content, LOW_COST).block(); + BlobId blobId = Mono.from(encryptedBlobStore.save(encryptedBlobStore.getDefaultBucketName(), content, LOW_COST)).block(); InputStream encryptedIs = testee.read(encryptedBlobStore.getDefaultBucketName(), blobId); assertThat(encryptedIs).isNotNull(); @@ -151,7 +151,7 @@ public class ObjectStorageBlobStoreTest implements MetricableBlobStoreContract { @Test void deleteBucketShouldDeleteSwiftContainer() { BucketName bucketName = BucketName.of("azerty"); - objectStorageBlobStore.save(bucketName, "data", LOW_COST).block(); + Mono.from(objectStorageBlobStore.save(bucketName, "data", LOW_COST)).block(); objectStorageBlobStore.deleteBucket(bucketName).block(); @@ -177,32 +177,32 @@ public class ObjectStorageBlobStoreTest implements MetricableBlobStoreContract { @Test void saveBytesShouldNotCompleteWhenDoesNotAwait() { // String need to be big enough to get async thread busy hence could not return result instantly - Mono<BlobId> blobIdFuture = testee - .save(testee.getDefaultBucketName(), BIG_STRING.getBytes(StandardCharsets.UTF_8), LOW_COST) + Mono<BlobId> blobIdFuture = Mono.from(testee + .save(testee.getDefaultBucketName(), BIG_STRING.getBytes(StandardCharsets.UTF_8), LOW_COST)) .subscribeOn(Schedulers.elastic()); assertThat(blobIdFuture.toFuture()).isNotCompleted(); } @Test void saveStringShouldNotCompleteWhenDoesNotAwait() { - Mono<BlobId> blobIdFuture = testee - .save(testee.getDefaultBucketName(), BIG_STRING, LOW_COST) + Mono<BlobId> blobIdFuture = Mono.from(testee + .save(testee.getDefaultBucketName(), BIG_STRING, LOW_COST)) .subscribeOn(Schedulers.elastic()); assertThat(blobIdFuture.toFuture()).isNotCompleted(); } @Test void saveInputStreamShouldNotCompleteWhenDoesNotAwait() { - Mono<BlobId> blobIdFuture = testee - .save(testee.getDefaultBucketName(), new ByteArrayInputStream(BIG_STRING.getBytes(StandardCharsets.UTF_8)), LOW_COST) + Mono<BlobId> blobIdFuture = Mono.from(testee + .save(testee.getDefaultBucketName(), new ByteArrayInputStream(BIG_STRING.getBytes(StandardCharsets.UTF_8)), LOW_COST)) .subscribeOn(Schedulers.elastic()); assertThat(blobIdFuture.toFuture()).isNotCompleted(); } @Test void readBytesShouldNotCompleteWhenDoesNotAwait() { - BlobId blobId = testee().save(testee.getDefaultBucketName(), BIG_STRING, LOW_COST).block(); - Mono<byte[]> resultFuture = testee.readBytes(testee.getDefaultBucketName(), blobId).subscribeOn(Schedulers.elastic()); + BlobId blobId = Mono.from(testee().save(testee.getDefaultBucketName(), BIG_STRING, LOW_COST)).block(); + Mono<byte[]> resultFuture = Mono.from(testee.readBytes(testee.getDefaultBucketName(), blobId)).subscribeOn(Schedulers.elastic()); assertThat(resultFuture.toFuture()).isNotCompleted(); } } diff --git a/server/blob/blob-union/src/main/java/org/apache/james/blob/union/HybridBlobStore.java b/server/blob/blob-union/src/main/java/org/apache/james/blob/union/HybridBlobStore.java index 93e1532..0d700d8 100644 --- a/server/blob/blob-union/src/main/java/org/apache/james/blob/union/HybridBlobStore.java +++ b/server/blob/blob-union/src/main/java/org/apache/james/blob/union/HybridBlobStore.java @@ -129,7 +129,7 @@ public class HybridBlobStore implements BlobStore { @Override public Mono<BlobId> save(BucketName bucketName, byte[] data, StoragePolicy storagePolicy) { return selectBlobStore(storagePolicy, Mono.just(data.length > configuration.getSizeThreshold())) - .flatMap(blobStore -> blobStore.save(bucketName, data, storagePolicy)); + .flatMap(blobStore -> Mono.from(blobStore.save(bucketName, data, storagePolicy))); } @Override @@ -138,7 +138,7 @@ public class HybridBlobStore implements BlobStore { BufferedInputStream bufferedInputStream = new BufferedInputStream(data, configuration.getSizeThreshold() + 1); return selectBlobStore(storagePolicy, Mono.fromCallable(() -> isItABigStream(bufferedInputStream))) - .flatMap(blobStore -> blobStore.save(bucketName, bufferedInputStream, storagePolicy)); + .flatMap(blobStore -> Mono.from(blobStore.save(bucketName, bufferedInputStream, storagePolicy))); } private Mono<BlobStore> selectBlobStore(StoragePolicy storagePolicy, Mono<Boolean> largeData) { @@ -180,9 +180,9 @@ public class HybridBlobStore implements BlobStore { @Override public Mono<byte[]> readBytes(BucketName bucketName, BlobId blobId) { - return Mono.defer(() -> highPerformanceBlobStore.readBytes(bucketName, blobId)) + return Mono.defer(() -> Mono.from(highPerformanceBlobStore.readBytes(bucketName, blobId))) .onErrorResume(this::logAndReturnEmpty) - .switchIfEmpty(Mono.defer(() -> lowCostBlobStore.readBytes(bucketName, blobId))); + .switchIfEmpty(Mono.defer(() -> Mono.from(lowCostBlobStore.readBytes(bucketName, blobId)))); } @Override @@ -199,14 +199,14 @@ public class HybridBlobStore implements BlobStore { @Override public Mono<Void> deleteBucket(BucketName bucketName) { - return Mono.defer(() -> lowCostBlobStore.deleteBucket(bucketName)) + return Mono.defer(() -> Mono.from(lowCostBlobStore.deleteBucket(bucketName))) .and(highPerformanceBlobStore.deleteBucket(bucketName)) .onErrorResume(this::logDeleteFailureAndReturnEmpty); } @Override public Mono<Void> delete(BucketName bucketName, BlobId blobId) { - return Mono.defer(() -> lowCostBlobStore.delete(bucketName, blobId)) + return Mono.defer(() -> Mono.from(lowCostBlobStore.delete(bucketName, blobId))) .and(highPerformanceBlobStore.delete(bucketName, blobId)) .onErrorResume(this::logDeleteFailureAndReturnEmpty); } diff --git a/server/blob/mail-store/pom.xml b/server/blob/mail-store/pom.xml index 2ff830b..198faa5 100644 --- a/server/blob/mail-store/pom.xml +++ b/server/blob/mail-store/pom.xml @@ -38,6 +38,10 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> + <artifactId>blob-common</artifactId> + </dependency> + <dependency> + <groupId>${james.groupId}</groupId> <artifactId>blob-memory</artifactId> <scope>test</scope> </dependency> @@ -48,6 +52,10 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> + <artifactId>james-server-util</artifactId> + </dependency> + <dependency> + <groupId>${james.groupId}</groupId> <artifactId>testing-base</artifactId> <scope>test</scope> </dependency> diff --git a/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessagePartsId.java b/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessagePartsId.java index 7dc681a..5981be8 100644 --- a/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessagePartsId.java +++ b/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessagePartsId.java @@ -24,7 +24,7 @@ import java.util.Objects; import org.apache.james.blob.api.BlobId; import org.apache.james.blob.api.BlobPartsId; -import org.apache.james.blob.api.Store; +import org.apache.james.blob.api.BlobType; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; @@ -63,7 +63,7 @@ public class MimeMessagePartsId implements BlobPartsId { public static class Factory implements BlobPartsId.Factory<MimeMessagePartsId> { @Override - public MimeMessagePartsId generate(Map<Store.BlobType, BlobId> map) { + public MimeMessagePartsId generate(Map<BlobType, BlobId> map) { Preconditions.checkArgument(map.keySet().contains(HEADER_BLOB_TYPE), "Expecting 'mailHeader' blobId to be specified"); Preconditions.checkArgument(map.keySet().contains(BODY_BLOB_TYPE), "Expecting 'mailBody' blobId to be specified"); Preconditions.checkArgument(map.size() == 2, "blobId other than 'mailHeader' or 'mailBody' are not supported"); @@ -75,8 +75,8 @@ public class MimeMessagePartsId implements BlobPartsId { } } - static final Store.BlobType HEADER_BLOB_TYPE = new Store.BlobType("mailHeader"); - static final Store.BlobType BODY_BLOB_TYPE = new Store.BlobType("mailBody"); + static final BlobType HEADER_BLOB_TYPE = new BlobType("mailHeader"); + static final BlobType BODY_BLOB_TYPE = new BlobType("mailBody"); private final BlobId headerBlobId; private final BlobId bodyBlobId; @@ -87,7 +87,7 @@ public class MimeMessagePartsId implements BlobPartsId { } @Override - public Map<Store.BlobType, BlobId> asMap() { + public Map<BlobType, BlobId> asMap() { return ImmutableMap.of( HEADER_BLOB_TYPE, headerBlobId, BODY_BLOB_TYPE, bodyBlobId); diff --git a/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessageStore.java b/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessageStore.java index ad11196..47194a7 100644 --- a/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessageStore.java +++ b/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessageStore.java @@ -43,8 +43,8 @@ import javax.mail.internet.MimeMessage; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.james.blob.api.BlobStore; +import org.apache.james.blob.api.BlobType; import org.apache.james.blob.api.Store; -import org.apache.james.blob.api.Store.BlobType; import org.apache.james.util.BodyOffsetInputStream; import com.google.common.base.Preconditions; diff --git a/server/blob/mail-store/src/test/java/org/apache/james/blob/mail/MimeMessageStoreTest.java b/server/blob/mail-store/src/test/java/org/apache/james/blob/mail/MimeMessageStoreTest.java index ca3e64d..a7c0649 100644 --- a/server/blob/mail-store/src/test/java/org/apache/james/blob/mail/MimeMessageStoreTest.java +++ b/server/blob/mail-store/src/test/java/org/apache/james/blob/mail/MimeMessageStoreTest.java @@ -38,6 +38,8 @@ import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + class MimeMessageStoreTest { private static final HashBlobId.Factory BLOB_ID_FACTORY = new HashBlobId.Factory(); @@ -113,7 +115,7 @@ class MimeMessageStoreTest { BlobId headerBlobId = parts.getHeaderBlobId(); BlobId bodyBlobId = parts.getBodyBlobId(); - softly.assertThat(new String(blobStore.readBytes(blobStore.getDefaultBucketName(), headerBlobId).block(), StandardCharsets.UTF_8)) + softly.assertThat(new String(Mono.from(blobStore.readBytes(blobStore.getDefaultBucketName(), headerBlobId)).block(), StandardCharsets.UTF_8)) .isEqualTo("Date: Thu, 6 Sep 2018 13:29:13 +0700 (ICT)\r\n" + "From: [email protected]\r\n" + "To: [email protected]\r\n" + @@ -122,7 +124,7 @@ class MimeMessageStoreTest { "MIME-Version: 1.0\r\n" + "Content-Type: text/plain; charset=UTF-8\r\n" + "Content-Transfer-Encoding: 7bit\r\n\r\n"); - softly.assertThat(new String(blobStore.readBytes(blobStore.getDefaultBucketName(), bodyBlobId).block(), StandardCharsets.UTF_8)) + softly.assertThat(new String(Mono.from(blobStore.readBytes(blobStore.getDefaultBucketName(), bodyBlobId)).block(), StandardCharsets.UTF_8)) .isEqualTo("Important mail content"); }); } diff --git a/server/blob/pom.xml b/server/blob/pom.xml index 43d91bd..7385bfb 100644 --- a/server/blob/pom.xml +++ b/server/blob/pom.xml @@ -35,6 +35,7 @@ <modules> <module>blob-api</module> <module>blob-cassandra</module> + <module>blob-common</module> <module>blob-export-api</module> <module>blob-export-file</module> <module>blob-memory</module> diff --git a/server/container/jetty/pom.xml b/server/container/jetty/pom.xml index 5c80c03..32c5963 100644 --- a/server/container/jetty/pom.xml +++ b/server/container/jetty/pom.xml @@ -35,6 +35,10 @@ <dependencies> <dependency> <groupId>${james.groupId}</groupId> + <artifactId>james-core</artifactId> + </dependency> + <dependency> + <groupId>${james.groupId}</groupId> <artifactId>james-server-core</artifactId> <scope>test</scope> </dependency> diff --git a/server/container/lifecycle-api/pom.xml b/server/container/lifecycle-api/pom.xml index 9f020e4..dabda94 100644 --- a/server/container/lifecycle-api/pom.xml +++ b/server/container/lifecycle-api/pom.xml @@ -48,14 +48,6 @@ </dependency> <dependency> <groupId>org.slf4j</groupId> - <artifactId>jcl-over-slf4j</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>log4j-over-slf4j</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> </dependencies> diff --git a/server/container/metrics/metrics-es-reporter/pom.xml b/server/container/metrics/metrics-es-reporter/pom.xml index 4d3ee84..3414cd3 100644 --- a/server/container/metrics/metrics-es-reporter/pom.xml +++ b/server/container/metrics/metrics-es-reporter/pom.xml @@ -43,11 +43,11 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> - <artifactId>james-server-lifecycle-api</artifactId> + <artifactId>james-core</artifactId> </dependency> <dependency> <groupId>${james.groupId}</groupId> - <artifactId>james-server-util</artifactId> + <artifactId>james-server-lifecycle-api</artifactId> </dependency> <dependency> <groupId>${james.groupId}</groupId> diff --git a/server/data/data-api/pom.xml b/server/data/data-api/pom.xml index f98422d..3818153 100644 --- a/server/data/data-api/pom.xml +++ b/server/data/data-api/pom.xml @@ -43,10 +43,6 @@ </dependency> <dependency> <groupId>${james.groupId}</groupId> - <artifactId>james-server-util</artifactId> - </dependency> - <dependency> - <groupId>${james.groupId}</groupId> <artifactId>testing-base</artifactId> <scope>test</scope> </dependency> diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Keyword.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Keyword.java index 7b75299..d3296c2 100644 --- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Keyword.java +++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Keyword.java @@ -24,7 +24,6 @@ import java.util.Optional; import javax.mail.Flags; import org.apache.commons.lang3.StringUtils; -import org.apache.james.util.UnicodeSetUtils; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; @@ -36,11 +35,11 @@ public class Keyword { private static final int FLAG_NAME_MIN_LENGTH = 1; private static final int FLAG_NAME_MAX_LENGTH = 255; private static final UnicodeSet FLAG_NAME_PATTERN = - UnicodeSetUtils.letterOrDigitUnicodeSet() - .add('$') - .add('_') - .add('-') - .freeze(); + new UnicodeSet("[[a-z][A-Z][0-9]]") + .add('$') + .add('_') + .add('-') + .freeze(); public static final Keyword DRAFT = Keyword.of("$Draft"); public static final Keyword SEEN = Keyword.of("$Seen"); diff --git a/server/protocols/webadmin/webadmin-core/pom.xml b/server/protocols/webadmin/webadmin-core/pom.xml index d77687a..2b8680b 100644 --- a/server/protocols/webadmin/webadmin-core/pom.xml +++ b/server/protocols/webadmin/webadmin-core/pom.xml @@ -136,6 +136,11 @@ <artifactId>slf4j-api</artifactId> </dependency> <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>net.javacrumbs.json-unit</groupId> <artifactId>json-unit-assertj</artifactId> <scope>test</scope> diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/ExportService.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/ExportService.java index f3ca133..1ba4ed2 100644 --- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/ExportService.java +++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/ExportService.java @@ -87,7 +87,7 @@ class ExportService { try (FileBackedOutputStream fileOutputStream = new FileBackedOutputStream(FileUtils.ONE_MB_BI.intValue())) { zipper.zip(contentLoader(username), messages.toStream(), fileOutputStream); ByteSource byteSource = fileOutputStream.asByteSource(); - return blobStore.save(blobStore.getDefaultBucketName(), byteSource.openStream(), LOW_COST).block(); + return Mono.from(blobStore.save(blobStore.getDefaultBucketName(), byteSource.openStream(), LOW_COST)).block(); } } diff --git a/server/queue/queue-api/pom.xml b/server/queue/queue-api/pom.xml index 81c1abc..f0bab70 100644 --- a/server/queue/queue-api/pom.xml +++ b/server/queue/queue-api/pom.xml @@ -66,6 +66,11 @@ <artifactId>javax.mail</artifactId> </dependency> <dependency> + <groupId>io.projectreactor</groupId> + <artifactId>reactor-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> diff --git a/server/queue/queue-jms/pom.xml b/server/queue/queue-jms/pom.xml index 80f638d..44404db 100644 --- a/server/queue/queue-jms/pom.xml +++ b/server/queue/queue-jms/pom.xml @@ -89,6 +89,10 @@ <artifactId>javax.mail</artifactId> </dependency> <dependency> + <groupId>io.projectreactor</groupId> + <artifactId>reactor-core</artifactId> + </dependency> + <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-text</artifactId> <scope>test</scope> diff --git a/server/task/task-api/pom.xml b/server/task/task-api/pom.xml index 5c6fea7..61daaec 100644 --- a/server/task/task-api/pom.xml +++ b/server/task/task-api/pom.xml @@ -35,14 +35,19 @@ <dependencies> <dependency> <groupId>${james.groupId}</groupId> - <artifactId>james-server-util</artifactId> + <artifactId>testing-base</artifactId> + <scope>test</scope> </dependency> <dependency> - <groupId>${james.groupId}</groupId> - <artifactId>testing-base</artifactId> + <groupId>com.github.fge</groupId> + <artifactId>throwing-lambdas</artifactId> <scope>test</scope> </dependency> <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> </dependency> @@ -64,6 +69,10 @@ <groupId>org.scala-lang.modules</groupId> <artifactId>scala-java8-compat_${scala.base}</artifactId> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> </dependencies> <build> diff --git a/server/task/task-json/pom.xml b/server/task/task-json/pom.xml index e6a3dd0..4782d4d 100644 --- a/server/task/task-json/pom.xml +++ b/server/task/task-json/pom.xml @@ -63,6 +63,10 @@ <artifactId>jackson-databind</artifactId> </dependency> <dependency> + <groupId>javax.inject</groupId> + <artifactId>javax.inject</artifactId> + </dependency> + <dependency> <groupId>net.javacrumbs.json-unit</groupId> <artifactId>json-unit-assertj</artifactId> <scope>test</scope> diff --git a/third-party/linshare/src/test/java/org/apache/james/linshare/LinshareBlobExportMechanismTest.java b/third-party/linshare/src/test/java/org/apache/james/linshare/LinshareBlobExportMechanismTest.java index 736707c..3148e50 100644 --- a/third-party/linshare/src/test/java/org/apache/james/linshare/LinshareBlobExportMechanismTest.java +++ b/third-party/linshare/src/test/java/org/apache/james/linshare/LinshareBlobExportMechanismTest.java @@ -41,6 +41,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import reactor.core.publisher.Mono; + class LinshareBlobExportMechanismTest { private static final String FILE_CONTENT = "content"; private static final String EXPLANATION = "Explanation about the file being shared"; @@ -68,7 +70,7 @@ class LinshareBlobExportMechanismTest { @Test void exportShouldUploadTheDocumentToTargetUserViaLinshare() throws Exception { - BlobId blobId = blobStore.save(blobStore.getDefaultBucketName(), FILE_CONTENT, LOW_COST).block(); + BlobId blobId = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), FILE_CONTENT, LOW_COST)).block(); String filePrefix = "[email protected]"; testee.blobId(blobId) @@ -86,7 +88,7 @@ class LinshareBlobExportMechanismTest { @Test void exportShouldUploadTheDocumentAndAllowDownloadViaLinshare(LinshareAPIForTechnicalAccountTesting delegationAPIForTesting) throws Exception { - BlobId blobId = blobStore.save(blobStore.getDefaultBucketName(), FILE_CONTENT, LOW_COST).block(); + BlobId blobId = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), FILE_CONTENT, LOW_COST)).block(); testee.blobId(blobId) .with(new MailAddress(USER_2.getUsername())) @@ -116,7 +118,7 @@ class LinshareBlobExportMechanismTest { @Test void exportWithFilePrefixShouldCreateFileWithCustomPrefix() throws Exception { - BlobId blobId = blobStore.save(blobStore.getDefaultBucketName(), FILE_CONTENT, LOW_COST).block(); + BlobId blobId = Mono.from(blobStore.save(blobStore.getDefaultBucketName(), FILE_CONTENT, LOW_COST)).block(); String filePrefix = "[email protected]"; testee.blobId(blobId) @@ -130,4 +132,4 @@ class LinshareBlobExportMechanismTest { assertThat(sharedDoc.getName()) .startsWith(filePrefix); } -} \ No newline at end of file +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
