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 |