Skip to content

Commit 2295fb8

Browse files
committed
feat: improved attachment handling to lower memory consumption
1 parent b468a0d commit 2295fb8

File tree

7 files changed

+375
-30
lines changed

7 files changed

+375
-30
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ SOFTWARE.
8181
<maven.compiler.target>1.8</maven.compiler.target>
8282
<maven.javadoc.failOnError>false</maven.javadoc.failOnError>
8383

84-
<spring-boot.version>2.3.1.RELEASE</spring-boot.version>
84+
<spring-boot.version>2.3.6.RELEASE</spring-boot.version>
8585
</properties>
8686

8787

src/main/java/io/rocketbase/mail/PostmarkClient.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
package io.rocketbase.mail;
22

33
import io.rocketbase.mail.config.PostmarkProperties;
4+
import io.rocketbase.mail.dto.EmailAttachment;
45
import io.rocketbase.mail.dto.Message;
56
import io.rocketbase.mail.dto.MessageResponse;
7+
import io.rocketbase.mail.util.MessageJsonWriter;
68
import lombok.RequiredArgsConstructor;
79
import org.springframework.core.ParameterizedTypeReference;
10+
import org.springframework.core.io.FileSystemResource;
811
import org.springframework.http.HttpEntity;
912
import org.springframework.http.HttpHeaders;
1013
import org.springframework.http.HttpMethod;
1114
import org.springframework.http.ResponseEntity;
1215
import org.springframework.web.client.RestTemplate;
1316
import org.springframework.web.util.UriComponentsBuilder;
1417

18+
import java.io.File;
1519
import java.util.List;
1620

1721
@RequiredArgsConstructor
@@ -29,15 +33,35 @@ protected RestTemplate getRestTemplate() {
2933
}
3034

