bigMail = null; mailboxManager.getMailbox(mailboxPath, session).appendMessage(MessageManager.AppendCommand.builder() .build(out.toByteArray()), session); mailboxManager.startProcessingRequest(session);
mailboxManager.getMailbox(mailboxPath, session).appendMessage(MessageManager.AppendCommand.from( Message.Builder.of() .setSubject("test")
public AppendCommand build(InputStream msgIn) { return new AppendCommand( msgIn, internalDate.orElse(new Date()), isRecent.orElse(true), flags.orElse(new Flags())); }
ComposedMessageId messageId = m.appendMessage( MessageManager.AppendCommand .from(Message.Builder.of() .setSubject("test") .setBody("testmail", StandardCharsets.UTF_8)), mailboxSession);
MessageManager inbox = mailboxManager.getMailbox(inboxPath, session); ComposedMessageId message1 = inbox.appendMessage( AppendCommand.builder() .withFlags(flags1) .build(messageContent1), session); ComposedMessageId message2 = inbox.appendMessage( AppendCommand.builder() .withFlags(flags2) .build(messageContent2), session); ComposedMessageId message3 = inbox.appendMessage( AppendCommand.builder() .withFlags(flags3) .build(messageContent3),
MessageManager inbox = mailboxManager.getMailbox(inboxPath, session); ComposedMessageId message1 = inbox.appendMessage( AppendCommand.builder() .withFlags(flags) .build(messageContent1), session); ComposedMessageId message2 = inbox.appendMessage( AppendCommand.builder() .withFlags(flags) .build(messageContent2), session); ComposedMessageId message3 = inbox.appendMessage( AppendCommand.builder() .withFlags(flags) .build(messageContent3),
mailboxManager.getMailbox(mailboxPath, session).appendMessage(MessageManager.AppendCommand.from( Message.Builder.of() .setSubject("test")
.appendMessage(MessageManager.AppendCommand.builder() .recent() .build(envelope.getMessageInputStream()),
Flags readMessageFlag = new Flags(); readMessageFlag.add(Flags.Flag.SEEN); messageManager.appendMessage(MessageManager.AppendCommand.builder() .withFlags(defaultUnseenFlag) .build(Message.Builder.of() .setSubject("test") .setBody("testmail", StandardCharsets.UTF_8)), mailboxSession); messageManager.appendMessage(MessageManager.AppendCommand.builder() .withFlags(defaultUnseenFlag) .build(Message.Builder.of() .setSubject("test2") .setBody("testmail", StandardCharsets.UTF_8)), mailboxSession); messageManager.appendMessage(MessageManager.AppendCommand.builder() .withFlags(readMessageFlag) .build(Message.Builder.of()
public MessageFactory.MetaDataWithContent appendMessageInMailboxes(CreationMessageEntry createdEntry, List<MailboxId> targetMailboxes, MailboxSession session) throws MailboxException { Preconditions.checkArgument(!targetMailboxes.isEmpty()); ImmutableList<MessageAttachment> messageAttachments = getMessageAttachments(session, createdEntry.getValue().getAttachments()); byte[] messageContent = mimeMessageConverter.convert(createdEntry, messageAttachments); SharedByteArrayInputStream content = new SharedByteArrayInputStream(messageContent); Date internalDate = Date.from(createdEntry.getValue().getDate().toInstant()); MessageManager mailbox = mailboxManager.getMailbox(targetMailboxes.get(0), session); ComposedMessageId message = mailbox.appendMessage( MessageManager.AppendCommand.builder() .withInternalDate(internalDate) .withFlags(getFlags(createdEntry.getValue())) .notRecent() .build(content), session); if (targetMailboxes.size() > 1) { messageIdManager.setInMailboxes(message.getMessageId(), targetMailboxes, session); } return MessageFactory.MetaDataWithContent.builder() .uid(message.getUid()) .keywords(createdEntry.getValue().getKeywords()) .internalDate(internalDate.toInstant()) .sharedContent(content) .size(messageContent.length) .attachments(messageAttachments) .mailboxId(mailbox.getId()) .messageId(message.getMessageId()) .build(); }
@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 getMailboxesShouldReturnMailboxPropertiesWhenAvailable() throws Exception { String myMailboxId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, ALICE, "name").serialize(); mailboxProbe.appendMessage(ALICE, MailboxPath.forUser(ALICE, "name"), AppendCommand.from(message)); given() .header("Authorization", accessToken.serialize()) .body("[[\"getMailboxes\", {\"ids\": [\"" + myMailboxId + "\"]}, \"#0\"]]") .when() .post("/jmap") .then() .statusCode(200) .body(NAME, equalTo("mailboxes")) .body(ARGUMENTS + ".list.name", hasItem("name")) .body(FIRST_MAILBOX + ".parentId", nullValue()) .body(FIRST_MAILBOX + ".role", nullValue()) .body(FIRST_MAILBOX + ".sortOrder", equalTo(1000)) .body(FIRST_MAILBOX + ".mustBeOnlyMailbox", equalTo(false)) .body(FIRST_MAILBOX + ".mayReadItems", equalTo(true)) .body(FIRST_MAILBOX + ".mayAddItems", equalTo(true)) .body(FIRST_MAILBOX + ".mayRemoveItems", equalTo(true)) .body(FIRST_MAILBOX + ".mayCreateChild", equalTo(true)) .body(FIRST_MAILBOX + ".mayRename", equalTo(true)) .body(FIRST_MAILBOX + ".mayDelete", equalTo(true)) .body(FIRST_MAILBOX + ".totalMessages", equalTo(1)) .body(FIRST_MAILBOX + ".unreadMessages", equalTo(1)) .body(FIRST_MAILBOX + ".unreadThreads", equalTo(0)); }
@Test public void processShouldReturnKeywordsWithoutForwardedWhenForwardedUserFlagsMessages() throws Exception { Flags flags = FlagsBuilder.builder() .add(Flag.ANSWERED, Flag.DELETED) .add(FORWARDED) .build(); MessageManager inbox = mailboxManager.getMailbox(inboxPath, session); ComposedMessageId message1 = inbox.appendMessage( AppendCommand.builder() .withFlags(flags) .build(messageContent1), session); GetMessagesRequest request = GetMessagesRequest.builder() .ids(ImmutableList.of(message1.getMessageId())) .build(); List<JmapResponse> result = testee.process(request, clientId, session).collect(Collectors.toList()); assertThat(result).hasSize(1) .extracting(JmapResponse::getResponse) .hasOnlyElementsOfType(GetMessagesResponse.class) .extracting(GetMessagesResponse.class::cast) .flatExtracting(GetMessagesResponse::list) .extracting(Message::getKeywords) .containsOnlyElementsOf( ImmutableList.of( ImmutableMap.of( "$Answered", true, FORWARDED, true))); }
MessageManager.AppendCommand.builder() .build(Message.Builder.of() .setSubject("test") .setBody("content", StandardCharsets.UTF_8))); ComposedMessageId message2 = mailboxProbe.appendMessage(ALICE, MailboxPath.forUser(ALICE, "mailbox"), MessageManager.AppendCommand.builder() .build(Message.Builder.of() .setBody(
MessageManager.AppendCommand.builder() .build(Message.Builder.of() .setSubject("test") .setBody("content", StandardCharsets.UTF_8))); ComposedMessageId message2 = mailboxProbe.appendMessage(ALICE, MailboxPath.forUser(ALICE, "mailbox"), MessageManager.AppendCommand.builder() .build(Message.Builder.of() .setBody(
private void simulateGhostMailboxBug() throws MailboxException, IOException { // State before ghost mailbox bug // Alice INBOX is delegated to Bob and contains one message aliceInboxPath = MailboxPath.forUser(ALICE, MailboxConstants.INBOX); aliceGhostInboxId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, ALICE, MailboxConstants.INBOX); aclProbe.addRights(aliceInboxPath, BOB, MailboxACL.FULL_RIGHTS); message1 = mailboxProbe.appendMessage(ALICE, aliceInboxPath, AppendCommand.from(generateMessageContent())); testExtension.await(); // Simulate ghost mailbox bug session.execute(delete().from(CassandraMailboxPathV2Table.TABLE_NAME) .where(eq(CassandraMailboxPathV2Table.NAMESPACE, MailboxConstants.USER_NAMESPACE)) .and(eq(CassandraMailboxPathV2Table.USER, ALICE)) .and(eq(CassandraMailboxPathV2Table.MAILBOX_NAME, MailboxConstants.INBOX))); // trigger provisioning given() .header("Authorization", accessToken.serialize()) .body("[[\"getMailboxes\", {}, \"#0\"]]") .when() .post("/jmap") .then() .statusCode(200); // Received a new message message2 = mailboxProbe.appendMessage(ALICE, aliceInboxPath, AppendCommand.from(generateMessageContent())); testExtension.await(); }
@Test void reIndexShouldBeWellPerformed() throws Exception { // Given a mailbox with 1000 messages * 150 KB MailboxSession systemSession = mailboxManager.createSystemSession(USERNAME); mailboxManager.createMailbox(INBOX, systemSession); byte[] bigBody = (Strings.repeat("header: value\r\n", 10000) + "\r\nbody").getBytes(StandardCharsets.UTF_8); int threadCount = 10; int operationCount = 100; MessageManager mailbox = mailboxManager.getMailbox(INBOX, systemSession); ConcurrentTestRunner.builder() .operation((a, b) -> mailbox .appendMessage( MessageManager.AppendCommand.builder().build(bigBody), systemSession)) .threadCount(threadCount) .operationCount(operationCount) .runSuccessfullyWithin(Duration.ofMinutes(10)); // When We re-index reIndexer.reIndex(INBOX).run(); // The indexer is called for each message verify(messageSearchIndex).deleteAll(any(MailboxSession.class), any(Mailbox.class)); verify(messageSearchIndex, times(threadCount * operationCount)) .add(any(MailboxSession.class), any(Mailbox.class),any(MailboxMessage.class)); verifyNoMoreInteractions(messageSearchIndex); } }
@Test public void processShouldNotFailOnSingleMessageFailure() throws Exception { MessageFactory messageFactory = mock(MessageFactory.class); testee = new GetMessagesMethod(messageFactory, messageIdManager, new DefaultMetricFactory()); MessageManager inbox = mailboxManager.getMailbox(inboxPath, session); org.apache.james.mime4j.dom.Message messageContent = 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) .build(); ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent), session); ComposedMessageId message2 = inbox.appendMessage(AppendCommand.from(messageContent), session); when(messageFactory.fromMetaDataWithContent(any())) .thenReturn(mock(Message.class)) .thenThrow(new RuntimeException()); GetMessagesRequest request = GetMessagesRequest.builder() .ids(ImmutableList.of(message1.getMessageId(), message2.getMessageId())) .properties(ImmutableList.of("mailboxIds")) .build(); List<JmapResponse> responses = testee.process(request, clientId, session).collect(Guavate.toImmutableList()); assertThat(responses).hasSize(1); Method.Response response = responses.get(0).getResponse(); assertThat(response).isInstanceOf(GetMessagesResponse.class); GetMessagesResponse getMessagesResponse = (GetMessagesResponse) response; assertThat(getMessagesResponse.list()).hasSize(1); }
@Test @SuppressWarnings("unchecked") public void processShouldFetchMessages() throws Exception { MessageManager inbox = mailboxManager.getMailbox(inboxPath, session); ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session); ComposedMessageId message2 = inbox.appendMessage(AppendCommand.from(messageContent2), session); ComposedMessageId message3 = inbox.appendMessage(AppendCommand.from(messageContent3), session); GetMessagesRequest request = GetMessagesRequest.builder() .ids(ImmutableList.of(message1.getMessageId(), message2.getMessageId(), message3.getMessageId())) .build(); List<JmapResponse> result = testee.process(request, clientId, session).collect(Collectors.toList()); assertThat(result).hasSize(1) .extracting(JmapResponse::getResponse) .hasOnlyElementsOfType(GetMessagesResponse.class) .extracting(GetMessagesResponse.class::cast) .flatExtracting(GetMessagesResponse::list) .extracting(Message::getId, Message::getSubject, Message::getTextBody) .containsOnly( Tuple.tuple(message1.getMessageId(), "message 1 subject", Optional.of("my message")), Tuple.tuple(message2.getMessageId(), "message 2 subject", Optional.of("my message")), Tuple.tuple(message3.getMessageId(), "", Optional.of("my message"))); }
@Test public void processShouldReturnPropertyFilterWhenFilteringHeadersRequested() 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); GetMessagesRequest request = GetMessagesRequest.builder() .ids(ImmutableList.of(message1.getMessageId())) .properties(ImmutableList.of("headers.from", "headers.heADER2")) .build(); List<JmapResponse> result = testee.process(request, clientId, session).collect(Collectors.toList()); assertThat(result) .hasSize(1) .extracting(JmapResponse::getFilterProvider) .are(new Condition<>(Optional::isPresent, "present")); SimpleFilterProvider actualFilterProvider = result.get(0).getFilterProvider().get(); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setFilterProvider(actualFilterProvider.setDefaultFilter(SimpleBeanPropertyFilter.serializeAll())); String response = objectMapper.writer().writeValueAsString(result.get(0)); assertThat(JsonPath.parse(response).<Map<String, String>>read("$.response.list[0].headers")).containsOnly(MapEntry.entry("From", "user@domain.tld"), MapEntry.entry("HEADer2", "Header2Content")); }