JAMES-2266 Implement a task for merging mailboxes We merges mailboxes content and rights
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c6ec2831 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c6ec2831 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c6ec2831 Branch: refs/heads/master Commit: c6ec283177cdf04bb24424e43d207e5a42e81729 Parents: c964a64 Author: benwa <[email protected]> Authored: Thu Dec 14 14:45:21 2017 +0700 Committer: benwa <[email protected]> Committed: Fri Jan 5 16:06:36 2018 +0700 ---------------------------------------------------------------------- .../cassandra/mail/task/MailboxMergingTask.java | 73 ++++++++++++++ .../mail/task/MailboxMergingTaskRunner.java | 101 +++++++++++++++++++ 2 files changed, 174 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/c6ec2831/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTask.java ---------------------------------------------------------------------- diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTask.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTask.java new file mode 100644 index 0000000..62af99a --- /dev/null +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTask.java @@ -0,0 +1,73 @@ +/**************************************************************** + * 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.cassandra.mail.task; + +import java.util.Optional; + +import org.apache.james.mailbox.cassandra.ids.CassandraId; +import org.apache.james.task.Task; +import org.apache.james.task.TaskExecutionDetails; + +public class MailboxMergingTask implements Task { + public static final String MAILBOX_MERGING = "mailboxMerging"; + + public static class Details implements TaskExecutionDetails.AdditionalInformation { + private final CassandraId oldMailboxId; + private final CassandraId newMailboxId; + + public Details(CassandraId oldId, CassandraId newId) { + this.oldMailboxId = oldId; + this.newMailboxId = newId; + } + + public String getOldMailboxId() { + return oldMailboxId.serialize(); + } + + public String getNewMailboxId() { + return newMailboxId.serialize(); + } + } + + private final MailboxMergingTaskRunner taskRunner; + private final CassandraId oldMailboxId; + private final CassandraId newMailboxId; + + public MailboxMergingTask(MailboxMergingTaskRunner taskRunner, CassandraId oldMailboxId, CassandraId newMailboxId) { + this.taskRunner = taskRunner; + this.oldMailboxId = oldMailboxId; + this.newMailboxId = newMailboxId; + } + + @Override + public Result run() { + return taskRunner.run(oldMailboxId, newMailboxId); + } + + @Override + public String type() { + return MAILBOX_MERGING; + } + + @Override + public Optional<TaskExecutionDetails.AdditionalInformation> details() { + return Optional.of(new Details(oldMailboxId, newMailboxId)); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/c6ec2831/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTaskRunner.java ---------------------------------------------------------------------- diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTaskRunner.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTaskRunner.java new file mode 100644 index 0000000..8a29274 --- /dev/null +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/task/MailboxMergingTaskRunner.java @@ -0,0 +1,101 @@ +/**************************************************************** + * 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.cassandra.mail.task; + +import javax.inject.Inject; + +import org.apache.james.mailbox.MailboxManager; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.acl.ACLDiff; +import org.apache.james.mailbox.cassandra.ids.CassandraId; +import org.apache.james.mailbox.cassandra.mail.CassandraACLMapper; +import org.apache.james.mailbox.cassandra.mail.CassandraMailboxDAO; +import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO; +import org.apache.james.mailbox.cassandra.mail.CassandraUserMailboxRightsDAO; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.model.ComposedMessageId; +import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData; +import org.apache.james.mailbox.model.MailboxACL; +import org.apache.james.mailbox.model.MessageRange; +import org.apache.james.mailbox.store.StoreMessageIdManager; +import org.apache.james.task.Task; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Throwables; + +public class MailboxMergingTaskRunner { + private static final Logger LOGGER = LoggerFactory.getLogger(MailboxMergingTaskRunner.class); + + private final StoreMessageIdManager messageIdManager; + private final CassandraMessageIdDAO cassandraMessageIdDAO; + private final CassandraMailboxDAO mailboxDAO; + private final CassandraUserMailboxRightsDAO rightsDAO; + private final CassandraACLMapper cassandraACLMapper; + private final MailboxSession mailboxSession; + + @Inject + public MailboxMergingTaskRunner(MailboxManager mailboxManager, StoreMessageIdManager messageIdManager, CassandraMessageIdDAO cassandraMessageIdDAO, CassandraMailboxDAO mailboxDAO, CassandraUserMailboxRightsDAO rightsDAO, CassandraACLMapper cassandraACLMapper) throws MailboxException { + this.mailboxSession = mailboxManager.createSystemSession("task"); + this.messageIdManager = messageIdManager; + this.cassandraMessageIdDAO = cassandraMessageIdDAO; + this.mailboxDAO = mailboxDAO; + this.rightsDAO = rightsDAO; + this.cassandraACLMapper = cassandraACLMapper; + } + + public Task.Result run(CassandraId oldMailboxId, CassandraId newMailboxId) { + return moveMessages(oldMailboxId, newMailboxId, mailboxSession) + .onComplete( + () -> mergeRights(oldMailboxId, newMailboxId), + () -> mailboxDAO.delete(oldMailboxId).join()); + } + + private Task.Result moveMessages(CassandraId oldMailboxId, CassandraId newMailboxId, MailboxSession session) { + return cassandraMessageIdDAO.retrieveMessages(oldMailboxId, MessageRange.all()) + .join() + .map(ComposedMessageIdWithMetaData::getComposedMessageId) + .map(messageId -> moveMessage(newMailboxId, messageId, session)) + .reduce(Task.Result.COMPLETED, Task::combine); + } + + private Task.Result moveMessage(CassandraId newMailboxId, ComposedMessageId composedMessageId, MailboxSession session) { + try { + messageIdManager.setInMailboxesNoCheck(composedMessageId.getMessageId(), newMailboxId, session); + return Task.Result.COMPLETED; + } catch (MailboxException e) { + LOGGER.warn("Failed moving message {}", composedMessageId.getMessageId(), e); + return Task.Result.PARTIAL; + } + } + + private void mergeRights(CassandraId oldMailboxId, CassandraId newMailboxId) { + try { + MailboxACL oldAcl = cassandraACLMapper.getACL(oldMailboxId).join(); + MailboxACL newAcl = cassandraACLMapper.getACL(newMailboxId).join(); + MailboxACL finalAcl = newAcl.union(oldAcl); + + cassandraACLMapper.setACL(newMailboxId, finalAcl); + rightsDAO.update(oldMailboxId, ACLDiff.computeDiff(oldAcl, MailboxACL.EMPTY)).join(); + } catch (MailboxException e) { + Throwables.propagate(e); + } + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
