This repository has been archived by the owner on Jan 18, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract the AsynchronousMailProcessService
- Loading branch information
Vitalii Samolovskikh
committed
Sep 28, 2013
1 parent
e2b85bf
commit 992c06a
Showing
6 changed files
with
174 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
grails-app/services/grails/plugin/asyncmail/AsynchronousMailProcessService.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package grails.plugin.asyncmail | ||
|
||
import org.springframework.mail.* | ||
import groovyx.gpars.GParsPool | ||
|
||
class AsynchronousMailProcessService { | ||
def grailsApplication | ||
|
||
def asynchronousMailPersistenceService | ||
def asynchronousMailSendService | ||
|
||
public void findAndSendEmails() { | ||
// Get messages from DB | ||
def messagesIds = asynchronousMailPersistenceService.selectMessagesIdsForSend() | ||
|
||
Integer gparsPoolSize = grailsApplication.config.asynchronous.mail.gparsPoolSize | ||
|
||
// Send each message and save new status | ||
try { | ||
GParsPool.withPool(gparsPoolSize) { | ||
messagesIds.eachParallel {Long messageId -> | ||
AsynchronousMailMessage.withNewSession { session -> | ||
processEmailMessage(messageId) | ||
} | ||
} | ||
} | ||
} catch (Exception e) { | ||
log.error('Abort mail sent.', e) | ||
} | ||
} | ||
|
||
void processEmailMessage(long messageId) { | ||
boolean useFlushOnSave = grailsApplication.config.asynchronous.mail.useFlushOnSave | ||
|
||
def message = asynchronousMailPersistenceService.getMessage(messageId) | ||
log.trace("Found a message: " + message.toString()) | ||
|
||
Date now = new Date() | ||
Date attemptDate = new Date(now.getTime() - message.attemptInterval) | ||
if ( | ||
message.status == MessageStatus.CREATED | ||
|| (message.status == MessageStatus.ATTEMPTED && message.lastAttemptDate.before(attemptDate)) | ||
) { | ||
message.lastAttemptDate = now | ||
message.attemptsCount++ | ||
|
||
// It guarantee that e-mail can't be sent more than 1 time | ||
message.status = MessageStatus.ERROR | ||
asynchronousMailPersistenceService.save(message, useFlushOnSave) | ||
|
||
// Attempt to send | ||
try { | ||
log.trace("Attempt to send the message with id=${message.id}.") | ||
asynchronousMailSendService.send(message) | ||
message.sentDate = now | ||
message.status = MessageStatus.SENT | ||
log.trace("The message with id=${message.id} was sent successfully.") | ||
} catch (MailException e) { | ||
log.warn("Attempt to send the message with id=${message.id} was failed.", e) | ||
if (message.attemptsCount < message.maxAttemptsCount && | ||
!(e instanceof MailParseException || e instanceof MailPreparationException) | ||
) { | ||
message.status = MessageStatus.ATTEMPTED | ||
} | ||
|
||
if (e instanceof MailAuthenticationException) { | ||
throw e | ||
} | ||
} finally { | ||
asynchronousMailPersistenceService.save(message, useFlushOnSave) | ||
} | ||
|
||
// Delete message if it is sent successfully and can be deleted | ||
if (message.status == MessageStatus.SENT && message.markDelete) { | ||
long id = message.id | ||
asynchronousMailPersistenceService.delete(message); | ||
log.trace("The message with id=${id} was deleted.") | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
test/unit/grails/plugin/asyncmail/AsynchronousMailProcessServiceTests.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package grails.plugin.asyncmail | ||
|
||
import grails.test.mixin.* | ||
import org.junit.* | ||
|
||
/** | ||
* See the API for {@link grails.test.mixin.services.ServiceUnitTestMixin} for usage instructions | ||
*/ | ||
@TestFor(AsynchronousMailProcessService) | ||
class AsynchronousMailProcessServiceTests { | ||
AsynchronousMailProcessService asynchronousMailProcessService | ||
def asynchronousMailPersistenceService | ||
|
||
@Before | ||
void init(){ | ||
asynchronousMailProcessService = new AsynchronousMailProcessService() | ||
asynchronousMailPersistenceService = new AsynchronousMailPersistenceServiceMock() | ||
asynchronousMailProcessService.asynchronousMailPersistenceService = asynchronousMailPersistenceService | ||
asynchronousMailProcessService.asynchronousMailSendService = new AsynchronousMailSendServiceMock() | ||
|
||
grailsApplication.config.asynchronous.mail.useFlushOnSave = true | ||
asynchronousMailProcessService.grailsApplication = grailsApplication | ||
} | ||
|
||
void testProcessEmailMessage() { | ||
def message = new AsynchronousMailMessage( | ||
from: 'John Smith <john@example.com>', | ||
to: ['Mary Smith <mary@example.com>'], | ||
subject: 'Subject', | ||
text: 'Text' | ||
) | ||
|
||
asynchronousMailPersistenceService.save(message) | ||
asynchronousMailProcessService.processEmailMessage(1) | ||
assert message.status == MessageStatus.SENT | ||
assert message.sentDate !=null | ||
} | ||
} | ||
|
||
class AsynchronousMailPersistenceServiceMock{ | ||
def message | ||
|
||
void save(message, boolean flush = true){ | ||
this.message = message | ||
} | ||
|
||
def getMessage(id){ | ||
return message | ||
} | ||
} | ||
|
||
class AsynchronousMailSendServiceMock{ | ||
void send(message){ | ||
// Nothing! | ||
} | ||
} |