| 1 | package fr.sii.ogham.email.sendgrid.v2.sender.impl; | |
| 2 | ||
| 3 | import static fr.sii.ogham.core.util.LogUtils.logString; | |
| 4 | import static fr.sii.ogham.email.sendgrid.SendGridConstants.DEFAULT_SENDGRID_IMPLEMENTATION_PRIORITY; | |
| 5 | import static fr.sii.ogham.email.sendgrid.sender.EmailValidator.validate; | |
| 6 | ||
| 7 | import java.io.IOException; | |
| 8 | import java.util.regex.Pattern; | |
| 9 | ||
| 10 | import org.slf4j.Logger; | |
| 11 | import org.slf4j.LoggerFactory; | |
| 12 | ||
| 13 | import com.sendgrid.SendGrid; | |
| 14 | import com.sendgrid.SendGridException; | |
| 15 | ||
| 16 | import fr.sii.ogham.core.builder.priority.Priority; | |
| 17 | import fr.sii.ogham.core.exception.MessageException; | |
| 18 | import fr.sii.ogham.core.sender.AbstractSpecializedSender; | |
| 19 | import fr.sii.ogham.email.attachment.Attachment; | |
| 20 | import fr.sii.ogham.email.exception.handler.ContentHandlerException; | |
| 21 | import fr.sii.ogham.email.message.Email; | |
| 22 | import fr.sii.ogham.email.message.EmailAddress; | |
| 23 | import fr.sii.ogham.email.message.Recipient; | |
| 24 | import fr.sii.ogham.email.sendgrid.sender.SendGridSender; | |
| 25 | import fr.sii.ogham.email.sendgrid.sender.exception.AttachmentReadException; | |
| 26 | import fr.sii.ogham.email.sendgrid.v2.sender.impl.sendgrid.client.SendGridClient; | |
| 27 | import fr.sii.ogham.email.sendgrid.v2.sender.impl.sendgrid.client.SendGridInterceptor; | |
| 28 | import fr.sii.ogham.email.sendgrid.v2.sender.impl.sendgrid.handler.SendGridContentHandler; | |
| 29 | ||
| 30 | /** | |
| 31 | * SendGrid-backed implementation of the email sender. | |
| 32 | */ | |
| 33 | @Priority(properties = "${ogham.email.implementation-priority.sendgrid}", defaultValue = DEFAULT_SENDGRID_IMPLEMENTATION_PRIORITY) | |
| 34 | public final class SendGridV2Sender extends AbstractSpecializedSender<Email> implements SendGridSender { | |
| 35 | private static final Logger LOG = LoggerFactory.getLogger(SendGridV2Sender.class); | |
| 36 | private static final Pattern CID = Pattern.compile("^<(.+)>$"); | |
| 37 | ||
| 38 | private final SendGridClient delegate; | |
| 39 | private final SendGridContentHandler handler; | |
| 40 | private final SendGridInterceptor interceptor; | |
| 41 | ||
| 42 | /** | |
| 43 | * Constructor. | |
| 44 | * | |
| 45 | * @param service | |
| 46 | * the underlying SendGrid service | |
| 47 | * @param handler | |
| 48 | * the content handler, in change of converting the email content | |
| 49 | * into something the {@link SendGridClient} can work with | |
| 50 | */ | |
| 51 | public SendGridV2Sender(final SendGridClient service, final SendGridContentHandler handler) { | |
| 52 | this(service, handler, null); | |
| 53 | } | |
| 54 | ||
| 55 | /** | |
| 56 | * Constructor. | |
| 57 | * | |
| 58 | * @param service | |
| 59 | * the underlying SendGrid service | |
| 60 | * @param handler | |
| 61 | * the content handler, in change of converting the email content | |
| 62 | * into something the {@link SendGridClient} can work with | |
| 63 | * @param interceptor | |
| 64 | * an extension point for customizing the email to send | |
| 65 | */ | |
| 66 | public SendGridV2Sender(final SendGridClient service, final SendGridContentHandler handler, SendGridInterceptor interceptor) { | |
| 67 |
3
1. <init> : negated conditional → NO_COVERAGE 2. <init> : negated conditional → KILLED 3. <init> : negated conditional → KILLED |
if (service == null) { |
| 68 | throw new IllegalArgumentException("[service] cannot be null"); | |
| 69 | } | |
| 70 |
3
1. <init> : negated conditional → NO_COVERAGE 2. <init> : negated conditional → KILLED 3. <init> : negated conditional → KILLED |
if (handler == null) { |
| 71 | throw new IllegalArgumentException("[handler] cannot be null"); | |
| 72 | } | |
| 73 | ||
| 74 | this.delegate = service; | |
| 75 | this.handler = handler; | |
| 76 | this.interceptor = interceptor; | |
| 77 | } | |
| 78 | ||
| 79 | @Override | |
| 80 | public void send(final Email message) throws MessageException { | |
| 81 |
2
1. send : negated conditional → NO_COVERAGE 2. send : negated conditional → KILLED |
if (message == null) { |
| 82 | throw new IllegalArgumentException("[message] cannot be null"); | |
| 83 | } | |
| 84 |
2
1. send : removed call to fr/sii/ogham/email/sendgrid/sender/EmailValidator::validate → NO_COVERAGE 2. send : removed call to fr/sii/ogham/email/sendgrid/sender/EmailValidator::validate → KILLED |
validate(message); |
| 85 | ||
| 86 | try { | |
| 87 | LOG.debug("Preparing to send email using SendGrid: {}", logString(message)); | |
| 88 | final SendGrid.Email sgEmail = intercept(toSendGridEmail(message), message); | |
| 89 | ||
| 90 | LOG.debug("Sending email...\n{}", logString(message)); | |
| 91 | LOG.trace("SendGrid email: {}", sgEmail); | |
| 92 |
2
1. send : removed call to fr/sii/ogham/email/sendgrid/v2/sender/impl/sendgrid/client/SendGridClient::send → NO_COVERAGE 2. send : removed call to fr/sii/ogham/email/sendgrid/v2/sender/impl/sendgrid/client/SendGridClient::send → KILLED |
delegate.send(sgEmail); |
| 93 | LOG.debug("Email has been successfully sent"); | |
| 94 | } catch (ContentHandlerException e) { | |
| 95 | throw new MessageException("A content-related error occurred when trying to build an email", message, e); | |
| 96 | } catch (AttachmentReadException e) { | |
| 97 | throw new MessageException("Attaching file to email failed when trying to send an email", message, e); | |
| 98 | } catch (SendGridException e) { | |
| 99 | throw new MessageException("A SendGrid-related error occurred when trying to send an email", message, e); | |
| 100 | } | |
| 101 | } | |
| 102 | ||
| 103 | private SendGrid.Email intercept(SendGrid.Email sendGridEmail, Email source) { | |
| 104 |
2
1. intercept : negated conditional → NO_COVERAGE 2. intercept : negated conditional → KILLED |
if (interceptor == null) { |
| 105 |
2
1. intercept : replaced return value with null for fr/sii/ogham/email/sendgrid/v2/sender/impl/SendGridV2Sender::intercept → NO_COVERAGE 2. intercept : replaced return value with null for fr/sii/ogham/email/sendgrid/v2/sender/impl/SendGridV2Sender::intercept → KILLED |
return sendGridEmail; |
| 106 | } | |
| 107 |
1
1. intercept : replaced return value with null for fr/sii/ogham/email/sendgrid/v2/sender/impl/SendGridV2Sender::intercept → NO_COVERAGE |
return interceptor.intercept(sendGridEmail, source); |
| 108 | } | |
| 109 | ||
| 110 | private SendGrid.Email toSendGridEmail(final Email message) throws ContentHandlerException, AttachmentReadException { | |
| 111 | final SendGrid.Email ret = new SendGrid.Email(); | |
| 112 | ret.setSubject(message.getSubject()); | |
| 113 | ||
| 114 | ret.setFrom(message.getFrom().getAddress()); | |
| 115 |
2
1. toSendGridEmail : negated conditional → NO_COVERAGE 2. toSendGridEmail : negated conditional → KILLED |
ret.setFromName(message.getFrom().getPersonal() == null ? "" : message.getFrom().getPersonal()); |
| 116 | ||
| 117 | final String[] tos = new String[message.getRecipients().size()]; | |
| 118 | final String[] toNames = new String[message.getRecipients().size()]; | |
| 119 | int i = 0; | |
| 120 | for (Recipient recipient : message.getRecipients()) { | |
| 121 | final EmailAddress address = recipient.getAddress(); | |
| 122 | tos[i] = address.getAddress(); | |
| 123 |
2
1. toSendGridEmail : negated conditional → NO_COVERAGE 2. toSendGridEmail : negated conditional → KILLED |
toNames[i] = address.getPersonal() == null ? "" : address.getPersonal(); |
| 124 |
2
1. toSendGridEmail : Changed increment from 1 to -1 → NO_COVERAGE 2. toSendGridEmail : Changed increment from 1 to -1 → KILLED |
i++; |
| 125 | } | |
| 126 | ret.setTo(tos); | |
| 127 | ret.setToName(toNames); | |
| 128 | ||
| 129 |
2
1. toSendGridEmail : removed call to fr/sii/ogham/email/sendgrid/v2/sender/impl/sendgrid/handler/SendGridContentHandler::setContent → NO_COVERAGE 2. toSendGridEmail : removed call to fr/sii/ogham/email/sendgrid/v2/sender/impl/sendgrid/handler/SendGridContentHandler::setContent → KILLED |
handler.setContent(message, ret, message.getContent()); |
| 130 | ||
| 131 | for (Attachment attachment : message.getAttachments()) { | |
| 132 |
2
1. toSendGridEmail : removed call to fr/sii/ogham/email/sendgrid/v2/sender/impl/SendGridV2Sender::addAttachment → NO_COVERAGE 2. toSendGridEmail : removed call to fr/sii/ogham/email/sendgrid/v2/sender/impl/SendGridV2Sender::addAttachment → KILLED |
addAttachment(ret, attachment); |
| 133 | } | |
| 134 | ||
| 135 |
2
1. toSendGridEmail : replaced return value with null for fr/sii/ogham/email/sendgrid/v2/sender/impl/SendGridV2Sender::toSendGridEmail → NO_COVERAGE 2. toSendGridEmail : replaced return value with null for fr/sii/ogham/email/sendgrid/v2/sender/impl/SendGridV2Sender::toSendGridEmail → KILLED |
return ret; |
| 136 | } | |
| 137 | ||
| 138 | private static void addAttachment(final SendGrid.Email ret, final Attachment attachment) throws AttachmentReadException { | |
| 139 | try { | |
| 140 | ret.addAttachment(attachment.getResource().getName(), attachment.getResource().getInputStream()); | |
| 141 | // TODO: how to set Content-Type per attachment with SendGrid v2 API ? | |
| 142 |
2
1. addAttachment : negated conditional → NO_COVERAGE 2. addAttachment : negated conditional → KILLED |
if (attachment.getContentId() != null) { |
| 143 | String id = CID.matcher(attachment.getContentId()).replaceAll("$1"); | |
| 144 | ret.addContentId(attachment.getResource().getName(), id); | |
| 145 | } | |
| 146 | } catch (IOException e) { | |
| 147 | throw new AttachmentReadException("Failed to attach email attachment named " + attachment.getResource().getName(), attachment, e); | |
| 148 | } | |
| 149 | } | |
| 150 | ||
| 151 | public SendGridClient getDelegate() { | |
| 152 |
1
1. getDelegate : replaced return value with null for fr/sii/ogham/email/sendgrid/v2/sender/impl/SendGridV2Sender::getDelegate → NO_COVERAGE |
return delegate; |
| 153 | } | |
| 154 | ||
| 155 | } | |
Mutations | ||
| 67 |
1.1 2.2 3.3 |
|
| 70 |
1.1 2.2 3.3 |
|
| 81 |
1.1 2.2 |
|
| 84 |
1.1 2.2 |
|
| 92 |
1.1 2.2 |
|
| 104 |
1.1 2.2 |
|
| 105 |
1.1 2.2 |
|
| 107 |
1.1 |
|
| 115 |
1.1 2.2 |
|
| 123 |
1.1 2.2 |
|
| 124 |
1.1 2.2 |
|
| 129 |
1.1 2.2 |
|
| 132 |
1.1 2.2 |
|
| 135 |
1.1 2.2 |
|
| 142 |
1.1 2.2 |
|
| 152 |
1.1 |