use of org.xwiki.mail.MailStatusResult in project xwiki-platform by xwiki.
the class PrepareMailRunnable method prepareMail.
/**
* Prepare the messages to send, persist them and put them on the Mail Sender Queue.
*
* @param item the queue item containing all the data for sending the mail
* @throws org.xwiki.context.ExecutionContextException when the XWiki Context fails to be set up
*/
protected void prepareMail(PrepareMailQueueItem item) throws ExecutionContextException {
Iterator<? extends MimeMessage> messageIterator = item.getMessages().iterator();
MailListener listener = item.getListener();
if (listener != null) {
listener.onPrepareBegin(item.getBatchId(), Collections.<String, Object>emptyMap());
}
// Count the total number of messages to process
long messageCounter = 0;
try {
boolean shouldStop = false;
while (!shouldStop) {
// Note that we need to have the hasNext() call after the context is ready since the implementation can
// need a valid XWiki Context.
prepareContext(item.getContext());
try {
if (messageIterator.hasNext()) {
MimeMessage mimeMessage = messageIterator.next();
prepareSingleMail(mimeMessage, item);
messageCounter++;
} else {
shouldStop = true;
}
} finally {
removeContext();
}
}
} catch (Exception e) {
if (listener != null) {
listener.onPrepareFatalError(e, Collections.<String, Object>emptyMap());
}
} finally {
if (listener != null) {
MailStatusResult result = listener.getMailStatusResult();
// so that waiting process have a chance to see an end.
if (result instanceof UpdateableMailStatusResult) {
((UpdateableMailStatusResult) result).setTotalSize(messageCounter);
}
listener.onPrepareEnd(Collections.<String, Object>emptyMap());
}
}
}
use of org.xwiki.mail.MailStatusResult in project xwiki-platform by xwiki.
the class MailStorageScriptService method resendAsynchronously.
/**
* Resend the serialized MimeMessage asynchronously.
*
* @param batchId the name of the directory that contains serialized MimeMessage
* @param uniqueMessageId the unique id of the serialized MimeMessage
* @return the result and status of the send batch; null if an error occurred when getting the message from the
* store
* @since 9.3RC1
*/
@Unstable
public ScriptMailResult resendAsynchronously(String batchId, String uniqueMessageId) {
try {
MailStatusResult statusResult = this.mailResender.resendAsynchronously(batchId, uniqueMessageId);
ScriptMailResult scriptMailResult = new ScriptMailResult(new DefaultMailResult(batchId), statusResult);
return scriptMailResult;
} catch (MailStoreException e) {
// Save the exception for reporting through the script services's getLastError() API
setError(e);
return null;
}
}
use of org.xwiki.mail.MailStatusResult in project xwiki-platform by xwiki.
the class PrepareMailRunnableTest method prepareMailWhenContentStoreFails.
@Test
public void prepareMailWhenContentStoreFails() throws Exception {
Properties properties = new Properties();
Session session = Session.getDefaultInstance(properties);
MimeMessage message1 = new MimeMessage(session);
message1.setText("Content1");
MimeMessage message2 = new MimeMessage(session);
message2.setText("Content2");
String batchId1 = UUID.randomUUID().toString();
String batchId2 = UUID.randomUUID().toString();
ExecutionContext context1 = new ExecutionContext();
XWikiContext xContext1 = new XWikiContext();
xContext1.setWikiId("wiki1");
context1.setProperty(XWikiContext.EXECUTIONCONTEXT_KEY, xContext1);
ExecutionContext context2 = new ExecutionContext();
XWikiContext xContext2 = new XWikiContext();
xContext2.setWikiId("wiki2");
context2.setProperty(XWikiContext.EXECUTIONCONTEXT_KEY, xContext2);
MemoryMailListener listener1 = this.mocker.getInstance(MailListener.class, "memory");
PrepareMailQueueItem item1 = new PrepareMailQueueItem(Arrays.asList(message1), session, listener1, batchId1, context1);
MemoryMailListener listener2 = this.mocker.getInstance(MailListener.class, "memory");
PrepareMailQueueItem item2 = new PrepareMailQueueItem(Arrays.asList(message2), session, listener2, batchId2, context2);
MailQueueManager mailQueueManager = this.mocker.getInstance(new DefaultParameterizedType(null, MailQueueManager.class, PrepareMailQueueItem.class));
// Make the content store save fail
MailContentStore contentStore = this.mocker.getInstance(MailContentStore.class, "filesystem");
doThrow(new MailStoreException("error")).when(contentStore).save(any(String.class), any(ExtendedMimeMessage.class));
// Prepare 2 mails. Both will fail but we want to verify that the second one is processed even though the first
// one failed.
mailQueueManager.addToQueue(item1);
mailQueueManager.addToQueue(item2);
MailRunnable runnable = this.mocker.getComponentUnderTest();
Thread thread = new Thread(runnable);
thread.start();
// Wait for the mails to have been processed.
try {
listener1.getMailStatusResult().waitTillProcessed(10000L);
listener2.getMailStatusResult().waitTillProcessed(10000L);
} finally {
runnable.stopProcessing();
thread.interrupt();
thread.join();
}
MailStatusResult result1 = listener1.getMailStatusResult();
MailStatusResult result2 = listener2.getMailStatusResult();
// Despite the errors, both process should be ended with known total number of mails
assertTrue(result1.isProcessed());
assertTrue(result2.isProcessed());
// This is the real test: we verify that there's been an error while sending each email.
MailStatus status1 = result1.getByState(MailState.PREPARE_ERROR).next();
assertEquals("MailStoreException: error", status1.getErrorSummary());
MailStatus status2 = result2.getByState(MailState.PREPARE_ERROR).next();
assertEquals("MailStoreException: error", status2.getErrorSummary());
}
use of org.xwiki.mail.MailStatusResult in project xwiki-platform by xwiki.
the class PrepareMailRunnableTest method prepareMailWhenIteratorFails.
@Test
public void prepareMailWhenIteratorFails() throws Exception {
Properties properties = new Properties();
Session session = Session.getDefaultInstance(properties);
final MimeMessage message1 = new MimeMessage(session);
message1.setText("Content1");
MimeMessage message2 = new MimeMessage(session);
message2.setText("Content2");
String batchId1 = UUID.randomUUID().toString();
String batchId2 = UUID.randomUUID().toString();
ExecutionContext context1 = new ExecutionContext();
XWikiContext xContext1 = new XWikiContext();
xContext1.setWikiId("wiki1");
context1.setProperty(XWikiContext.EXECUTIONCONTEXT_KEY, xContext1);
ExecutionContext context2 = new ExecutionContext();
XWikiContext xContext2 = new XWikiContext();
xContext2.setWikiId("wiki2");
context2.setProperty(XWikiContext.EXECUTIONCONTEXT_KEY, xContext2);
MemoryMailListener listener1 = this.mocker.getInstance(MailListener.class, "memory");
PrepareMailQueueItem item1 = new PrepareMailQueueItem(new Iterable<MimeMessage>() {
@Override
public Iterator<MimeMessage> iterator() {
return new Iterator<MimeMessage>() {
int index = 0;
@Override
public boolean hasNext() {
return true;
}
@Override
public MimeMessage next() {
if (index++ == 0) {
return message1;
}
throw new RuntimeException("Iterator failure");
}
@Override
public void remove() {
}
};
}
}, session, listener1, batchId1, context1);
MemoryMailListener listener2 = this.mocker.getInstance(MailListener.class, "memory");
PrepareMailQueueItem item2 = new PrepareMailQueueItem(Arrays.asList(message2), session, listener2, batchId2, context2);
MailQueueManager prepareMailQueueManager = this.mocker.getInstance(new DefaultParameterizedType(null, MailQueueManager.class, PrepareMailQueueItem.class));
MailQueueManager sendMailQueueManager = this.mocker.getInstance(new DefaultParameterizedType(null, MailQueueManager.class, SendMailQueueItem.class));
MailContentStore contentStore = this.mocker.getInstance(MailContentStore.class, "filesystem");
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Object[] args = invocationOnMock.getArguments();
MimeMessage message = (MimeMessage) args[1];
message.saveChanges();
return null;
}
}).when(contentStore).save(any(String.class), any(ExtendedMimeMessage.class));
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Object[] args = invocationOnMock.getArguments();
SendMailQueueItem item = (SendMailQueueItem) args[0];
((UpdateableMailStatusResult) item.getListener().getMailStatusResult()).incrementCurrentSize();
return null;
}
}).when(sendMailQueueManager).addToQueue(any(SendMailQueueItem.class));
// Prepare 2 mails. Both will fail but we want to verify that the second one is processed even though the first
// one failed.
prepareMailQueueManager.addToQueue(item1);
prepareMailQueueManager.addToQueue(item2);
MailRunnable runnable = this.mocker.getComponentUnderTest();
Thread thread = new Thread(runnable);
thread.start();
// Wait for the mails to have been processed.
try {
listener1.getMailStatusResult().waitTillProcessed(10000L);
listener2.getMailStatusResult().waitTillProcessed(10000L);
} finally {
runnable.stopProcessing();
thread.interrupt();
thread.join();
}
MailStatusResult result1 = listener1.getMailStatusResult();
MailStatusResult result2 = listener2.getMailStatusResult();
// Despite the errors, both process should be ended with known total number of mails
assertTrue(result1.isProcessed());
assertTrue(result2.isProcessed());
// This is the real test: we verify that there's been an error while sending each email.
assertNotNull(listener1.getMailStatusResult().getByState(MailState.PREPARE_SUCCESS).next());
assertNotNull(listener2.getMailStatusResult().getByState(MailState.PREPARE_SUCCESS).next());
assertFalse(listener1.getMailStatusResult().getByState(MailState.PREPARE_ERROR).hasNext());
assertFalse(listener2.getMailStatusResult().getByState(MailState.PREPARE_ERROR).hasNext());
assertEquals("Failure during preparation phase of thread [" + batchId1 + "]", logRule.getMessage(0));
}
Aggregations