public boolean isMatching(MessageId messageId) { return getComposedMessageId().getMessageId().equals(messageId); }
public ComposedMessageIdWithMetaData getMetadata() { return new ComposedMessageIdWithMetaData(new ComposedMessageId(mailboxId, messageId, messageUid), flags, modSeq); }
private CompletableFuture<Void> deleteUsingMailboxId(ComposedMessageIdWithMetaData composedMessageIdWithMetaData) { ComposedMessageId composedMessageId = composedMessageIdWithMetaData.getComposedMessageId(); CassandraMessageId messageId = (CassandraMessageId) composedMessageId.getMessageId(); CassandraId mailboxId = (CassandraId) composedMessageId.getMailboxId(); MessageUid uid = composedMessageId.getUid(); return CompletableFuture.allOf( imapUidDAO.delete(messageId, mailboxId), messageIdDAO.delete(mailboxId, uid) ).thenCompose(voidValue -> indexTableHandler.updateIndexOnDelete(composedMessageIdWithMetaData, mailboxId)); }
private Stream<Pair<MailboxId, UpdatedFlags>> flagsUpdateWithRetry(Flags newState, MessageManager.FlagsUpdateMode updateMode, MailboxId mailboxId, MessageId messageId) { try { Pair<Flags, ComposedMessageIdWithMetaData> pair = new FunctionRunnerWithRetry(cassandraConfiguration.getFlagsUpdateMessageIdMaxRetry()) .executeAndRetrieveObject(() -> tryFlagsUpdate(newState, updateMode, mailboxId, messageId)); ComposedMessageIdWithMetaData composedMessageIdWithMetaData = pair.getRight(); Flags oldFlags = pair.getLeft(); return Stream.of(Pair.of(composedMessageIdWithMetaData.getComposedMessageId().getMailboxId(), UpdatedFlags.builder() .uid(composedMessageIdWithMetaData.getComposedMessageId().getUid()) .modSeq(composedMessageIdWithMetaData.getModSeq()) .oldFlags(oldFlags) .newFlags(composedMessageIdWithMetaData.getFlags()) .build())); } catch (LightweightTransactionException e) { throw new RuntimeException(e); } catch (MailboxDeleteDuringUpdateException e) { LOGGER.info("Mailbox {} was deleted during flag update", mailboxId); return Stream.of(); } }
@Override public Iterator<MessageUid> listAllMessageUids(Mailbox mailbox) throws MailboxException { CassandraId cassandraId = (CassandraId) mailbox.getMailboxId(); return messageIdDAO.retrieveMessages(cassandraId, MessageRange.all()) .join() .map(metaData -> metaData.getComposedMessageId().getUid()) .iterator(); }
public MessageFactory.MetaDataWithContent appendMessageInMailbox(org.apache.james.mime4j.dom.Message message, MessageManager messageManager, List<MessageAttachment> attachments, Flags flags, MailboxSession session) throws MailboxException { byte[] messageContent = asBytes(message); SharedByteArrayInputStream content = new SharedByteArrayInputStream(messageContent); Date internalDate = new Date(); ComposedMessageId appendedMessage = messageManager.appendMessage(MessageManager.AppendCommand.builder() .withFlags(flags) .build(content), session); return MessageFactory.MetaDataWithContent.builder() .uid(appendedMessage.getUid()) .keywords(Keywords.factory().fromFlags(flags)) .internalDate(internalDate.toInstant()) .sharedContent(content) .size(messageContent.length) .attachments(attachments) .mailboxId(messageManager.getId()) .messageId(appendedMessage.getMessageId()) .build(); }
public CompletableFuture<Void> updateIndexOnDelete(ComposedMessageIdWithMetaData composedMessageIdWithMetaData, CassandraId mailboxId) { MessageUid uid = composedMessageIdWithMetaData.getComposedMessageId().getUid(); return CompletableFuture.allOf( updateFirstUnseenOnDelete(mailboxId, composedMessageIdWithMetaData.getFlags(), composedMessageIdWithMetaData.getComposedMessageId().getUid()), mailboxRecentDAO.removeFromRecent(mailboxId, composedMessageIdWithMetaData.getComposedMessageId().getUid()), mailboxCounterDAO.decrementCount(mailboxId), deletedMessageDAO.removeDeleted(mailboxId, uid), decrementUnseenOnDelete(mailboxId, composedMessageIdWithMetaData.getFlags())); }
public CompletableFuture<Void> updateMetadata(ComposedMessageIdWithMetaData composedMessageIdWithMetaData) { ComposedMessageId composedMessageId = composedMessageIdWithMetaData.getComposedMessageId(); Flags flags = composedMessageIdWithMetaData.getFlags(); return cassandraAsyncExecutor.executeVoid(update.bind() .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq()) .setBool(ANSWERED, flags.contains(Flag.ANSWERED)) .setBool(DELETED, flags.contains(Flag.DELETED)) .setBool(DRAFT, flags.contains(Flag.DRAFT)) .setBool(FLAGGED, flags.contains(Flag.FLAGGED)) .setBool(RECENT, flags.contains(Flag.RECENT)) .setBool(SEEN, flags.contains(Flag.SEEN)) .setBool(USER, flags.contains(Flag.USER)) .setSet(USER_FLAGS, ImmutableSet.copyOf(flags.getUserFlags())) .setUUID(MAILBOX_ID, ((CassandraId) composedMessageId.getMailboxId()).asUuid()) .setLong(IMAP_UID, composedMessageId.getUid().asLong())); }
private Task.Result moveMessage(CassandraId newMailboxId, ComposedMessageId composedMessageId, MailboxSession session, MailboxMergingTask.Context context) { try { messageIdManager.setInMailboxesNoCheck(composedMessageId.getMessageId(), newMailboxId, session); context.incrementMovedCount(); return Task.Result.COMPLETED; } catch (MailboxException e) { LOGGER.warn("Failed moving message {}", composedMessageId.getMessageId(), e); context.incrementFailedCount(); return Task.Result.PARTIAL; } }
@Test void updateIndexOnDeleteShouldUpdateFirstUnseenWhenUnseen() { MailboxMessage message = mock(MailboxMessage.class); when(message.createFlags()).thenReturn(new Flags()); when(message.getUid()).thenReturn(MESSAGE_UID); testee.updateIndexOnAdd(message, MAILBOX_ID).join(); testee.updateIndexOnDelete(new ComposedMessageIdWithMetaData( new ComposedMessageId(MAILBOX_ID, CASSANDRA_MESSAGE_ID, MESSAGE_UID), new Flags(), MODSEQ), MAILBOX_ID).join(); Optional<MessageUid> actual = firstUnseenDAO.retrieveFirstUnread(MAILBOX_ID).join(); assertThat(actual.isPresent()).isFalse(); }
private CompletableFuture<Void> deleteIds(ComposedMessageIdWithMetaData metaData) { CassandraMessageId messageId = (CassandraMessageId) metaData.getComposedMessageId().getMessageId(); CassandraId mailboxId = (CassandraId) metaData.getComposedMessageId().getMailboxId(); return CompletableFuture.allOf( imapUidDAO.delete(messageId, mailboxId), messageIdDAO.delete(mailboxId, metaData.getComposedMessageId().getUid())) .thenCompose(voidValue -> indexTableHandler.updateIndexOnDelete(metaData, mailboxId)); }
public MessageUid appendMessage(MessageManager messageManager, MailboxSession session, Flags flags) throws MailboxException, UnsupportedEncodingException { return messageManager.appendMessage(new ByteArrayInputStream(MockMail.MAIL_TEXT_PLAIN.getBytes(StandardCharsets.UTF_8)), Calendar.getInstance().getTime(), session, true, flags).getUid(); }
public void retrieveAndSaveAttachmentDetails(String user, String messageId, String attachmentId, ComposedMessageId composedMessageId) throws MailboxException { AttachmentId mailboxAttachmentId = mainStepdefs.messageIdProbe .retrieveAttachmentIds(composedMessageId.getMessageId(), user) .get(0); inputToMessageId.put(messageId, composedMessageId.getMessageId()); attachmentsByMessageId.put(messageId, attachmentId); blobIdByAttachmentId.put(attachmentId, mailboxAttachmentId.getId()); }
@Test void updateIndexOnDeleteShouldDecrementMessageCount() throws Exception { MailboxMessage message = mock(MailboxMessage.class); when(message.createFlags()).thenReturn(new Flags()); when(message.getUid()).thenReturn(MESSAGE_UID); testee.updateIndexOnAdd(message, MAILBOX_ID).join(); testee.updateIndexOnDelete(new ComposedMessageIdWithMetaData( new ComposedMessageId(MAILBOX_ID, CASSANDRA_MESSAGE_ID, MESSAGE_UID), new Flags(Flags.Flag.RECENT), MODSEQ), MAILBOX_ID).join(); Optional<Long> actual = mailboxCounterDAO.countMessagesInMailbox(mailbox).join(); assertThat(actual.isPresent()).isTrue(); assertThat(actual.get()).isEqualTo(0); }
public CompletableFuture<Void> insert(ComposedMessageIdWithMetaData composedMessageIdWithMetaData) { ComposedMessageId composedMessageId = composedMessageIdWithMetaData.getComposedMessageId(); Flags flags = composedMessageIdWithMetaData.getFlags(); return cassandraAsyncExecutor.executeVoid(insert.bind() .setUUID(MAILBOX_ID, ((CassandraId) composedMessageId.getMailboxId()).asUuid()) .setLong(IMAP_UID, composedMessageId.getUid().asLong()) .setUUID(MESSAGE_ID, ((CassandraMessageId) composedMessageId.getMessageId()).get()) .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq()) .setBool(ANSWERED, flags.contains(Flag.ANSWERED)) .setBool(DELETED, flags.contains(Flag.DELETED)) .setBool(DRAFT, flags.contains(Flag.DRAFT)) .setBool(FLAGGED, flags.contains(Flag.FLAGGED)) .setBool(RECENT, flags.contains(Flag.RECENT)) .setBool(SEEN, flags.contains(Flag.SEEN)) .setBool(USER, flags.contains(Flag.USER)) .setSet(USER_FLAGS, ImmutableSet.copyOf(flags.getUserFlags()))); }
@Test void reIndexShouldBeWellPerformed() throws Exception { MailboxSession systemSession = mailboxManager.createSystemSession(USERNAME); MailboxId mailboxId = mailboxManager.createMailbox(INBOX, systemSession).get(); ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession) .appendMessage( MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"), systemSession); reIndexer.reIndex(INBOX).run(); ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class); ArgumentCaptor<Mailbox> mailboxCaptor1 = ArgumentCaptor.forClass(Mailbox.class); ArgumentCaptor<Mailbox> mailboxCaptor2 = ArgumentCaptor.forClass(Mailbox.class); verify(messageSearchIndex).deleteAll(any(MailboxSession.class), mailboxCaptor1.capture()); verify(messageSearchIndex).add(any(MailboxSession.class), mailboxCaptor2.capture(), messageCaptor.capture()); verifyNoMoreInteractions(messageSearchIndex); assertThat(mailboxCaptor1.getValue()).matches(mailbox -> mailbox.getMailboxId().equals(mailboxId)); assertThat(mailboxCaptor2.getValue()).matches(mailbox -> mailbox.getMailboxId().equals(mailboxId)); assertThat(messageCaptor.getValue()).matches(message -> message.getMailboxId().equals(mailboxId) && message.getUid().equals(createdMessage.getUid())); }
@Given("^\"([^\"]*)\" mailbox \"([^\"]*)\" contains a big message \"([^\"]*)\"$") public void appendBigMessageToMailbox(String user, String mailbox, String messageId) throws Throwable { MailboxPath mailboxPath = MailboxPath.forUser(user, mailbox); ComposedMessageId composedMessageId = mainStepdefs.mailboxProbe.appendMessage(user, mailboxPath, AppendCommand.from(new ByteArrayInputStream( Strings.repeat("header: 0123456789\r\n", 128 * 1024) .getBytes(StandardCharsets.UTF_8)))); inputToMessageId.put(messageId, composedMessageId.getMessageId()); }
@Test void updateIndexOnDeleteShouldDecrementUnseenMessageCountWhenUnseen() throws Exception { MailboxMessage message = mock(MailboxMessage.class); when(message.createFlags()).thenReturn(new Flags()); when(message.getUid()).thenReturn(MESSAGE_UID); testee.updateIndexOnAdd(message, MAILBOX_ID).join(); testee.updateIndexOnDelete(new ComposedMessageIdWithMetaData( new ComposedMessageId(MAILBOX_ID, CASSANDRA_MESSAGE_ID, MESSAGE_UID), new Flags(), MODSEQ), MAILBOX_ID).join(); Optional<Long> actual = mailboxCounterDAO.countUnseenMessagesInMailbox(mailbox).join(); assertThat(actual.isPresent()).isTrue(); assertThat(actual.get()).isEqualTo(0); }
public CompletableFuture<Void> insert(ComposedMessageIdWithMetaData composedMessageIdWithMetaData) { ComposedMessageId composedMessageId = composedMessageIdWithMetaData.getComposedMessageId(); Flags flags = composedMessageIdWithMetaData.getFlags(); return cassandraAsyncExecutor.executeVoid(insert.bind() .setUUID(MESSAGE_ID, ((CassandraMessageId) composedMessageId.getMessageId()).get()) .setUUID(MAILBOX_ID, ((CassandraId) composedMessageId.getMailboxId()).asUuid()) .setLong(IMAP_UID, composedMessageId.getUid().asLong()) .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq()) .setBool(ANSWERED, flags.contains(Flag.ANSWERED)) .setBool(DELETED, flags.contains(Flag.DELETED)) .setBool(DRAFT, flags.contains(Flag.DRAFT)) .setBool(FLAGGED, flags.contains(Flag.FLAGGED)) .setBool(RECENT, flags.contains(Flag.RECENT)) .setBool(SEEN, flags.contains(Flag.SEEN)) .setBool(USER, flags.contains(Flag.USER)) .setSet(USER_FLAGS, ImmutableSet.copyOf(flags.getUserFlags()))); }
@Test void mailboxPathUserShouldBeUsedWhenReIndexing() throws Exception { MailboxSession systemSession = mailboxManager.createSystemSession(USERNAME); MailboxId mailboxId = mailboxManager.createMailbox(INBOX, systemSession).get(); ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession) .appendMessage( MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"), systemSession); reIndexer.reIndex().run(); ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class); ArgumentCaptor<Mailbox> mailboxCaptor1 = ArgumentCaptor.forClass(Mailbox.class); ArgumentCaptor<Mailbox> mailboxCaptor2 = ArgumentCaptor.forClass(Mailbox.class); verify(messageSearchIndex).deleteAll(any(MailboxSession.class), mailboxCaptor1.capture()); verify(messageSearchIndex).add(any(MailboxSession.class), mailboxCaptor2.capture(), messageCaptor.capture()); verifyNoMoreInteractions(messageSearchIndex); assertThat(mailboxCaptor1.getValue()).matches(mailbox -> mailbox.getMailboxId().equals(mailboxId)); assertThat(mailboxCaptor2.getValue()).matches(mailbox -> mailbox.getMailboxId().equals(mailboxId)); assertThat(messageCaptor.getValue()).matches(message -> message.getMailboxId().equals(mailboxId) && message.getUid().equals(createdMessage.getUid())); }