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 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)); }
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(); } }
private CompletableFuture<MessageResult> message(ResultSet rows,ComposedMessageIdWithMetaData messageIdWithMetaData, FetchType fetchType) { ComposedMessageId messageId = messageIdWithMetaData.getComposedMessageId(); if (rows.isExhausted()) { return CompletableFuture.completedFuture(notFound(messageIdWithMetaData)); } Row row = rows.one(); CompletableFuture<byte[]> contentFuture = buildContentRetriever(fetchType).apply(row); return contentFuture.thenApply(content -> { MessageWithoutAttachment messageWithoutAttachment = new MessageWithoutAttachment( messageId.getMessageId(), row.getTimestamp(INTERNAL_DATE), row.getLong(FULL_CONTENT_OCTETS), row.getInt(BODY_START_OCTET), new SharedByteArrayInputStream(content), messageIdWithMetaData.getFlags(), getPropertyBuilder(row), messageId.getMailboxId(), messageId.getUid(), messageIdWithMetaData.getModSeq()); return found(Pair.of(messageWithoutAttachment, getAttachments(row, fetchType))); }); }
@Test public void processShouldReturnOneMessageWhenMessageInSeveralMailboxes() throws Exception { MessageManager inbox = mailboxManager.getMailbox(inboxPath, session); ComposedMessageId message1 = inbox.appendMessage( AppendCommand.from( org.apache.james.mime4j.dom.Message.Builder.of() .setFrom("user@domain.tld") .setField(new RawField("header1", "Header1Content")) .setField(new RawField("HEADer2", "Header2Content")) .setSubject("message 1 subject") .setBody("my message", StandardCharsets.UTF_8)), session); MailboxId customMailboxId = mailboxManager.getMailbox(customMailboxPath, session).getId(); messageIdManager.setInMailboxes(message1.getMessageId(), ImmutableList.of(message1.getMailboxId(), customMailboxId), session); GetMessagesRequest request = GetMessagesRequest.builder() .ids(ImmutableList.of(message1.getMessageId())) .properties(ImmutableList.of("mailboxIds")) .build(); List<JmapResponse> result = testee.process(request, clientId, session).collect(Collectors.toList()); assertThat(result).hasSize(1); Method.Response response = result.get(0).getResponse(); assertThat(response).isInstanceOf(GetMessagesResponse.class); GetMessagesResponse getMessagesResponse = (GetMessagesResponse) response; assertThat(getMessagesResponse.list()).hasSize(1); assertThat(getMessagesResponse.list().get(0).getMailboxIds()).containsOnly(customMailboxId, message1.getMailboxId()); }
@Test public void mailboxIdsShouldReturnUpdatedWhenNoChange() throws Exception { ZonedDateTime dateTime = ZonedDateTime.parse("2014-10-30T14:12:00Z"); ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, MailboxPath.forUser(USERNAME, MailboxConstants.INBOX), new ByteArrayInputStream("Subject: my test subject\r\n\r\ntestmail".getBytes(StandardCharsets.UTF_8)), Date.from(dateTime.toInstant()), false, new Flags()); String messageToMoveId = message.getMessageId().serialize(); String mailboxId = message.getMailboxId().serialize(); String requestBody = "[" + " [" + " \"setMessages\"," + " {" + " \"update\": { \"" + messageToMoveId + "\" : {" + " \"mailboxIds\": [\"" + mailboxId + "\"]" + " }}" + " }," + " \"#0\"" + " ]" + "]"; given() .header("Authorization", accessToken.serialize()) .body(requestBody) .when() .post("/jmap") .then() .log().ifValidationFails() .spec(getSetMessagesUpdateOKResponseAssertions(messageToMoveId)); }
String inboxId = message.getMailboxId().serialize(); String requestBody = "[" + " [" +
String mailboxId = message.getMailboxId().serialize(); String requestBody = "[" + " [" +
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())); }
String inboxId = message.getMailboxId().serialize(); String requestBody = "[" + " [" +
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()))); }
String mailboxId = message.getMailboxId().serialize(); String requestBody = "[" + " [" +
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()))); }
public CompletableFuture<Boolean> updateMetadata(ComposedMessageIdWithMetaData composedMessageIdWithMetaData, long oldModSeq) { ComposedMessageId composedMessageId = composedMessageIdWithMetaData.getComposedMessageId(); Flags flags = composedMessageIdWithMetaData.getFlags(); return cassandraAsyncExecutor.executeReturnApplied(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(MESSAGE_ID, ((CassandraMessageId) composedMessageId.getMessageId()).get()) .setUUID(MAILBOX_ID, ((CassandraId) composedMessageId.getMailboxId()).asUuid()) .setLong(IMAP_UID, composedMessageId.getUid().asLong()) .setLong(MOD_SEQ_CONDITION, oldModSeq)); }