This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch postgresql in repository https://gitbox.apache.org/repos/asf/james-project.git
commit de96f76fd9f562cfd2dfebacee7b3858a3716af5 Author: Quan Tran <[email protected]> AuthorDate: Mon Jan 8 10:27:48 2024 +0700 JAMES-2586 Plug DeletedMessageVaultDeletionCallback into DeleteMessageListener missing attachment metadata though -> need to do it in https://github.com/linagora/james-project/issues/5011 --- .../plugin/deleted-messages-vault-postgres/pom.xml | 4 + .../DeletedMessageVaultDeletionCallback.java | 123 +++++++++++++++++++++ .../mailbox/postgres/DeleteMessageListener.java | 52 ++++++--- .../postgres/mail/MessageRepresentation.java | 113 +++++++++++++++++++ .../postgres/mail/dao/PostgresMessageDAO.java | 27 ++++- .../postgres/DeleteMessageListenerContract.java | 8 +- .../postgres/PostgresMailboxManagerProvider.java | 5 +- .../mailbox/PostgresDeletedMessageVaultModule.java | 6 + .../modules/mailbox/PostgresMailboxModule.java | 1 + 9 files changed, 319 insertions(+), 20 deletions(-) diff --git a/mailbox/plugin/deleted-messages-vault-postgres/pom.xml b/mailbox/plugin/deleted-messages-vault-postgres/pom.xml index 103fd725b4..856b49aa56 100644 --- a/mailbox/plugin/deleted-messages-vault-postgres/pom.xml +++ b/mailbox/plugin/deleted-messages-vault-postgres/pom.xml @@ -54,6 +54,10 @@ <artifactId>apache-james-mailbox-memory</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>${james.groupId}</groupId> + <artifactId>apache-james-mailbox-postgres</artifactId> + </dependency> <dependency> <groupId>${james.groupId}</groupId> <artifactId>james-server-guice-common</artifactId> diff --git a/mailbox/plugin/deleted-messages-vault-postgres/src/main/java/org/apache/james/vault/metadata/DeletedMessageVaultDeletionCallback.java b/mailbox/plugin/deleted-messages-vault-postgres/src/main/java/org/apache/james/vault/metadata/DeletedMessageVaultDeletionCallback.java new file mode 100644 index 0000000000..18a7027c46 --- /dev/null +++ b/mailbox/plugin/deleted-messages-vault-postgres/src/main/java/org/apache/james/vault/metadata/DeletedMessageVaultDeletionCallback.java @@ -0,0 +1,123 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "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 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.vault.metadata; + +import java.io.IOException; +import java.io.InputStream; +import java.io.SequenceInputStream; +import java.time.Clock; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.Optional; +import java.util.Set; + +import javax.inject.Inject; + +import org.apache.james.blob.api.BlobStore; +import org.apache.james.core.MailAddress; +import org.apache.james.core.MaybeSender; +import org.apache.james.core.Username; +import org.apache.james.mailbox.model.MailboxId; +import org.apache.james.mailbox.model.MessageId; +import org.apache.james.mailbox.postgres.DeleteMessageListener; +import org.apache.james.mailbox.postgres.mail.MessageRepresentation; +import org.apache.james.mime4j.MimeIOException; +import org.apache.james.mime4j.codec.DecodeMonitor; +import org.apache.james.mime4j.dom.Message; +import org.apache.james.mime4j.dom.address.Mailbox; +import org.apache.james.mime4j.message.DefaultMessageBuilder; +import org.apache.james.mime4j.stream.MimeConfig; +import org.apache.james.server.core.Envelope; +import org.apache.james.vault.DeletedMessage; +import org.apache.james.vault.DeletedMessageVault; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.fge.lambdas.Throwing; +import com.google.common.collect.ImmutableSet; + +import reactor.core.publisher.Mono; + +public class DeletedMessageVaultDeletionCallback implements DeleteMessageListener.DeletionCallback { + private static final Logger LOGGER = LoggerFactory.getLogger(DeletedMessageVaultDeletionCallback.class); + + private final DeletedMessageVault deletedMessageVault; + private final BlobStore blobStore; + private final Clock clock; + + @Inject + public DeletedMessageVaultDeletionCallback(DeletedMessageVault deletedMessageVault, BlobStore blobStore, Clock clock) { + this.deletedMessageVault = deletedMessageVault; + this.blobStore = blobStore; + this.clock = clock; + } + + @Override + public Mono<Void> forMessage(MessageRepresentation message, MailboxId mailboxId, Username owner) { + return Mono.fromSupplier(Throwing.supplier(() -> message.getHeaderContent().getInputStream())) + .flatMap(headerStream -> { + Optional<Message> mimeMessage = parseMessage(headerStream, message.getMessageId()); + DeletedMessage deletedMessage = DeletedMessage.builder() + .messageId(message.getMessageId()) + .originMailboxes(mailboxId) + .user(owner) + .deliveryDate(ZonedDateTime.ofInstant(message.getInternalDate().toInstant(), ZoneOffset.UTC)) + .deletionDate(ZonedDateTime.ofInstant(clock.instant(), ZoneOffset.UTC)) + .sender(retrieveSender(mimeMessage)) + .recipients(retrieveRecipients(mimeMessage)) + .hasAttachment(false) // todo return actual value in ticket: https://github.com/linagora/james-project/issues/5011 + .size(message.getSize()) + .subject(mimeMessage.map(Message::getSubject)) + .build(); + + return Mono.from(blobStore.readReactive(blobStore.getDefaultBucketName(), message.getBodyBlobId(), BlobStore.StoragePolicy.LOW_COST)) + .map(bodyStream -> new SequenceInputStream(headerStream, bodyStream)) + .flatMap(bodyStream -> Mono.from(deletedMessageVault.append(deletedMessage, bodyStream))); + }); + } + + private Optional<Message> parseMessage(InputStream inputStream, MessageId messageId) { + DefaultMessageBuilder messageBuilder = new DefaultMessageBuilder(); + messageBuilder.setMimeEntityConfig(MimeConfig.PERMISSIVE); + messageBuilder.setDecodeMonitor(DecodeMonitor.SILENT); + try { + return Optional.ofNullable(messageBuilder.parseMessage(inputStream)); + } catch (MimeIOException e) { + LOGGER.warn("Can not parse the message {}", messageId, e); + return Optional.empty(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private MaybeSender retrieveSender(Optional<Message> mimeMessage) { + return mimeMessage + .map(Message::getSender) + .map(Mailbox::getAddress) + .map(MaybeSender::getMailSender) + .orElse(MaybeSender.nullSender()); + } + + private Set<MailAddress> retrieveRecipients(Optional<Message> maybeMessage) { + return maybeMessage.map(message -> Envelope.fromMime4JMessage(message, Envelope.ValidationPolicy.IGNORE)) + .map(Envelope::getRecipients) + .orElse(ImmutableSet.of()); + } +} diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/DeleteMessageListener.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/DeleteMessageListener.java index 59c8768306..590e57a2d9 100644 --- a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/DeleteMessageListener.java +++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/DeleteMessageListener.java @@ -19,16 +19,21 @@ package org.apache.james.mailbox.postgres; +import java.util.Set; +import java.util.function.Function; + import javax.inject.Inject; -import org.apache.james.blob.api.BlobId; import org.apache.james.blob.api.BlobStore; +import org.apache.james.core.Username; import org.apache.james.events.Event; import org.apache.james.events.EventListener; import org.apache.james.events.Group; import org.apache.james.mailbox.events.MailboxEvents.Expunged; import org.apache.james.mailbox.events.MailboxEvents.MailboxDeletion; +import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MessageMetaData; +import org.apache.james.mailbox.postgres.mail.MessageRepresentation; import org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAO; import org.apache.james.mailbox.postgres.mail.dao.PostgresMessageDAO; import org.reactivestreams.Publisher; @@ -37,10 +42,18 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; public class DeleteMessageListener implements EventListener.ReactiveGroupEventListener { + @FunctionalInterface + public interface DeletionCallback { + Mono<Void> forMessage(MessageRepresentation messageRepresentation, MailboxId mailboxId, Username owner); + } + public static class DeleteMessageListenerGroup extends Group { } + public static final int LOW_CONCURRENCY = 4; + private final BlobStore blobStore; + private final Set<DeletionCallback> deletionCallbackList; private final PostgresMessageDAO.Factory messageDAOFactory; private final PostgresMailboxMessageDAO.Factory mailboxMessageDAOFactory; @@ -49,10 +62,12 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi @Inject public DeleteMessageListener(BlobStore blobStore, PostgresMailboxMessageDAO.Factory mailboxMessageDAOFactory, - PostgresMessageDAO.Factory messageDAOFactory) { + PostgresMessageDAO.Factory messageDAOFactory, + Set<DeletionCallback> deletionCallbackList) { this.messageDAOFactory = messageDAOFactory; this.mailboxMessageDAOFactory = mailboxMessageDAOFactory; this.blobStore = blobStore; + this.deletionCallbackList = deletionCallbackList; } @Override @@ -83,7 +98,7 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi PostgresMailboxMessageDAO postgresMailboxMessageDAO = mailboxMessageDAOFactory.create(event.getUsername().getDomainPart()); return postgresMailboxMessageDAO.deleteByMailboxId((PostgresMailboxId) event.getMailboxId()) - .flatMap(msgId -> handleMessageDeletion(msgId, postgresMessageDAO, postgresMailboxMessageDAO)) + .flatMap(msgId -> handleMessageDeletion(postgresMessageDAO, postgresMailboxMessageDAO, msgId, event.getMailboxId(), event.getMailboxPath().getUser())) .then(); } @@ -95,26 +110,35 @@ public class DeleteMessageListener implements EventListener.ReactiveGroupEventLi .values()) .map(MessageMetaData::getMessageId) .map(PostgresMessageId.class::cast) - .flatMap(msgId -> handleMessageDeletion(msgId, postgresMessageDAO, postgresMailboxMessageDAO)) + .flatMap(msgId -> handleMessageDeletion(postgresMessageDAO, postgresMailboxMessageDAO, msgId, event.getMailboxId(), event.getMailboxPath().getUser()), LOW_CONCURRENCY) .then(); } - - private Mono<Void> handleMessageDeletion(PostgresMessageId messageId, - PostgresMessageDAO postgresMessageDAO, - PostgresMailboxMessageDAO postgresMailboxMessageDAO) { + private Mono<Void> handleMessageDeletion(PostgresMessageDAO postgresMessageDAO, + PostgresMailboxMessageDAO postgresMailboxMessageDAO, + PostgresMessageId messageId, + MailboxId mailboxId, + Username owner) { return Mono.just(messageId) - .filterWhen(msgId -> isUnreferenced(msgId, postgresMailboxMessageDAO)) - .flatMap(id -> postgresMessageDAO.getBlobId(messageId) - .flatMap(this::deleteMessageBlobs) - .then(postgresMessageDAO.deleteByMessageId(messageId))); + .filterWhen(msgId -> isUnreferenced(messageId, postgresMailboxMessageDAO)) + .flatMap(msgId -> postgresMessageDAO.retrieveMessage(messageId) + .flatMap(executeDeletionCallbacks(mailboxId, owner)) + .then(deleteBodyBlob(msgId, postgresMessageDAO)) + .then(postgresMessageDAO.deleteByMessageId(msgId))); } - private Mono<Void> deleteMessageBlobs(BlobId blobId) { - return Mono.from(blobStore.delete(blobStore.getDefaultBucketName(), blobId)) + private Function<MessageRepresentation, Mono<Void>> executeDeletionCallbacks(MailboxId mailboxId, Username owner) { + return messageRepresentation -> Flux.fromIterable(deletionCallbackList) + .concatMap(callback -> callback.forMessage(messageRepresentation, mailboxId, owner)) .then(); } + private Mono<Void> deleteBodyBlob(PostgresMessageId id, PostgresMessageDAO postgresMessageDAO) { + return postgresMessageDAO.getBodyBlobId(id) + .flatMap(blobId -> Mono.from(blobStore.delete(blobStore.getDefaultBucketName(), blobId)) + .then()); + } + private Mono<Boolean> isUnreferenced(PostgresMessageId id, PostgresMailboxMessageDAO postgresMailboxMessageDAO) { return postgresMailboxMessageDAO.countByMessageId(id) .filter(count -> count == 0) diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/MessageRepresentation.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/MessageRepresentation.java new file mode 100644 index 0000000000..b960f7dde5 --- /dev/null +++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/MessageRepresentation.java @@ -0,0 +1,113 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "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 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox.postgres.mail; + +import java.util.Date; + +import org.apache.james.blob.api.BlobId; +import org.apache.james.mailbox.model.Content; +import org.apache.james.mailbox.model.MessageId; + +import com.google.common.base.Preconditions; + +public class MessageRepresentation { + public static MessageRepresentation.Builder builder() { + return new MessageRepresentation.Builder(); + } + + public static class Builder { + private MessageId messageId; + private Date internalDate; + private Long size; + private Content headerContent; + private BlobId bodyBlobId; + + public MessageRepresentation.Builder messageId(MessageId messageId) { + this.messageId = messageId; + return this; + } + + public MessageRepresentation.Builder internalDate(Date internalDate) { + this.internalDate = internalDate; + return this; + } + + public MessageRepresentation.Builder size(long size) { + Preconditions.checkArgument(size >= 0, "size can not be negative"); + this.size = size; + return this; + } + + public MessageRepresentation.Builder headerContent(Content headerContent) { + this.headerContent = headerContent; + return this; + } + + public MessageRepresentation.Builder bodyBlobId(BlobId bodyBlobId) { + this.bodyBlobId = bodyBlobId; + return this; + } + + public MessageRepresentation build() { + Preconditions.checkNotNull(messageId, "messageId is required"); + Preconditions.checkNotNull(internalDate, "internalDate is required"); + Preconditions.checkNotNull(size, "size is required"); + Preconditions.checkNotNull(headerContent, "headerContent is required"); + Preconditions.checkNotNull(bodyBlobId, "mailboxId is required"); + + return new MessageRepresentation(messageId, internalDate, size, headerContent, bodyBlobId); + } + } + + private final MessageId messageId; + private final Date internalDate; + private final Long size; + private final Content headerContent; + private final BlobId bodyBlobId; + + private MessageRepresentation(MessageId messageId, Date internalDate, Long size, + Content headerContent, BlobId bodyBlobId) { + this.messageId = messageId; + this.internalDate = internalDate; + this.size = size; + this.headerContent = headerContent; + this.bodyBlobId = bodyBlobId; + } + + public Date getInternalDate() { + return internalDate; + } + + public Long getSize() { + return size; + } + + public MessageId getMessageId() { + return messageId; + } + + public Content getHeaderContent() { + return headerContent; + } + + public BlobId getBodyBlobId() { + return bodyBlobId; + } +} diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMessageDAO.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMessageDAO.java index 3bb18c7bb4..c68b0e3792 100644 --- a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMessageDAO.java +++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMessageDAO.java @@ -20,6 +20,7 @@ package org.apache.james.mailbox.postgres.mail.dao; import static org.apache.james.backends.postgres.PostgresCommons.DATE_TO_LOCAL_DATE_TIME; +import static org.apache.james.backends.postgres.PostgresCommons.LOCAL_DATE_TIME_DATE_FUNCTION; import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.BODY_BLOB_ID; import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.BODY_START_OCTET; import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.CONTENT_DESCRIPTION; @@ -39,7 +40,9 @@ import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.Messa import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.SIZE; import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.TABLE_NAME; import static org.apache.james.mailbox.postgres.mail.PostgresMessageModule.MessageTable.TEXTUAL_LINE_COUNT; +import static org.apache.james.mailbox.postgres.mail.dao.PostgresMailboxMessageDAOUtils.BYTE_TO_CONTENT_FUNCTION; +import java.time.LocalDateTime; import java.util.Optional; import javax.inject.Inject; @@ -49,8 +52,12 @@ import org.apache.commons.io.IOUtils; import org.apache.james.backends.postgres.utils.PostgresExecutor; import org.apache.james.blob.api.BlobId; import org.apache.james.core.Domain; +import org.apache.james.mailbox.model.MessageId; import org.apache.james.mailbox.postgres.PostgresMessageId; +import org.apache.james.mailbox.postgres.mail.MessageRepresentation; +import org.apache.james.mailbox.postgres.mail.PostgresMessageModule; import org.apache.james.mailbox.store.mail.model.MailboxMessage; +import org.jooq.Record; import org.jooq.postgres.extensions.types.Hstore; import reactor.core.publisher.Mono; @@ -107,12 +114,30 @@ public class PostgresMessageDAO { .set(HEADER_CONTENT, headerContentAsByte)))); } + public Mono<MessageRepresentation> retrieveMessage(PostgresMessageId messageId) { + return postgresExecutor.executeRow(dslContext -> Mono.from(dslContext.select( + INTERNAL_DATE, SIZE, BODY_START_OCTET, HEADER_CONTENT, BODY_BLOB_ID) + .from(TABLE_NAME) + .where(MESSAGE_ID.eq(messageId.asUuid())))) + .map(record -> toMessageRepresentation(record, messageId)); + } + + private MessageRepresentation toMessageRepresentation(Record record, MessageId messageId) { + return MessageRepresentation.builder() + .messageId(messageId) + .internalDate(LOCAL_DATE_TIME_DATE_FUNCTION.apply(record.get(PostgresMessageModule.MessageTable.INTERNAL_DATE, LocalDateTime.class))) + .size(record.get(PostgresMessageModule.MessageTable.SIZE)) + .headerContent(BYTE_TO_CONTENT_FUNCTION.apply(record.get(HEADER_CONTENT))) + .bodyBlobId(blobIdFactory.from(record.get(BODY_BLOB_ID))) + .build(); + } + public Mono<Void> deleteByMessageId(PostgresMessageId messageId) { return postgresExecutor.executeVoid(dslContext -> Mono.from(dslContext.deleteFrom(TABLE_NAME) .where(MESSAGE_ID.eq(messageId.asUuid())))); } - public Mono<BlobId> getBlobId(PostgresMessageId messageId) { + public Mono<BlobId> getBodyBlobId(PostgresMessageId messageId) { return postgresExecutor.executeRow(dslContext -> Mono.from(dslContext.select(BODY_BLOB_ID) .from(TABLE_NAME) .where(MESSAGE_ID.eq(messageId.asUuid())))) diff --git a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/DeleteMessageListenerContract.java b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/DeleteMessageListenerContract.java index 6ca3ce9023..2ebb80f843 100644 --- a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/DeleteMessageListenerContract.java +++ b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/DeleteMessageListenerContract.java @@ -83,7 +83,7 @@ public abstract class DeleteMessageListenerContract { PostgresMessageId messageId = (PostgresMessageId) appendResult.getId().getMessageId(); PostgresMailboxId mailboxId = (PostgresMailboxId) appendResult.getId().getMailboxId(); - softly.assertThat(postgresMessageDAO.getBlobId(messageId).blockOptional()) + softly.assertThat(postgresMessageDAO.getBodyBlobId(messageId).blockOptional()) .isEmpty(); softly.assertThat(postgresMailboxMessageDAO.countTotalMessagesByMailboxId(mailboxId).block()) @@ -102,7 +102,7 @@ public abstract class DeleteMessageListenerContract { assertSoftly(softly -> { PostgresMessageId messageId = (PostgresMessageId) appendResult.getId().getMessageId(); - softly.assertThat(postgresMessageDAO.getBlobId(messageId).blockOptional()) + softly.assertThat(postgresMessageDAO.getBodyBlobId(messageId).blockOptional()) .isNotEmpty(); softly.assertThat(postgresMailboxMessageDAO.countTotalMessagesByMailboxId((PostgresMailboxId) otherBoxManager.getId()) @@ -121,7 +121,7 @@ public abstract class DeleteMessageListenerContract { assertSoftly(softly -> { PostgresMessageId messageId = (PostgresMessageId) appendResult.getId().getMessageId(); - softly.assertThat(postgresMessageDAO.getBlobId(messageId).blockOptional()) + softly.assertThat(postgresMessageDAO.getBodyBlobId(messageId).blockOptional()) .isEmpty(); }); } @@ -136,7 +136,7 @@ public abstract class DeleteMessageListenerContract { PostgresMessageId messageId = (PostgresMessageId) appendResult.getId().getMessageId(); assertSoftly(softly -> { - softly.assertThat(postgresMessageDAO.getBlobId(messageId).blockOptional()) + softly.assertThat(postgresMessageDAO.getBodyBlobId(messageId).blockOptional()) .isNotEmpty(); softly.assertThat(postgresMailboxMessageDAO.countTotalMessagesByMailboxId((PostgresMailboxId) otherBoxManager.getId()) diff --git a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/PostgresMailboxManagerProvider.java b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/PostgresMailboxManagerProvider.java index ccdcf906ce..a7753286f4 100644 --- a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/PostgresMailboxManagerProvider.java +++ b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/PostgresMailboxManagerProvider.java @@ -52,6 +52,8 @@ import org.apache.james.metrics.tests.RecordingMetricFactory; import org.apache.james.server.blob.deduplication.DeDuplicationBlobStore; import org.apache.james.utils.UpdatableTickingClock; +import com.google.common.collect.ImmutableSet; + public class PostgresMailboxManagerProvider { private static final int LIMIT_ANNOTATIONS = 3; @@ -80,7 +82,8 @@ public class PostgresMailboxManagerProvider { PostgresMessageDAO.Factory postgresMessageDAOFactory = new PostgresMessageDAO.Factory(BLOB_ID_FACTORY, postgresExtension.getExecutorFactory()); PostgresMailboxMessageDAO.Factory postgresMailboxMessageDAOFactory = new PostgresMailboxMessageDAO.Factory(postgresExtension.getExecutorFactory()); - eventBus.register(new DeleteMessageListener(blobStore, postgresMailboxMessageDAOFactory, postgresMessageDAOFactory)); + eventBus.register(new DeleteMessageListener(blobStore, postgresMailboxMessageDAOFactory, postgresMessageDAOFactory, + ImmutableSet.of())); return new PostgresMailboxManager((PostgresMailboxSessionMapperFactory) mf, sessionProvider, messageParser, new PostgresMessageId.Factory(), diff --git a/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresDeletedMessageVaultModule.java b/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresDeletedMessageVaultModule.java index 6e874b0d4f..607776982f 100644 --- a/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresDeletedMessageVaultModule.java +++ b/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresDeletedMessageVaultModule.java @@ -20,8 +20,10 @@ package org.apache.james.modules.mailbox; import org.apache.james.backends.postgres.PostgresModule; +import org.apache.james.mailbox.postgres.DeleteMessageListener; import org.apache.james.modules.vault.DeletedMessageVaultModule; import org.apache.james.vault.metadata.DeletedMessageMetadataVault; +import org.apache.james.vault.metadata.DeletedMessageVaultDeletionCallback; import org.apache.james.vault.metadata.PostgresDeletedMessageMetadataModule; import org.apache.james.vault.metadata.PostgresDeletedMessageMetadataVault; @@ -40,5 +42,9 @@ public class PostgresDeletedMessageVaultModule extends AbstractModule { bind(PostgresDeletedMessageMetadataVault.class).in(Scopes.SINGLETON); bind(DeletedMessageMetadataVault.class) .to(PostgresDeletedMessageMetadataVault.class); + + Multibinder.newSetBinder(binder(), DeleteMessageListener.DeletionCallback.class) + .addBinding() + .to(DeletedMessageVaultDeletionCallback.class); } } diff --git a/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresMailboxModule.java b/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresMailboxModule.java index 2361fbc750..97f4716a4a 100644 --- a/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresMailboxModule.java +++ b/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresMailboxModule.java @@ -129,6 +129,7 @@ public class PostgresMailboxModule extends AbstractModule { Multibinder.newSetBinder(binder(), EventListener.ReactiveGroupEventListener.class) .addBinding().to(DeleteMessageListener.class); + Multibinder.newSetBinder(binder(), DeleteMessageListener.DeletionCallback.class); bind(MailboxManager.class).annotatedWith(Names.named(MAILBOXMANAGER_NAME)).to(MailboxManager.class); bind(MailboxManagerConfiguration.class).toInstance(MailboxManagerConfiguration.DEFAULT); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
