1
16
17 package org.springframework.cloud.aws.mail.simplemail;
18
19 import java.io.ByteArrayOutputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.lang.reflect.Constructor;
23 import java.nio.ByteBuffer;
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.Properties;
27
28 import javax.activation.FileTypeMap;
29 import javax.mail.MessagingException;
30 import javax.mail.Session;
31 import javax.mail.internet.MimeMessage;
32
33 import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
34 import com.amazonaws.services.simpleemail.model.RawMessage;
35 import com.amazonaws.services.simpleemail.model.SendRawEmailRequest;
36 import com.amazonaws.services.simpleemail.model.SendRawEmailResult;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import org.springframework.beans.BeanUtils;
41 import org.springframework.mail.MailException;
42 import org.springframework.mail.MailParseException;
43 import org.springframework.mail.MailPreparationException;
44 import org.springframework.mail.MailSendException;
45 import org.springframework.mail.javamail.ConfigurableMimeFileTypeMap;
46 import org.springframework.mail.javamail.JavaMailSender;
47 import org.springframework.mail.javamail.MimeMessageHelper;
48 import org.springframework.mail.javamail.MimeMessagePreparator;
49 import org.springframework.util.Assert;
50 import org.springframework.util.ClassUtils;
51
52
60 public class SimpleEmailServiceJavaMailSender extends SimpleEmailServiceMailSender
61 implements JavaMailSender {
62
63 private static final Logger LOGGER = LoggerFactory
64 .getLogger(SimpleEmailServiceMailSender.class);
65
66 private static final String SMART_MIME_MESSAGE_CLASS_NAME = "org.springframework.mail.javamail.SmartMimeMessage";
67
68 private Properties javaMailProperties = new Properties();
69
70 private volatile Session session;
71
72 private String defaultEncoding;
73
74 private FileTypeMap defaultFileTypeMap;
75
76 public SimpleEmailServiceJavaMailSender(
77 AmazonSimpleEmailService amazonSimpleEmailService) {
78 super(amazonSimpleEmailService);
79 }
80
81
89 protected Properties getJavaMailProperties() {
90 return this.javaMailProperties;
91 }
92
93
101 public void setJavaMailProperties(Properties javaMailProperties) {
102 this.javaMailProperties = javaMailProperties;
103 this.session = null;
104 }
105
106
111 protected Session getSession() {
112 if (this.session == null) {
113 this.session = Session.getInstance(getJavaMailProperties());
114 }
115 return this.session;
116 }
117
118
129 public void setSession(Session session) {
130 Assert.notNull(session, "Session must not be null");
131 this.session = session;
132 }
133
134
141 public void setDefaultEncoding(String defaultEncoding) {
142 this.defaultEncoding = defaultEncoding;
143 }
144
145
161 public void setDefaultFileTypeMap(FileTypeMap defaultFileTypeMap) {
162 this.defaultFileTypeMap = defaultFileTypeMap;
163 }
164
165 @Override
166 public MimeMessage createMimeMessage() {
167
168
169 if (ClassUtils.isPresent(SMART_MIME_MESSAGE_CLASS_NAME,
170 ClassUtils.getDefaultClassLoader())) {
171 Class<?> smartMimeMessage = ClassUtils.resolveClassName(
172 SMART_MIME_MESSAGE_CLASS_NAME, ClassUtils.getDefaultClassLoader());
173 Constructor<?> constructor = ClassUtils.getConstructorIfAvailable(
174 smartMimeMessage, Session.class, String.class, FileTypeMap.class);
175 if (constructor != null) {
176 Object mimeMessage = BeanUtils.instantiateClass(constructor, getSession(),
177 this.defaultEncoding, this.defaultFileTypeMap);
178 return (MimeMessage) mimeMessage;
179 }
180 }
181
182 return new MimeMessage(getSession());
183 }
184
185 @Override
186 public MimeMessage createMimeMessage(InputStream contentStream) throws MailException {
187 try {
188 return new MimeMessage(getSession(), contentStream);
189 }
190 catch (MessagingException e) {
191 throw new MailParseException("Could not parse raw MIME content", e);
192 }
193 }
194
195 @Override
196 public void send(MimeMessage mimeMessage) throws MailException {
197 this.send(new MimeMessage[] { mimeMessage });
198 }
199
200 @SuppressWarnings("OverloadedVarargsMethod")
201 @Override
202 public void send(MimeMessage... mimeMessages) throws MailException {
203 Map<Object, Exception> failedMessages = new HashMap<>();
204
205 for (MimeMessage mimeMessage : mimeMessages) {
206 try {
207 RawMessage rm = createRawMessage(mimeMessage);
208 SendRawEmailResult sendRawEmailResult = getEmailService()
209 .sendRawEmail(new SendRawEmailRequest(rm));
210 if (LOGGER.isDebugEnabled()) {
211 LOGGER.debug("Message with id: {} successfully send",
212 sendRawEmailResult.getMessageId());
213 }
214 mimeMessage.setHeader("Message-ID", sendRawEmailResult.getMessageId());
215 }
216 catch (Exception e) {
217
218
219 failedMessages.put(mimeMessage, e);
220 }
221 }
222
223 if (!failedMessages.isEmpty()) {
224 throw new MailSendException(failedMessages);
225 }
226 }
227
228 @Override
229 public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException {
230 send(new MimeMessagePreparator[] { mimeMessagePreparator });
231 }
232
233 @SuppressWarnings("OverloadedVarargsMethod")
234 @Override
235 public void send(MimeMessagePreparator... mimeMessagePreparators)
236 throws MailException {
237 MimeMessage mimeMessage = createMimeMessage();
238 for (MimeMessagePreparator mimeMessagePreparator : mimeMessagePreparators) {
239 try {
240 mimeMessagePreparator.prepare(mimeMessage);
241 }
242 catch (Exception e) {
243 throw new MailPreparationException(e);
244 }
245 }
246 send(mimeMessage);
247 }
248
249 private RawMessage createRawMessage(MimeMessage mimeMessage) {
250 ByteArrayOutputStream out;
251 try {
252 out = new ByteArrayOutputStream();
253 mimeMessage.writeTo(out);
254 }
255 catch (IOException e) {
256 throw new MailPreparationException(e);
257 }
258 catch (MessagingException e) {
259 throw new MailParseException(e);
260 }
261 return new RawMessage(ByteBuffer.wrap(out.toByteArray()));
262 }
263
264 }
265