3135
public MessageResponse deliverMessage(Message msg) {
32-
ResponseEntity<MessageResponse> response = getRestTemplate().exchange(createUriBuilder().path("/email/").toUriString(),
36+
ResponseEntity<MessageResponse> response = getRestTemplate().exchange(createUriBuilder().path("/email/")
37+
.toUriString(),
3338
HttpMethod.POST,
3439
new HttpEntity<>(msg, buildHeaders()),
3540
MessageResponse.class);
3641
return response.getBody();
3742
}
3843

44+
public MessageResponse deliverMessage(Message msg, EmailAttachment... emailAttachments) {
45+
ResponseEntity<MessageResponse> response = null;
46+
File json = null;
47+
try {
48+
json = new MessageJsonWriter().writeMessageFile(msg, emailAttachments);
49+
response = getRestTemplate().exchange(createUriBuilder().path("/email/")
50+
.toUriString(),
51+
HttpMethod.POST,
52+
new HttpEntity<>(new FileSystemResource(json), buildHeaders()),
53+
MessageResponse.class);
54+
} finally {
55+
if (json != null) {
56+
json.delete();
57+
}
58+
}
59+
return response.getBody();
60+
}
61+
3962
public List<MessageResponse> deliverMessage(List<Message> messages) {
40-
ResponseEntity<List<MessageResponse>> response = getRestTemplate().exchange(createUriBuilder().path("/email/batch").toUriString(),
63+
ResponseEntity<List<MessageResponse>> response = getRestTemplate().exchange(createUriBuilder().path("/email/batch")
64+
.toUriString(),
4165
HttpMethod.POST,
4266
new HttpEntity<>(messages, buildHeaders()),
4367
new ParameterizedTypeReference<List<MessageResponse>>() {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.rocketbase.mail.dto;
2+
3+
import lombok.Data;
4+
import lombok.RequiredArgsConstructor;
5+
import org.springframework.lang.Nullable;
6+
7+
import java.io.File;
8+
9+
@Data
10+
@RequiredArgsConstructor
11+
public class EmailAttachment {
12+
13+
private final String name;
14+
15+
private final File file;
16+
17+
@Nullable
18+
private String contentId;
19+
20+
public EmailAttachment withContentId(String contentId) {
21+
setContentId(contentId);
22+
return this;
23+
}
24+
}

src/main/java/io/rocketbase/mail/dto/Message.java

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package io.rocketbase.mail.dto;
22

3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.fasterxml.jackson.annotation.JsonSetter;
36
import lombok.*;
47

58
import java.io.File;
@@ -15,36 +18,72 @@
1518
public class Message {
1619

1720
private String messageStream;
21+
1822
private String from;
23+
1924
private String to;
25+
2026
private String cc;
27+
2128
private String bcc;
29+
2230
private String replyTo;
31+
2332
private String subject;
33+
2434
private String htmlBody;
35+
2536
private String textBody;
37+
2638
private String tag;
39+
2740
private List<Header> headers;
41+
42+
@Deprecated
2843
private List<Map<String, String>> attachments;
2944

3045
private Boolean trackOpens;
46+
3147
private TrackLinksType trackLinks;
48+
3249
private Map<String, String> metadata;
3350

51+
3452
public Message(String from, String to, String subject, String htmlBody, String textBody) {
35-
this.from = from;
36-
this.to = to;
53+
setFrom(from);
54+
setTo(to);
3755
this.subject = subject;
3856
this.htmlBody = htmlBody;
3957
this.textBody = textBody;
4058
}
4159

4260
public Message(EmailAddress from, EmailAddress to, String subject, String htmlBody, String textBody) {
43-
this.from = from.toRecipient();
44-
this.to = to.toRecipient();
61+
setFrom(from);
62+
setTo(to);
63+
this.subject = subject;
64+
this.htmlBody = htmlBody;
65+
this.textBody = textBody;
66+
}
67+
68+
@JsonCreator
69+
public Message(@JsonProperty("from") String from,
70+
@JsonProperty("to") String to,
71+
@JsonProperty("subject") String subject,
72+
@JsonProperty("htmlBody") String htmlBody,
73+
@JsonProperty("textBody") String textBody,
74+
@JsonProperty("cc") String cc,
75+
@JsonProperty("bcc") String bcc) {
76+
setFrom(from);
77+
setTo(to);
4578
this.subject = subject;
4679
this.htmlBody = htmlBody;
4780
this.textBody = textBody;
81+
setCc(cc);
82+
setBcc(bcc);
83+
}
84+
85+
public void setFrom(String from) {
86+
this.from = from;
4887
}
4988

5089
public void setFrom(EmailAddress from) {
@@ -63,6 +102,11 @@ public void setTo(String... to) {
63102
this.to = emailList(to);
64103
}
65104

105+
@JsonSetter
106+
public void setTo(String to) {
107+
this.to = to;
108+
}
109+
66110
public void setCc(EmailAddress cc) {
67111
this.cc = cc != null ? cc.toRecipient() : null;
68112
}
@@ -75,6 +119,11 @@ public void setCc(String... cc) {
75119
this.cc = emailList(cc);
76120
}
77121

122+
@JsonSetter
123+
public void setCc(String cc) {
124+
this.cc = cc;
125+
}
126+
78127
public void setBcc(EmailAddress bcc) {
79128
this.bcc = bcc != null ? bcc.toRecipient() : null;
80129
}
@@ -83,26 +132,40 @@ public void setBcc(List<EmailAddress> bcc) {
83132
this.bcc = emailAddressList(bcc);
84133
}
85134

135+
public void setBcc(EmailAddress... bcc) {
136+
this.bcc = emailList(bcc);
137+
}
138+
86139
public void setBcc(String... bcc) {
87140
this.bcc = emailList(bcc);
88141
}
89142

143+
@JsonSetter
144+
public void setBcc(String bcc) {
145+
this.bcc = bcc;
146+
}
147+
148+
@Deprecated
90149
public void addAttachment(String path) {
91150
this.addAttachment((new File(path)).getName(), readFileContent(path), readFileContentType(path));
92151
}
93152

153+
@Deprecated
94154
public void addAttachment(String path, String contentId) {
95155
this.addAttachment((new File(path)).getName(), readFileContent(path), readFileContentType(path), contentId);
96156
}
97157

158+
@Deprecated
98159
public void addAttachment(String filename, String content, String contentType, String contentId) {
99160
this.addAttachment(filename, content.getBytes(), contentType, contentId);
100161
}
101162

163+
@Deprecated
102164
public void addAttachment(String filename, String content, String contentType) {
103165
this.addAttachment(filename, content.getBytes(), contentType);
104166
}
105167

168+
@Deprecated
106169
public void addAttachment(String name, byte[] content, String contentType) {
107170
Map<String, String> attachment = new HashMap();
108171
attachment.put("Name", name);
@@ -111,15 +174,17 @@ public void addAttachment(String name, byte[] content, String contentType) {
111174
this.addAttachment((Map) attachment);
112175
}
113176

177+
@Deprecated
114178
public void addAttachment(String name, byte[] content, String contentType, String contentId) {
115179
Map<String, String> attachment = new HashMap();
116180
attachment.put("Name", name);
117181
attachment.put("Content", Base64.getEncoder().encodeToString(content));
118182
attachment.put("ContentType", contentType);
119183
attachment.put("ContentId", contentId);
120-
this.addAttachment((Map) attachment);
184+
this.addAttachment(attachment);
121185
}
122186

187+
@Deprecated
123188
public void addAttachment(Map<String, String> attachment) {
124189
if (this.attachments == null) {
125190
this.attachments = new ArrayList();
@@ -128,6 +193,7 @@ public void addAttachment(Map<String, String> attachment) {
128193
this.attachments.add(attachment);
129194
}
130195

196+
@Deprecated
131197
public void addAttachments(List<Map<String, String>> attachments) {
132198
attachments.forEach(this::addAttachment);
133199
}
@@ -146,13 +212,28 @@ protected String emailAddressList(List<EmailAddress> addresses) {
146212
if (addresses == null || addresses.isEmpty()) {
147213
return null;
148214
}
149-
return addresses.stream().map(EmailAddress::toRecipient).collect(Collectors.joining(","));
215+
return addresses.stream()
216+
.map(EmailAddress::toRecipient)
217+
.collect(Collectors.joining(","));
150218
}
151219

152220
protected String emailList(String... addresses) {
153221
if (addresses == null || addresses.length == 0) {
154222
return null;
155223
}
156-
return Arrays.asList(addresses).stream().map(e -> new EmailAddress(e).toRecipient()).collect(Collectors.joining(","));
224+
return Arrays.asList(addresses)
225+
.stream()
226+
.map(e -> new EmailAddress(e).toRecipient())
227+
.collect(Collectors.joining(","));
228+
}
229+
230+
protected String emailList(EmailAddress... addresses) {
231+
if (addresses == null || addresses.length == 0) {
232+
return null;
233+
}
234+
return Arrays.asList(addresses)
235+
.stream()
236+
.map(EmailAddress::toRecipient)
237+
.collect(Collectors.joining(","));
157238
}
158239
}

0 commit comments

Comments
 (0)