Commit 6f67e72afda431f445b98746cf5b1cc9c66c5ba0

Authored by Andrii Shvaika
1 parent 3dd85167

Refactoring of MailService

@@ -31,6 +31,7 @@ import org.springframework.mail.javamail.MimeMessageHelper; @@ -31,6 +31,7 @@ import org.springframework.mail.javamail.MimeMessageHelper;
31 import org.springframework.stereotype.Service; 31 import org.springframework.stereotype.Service;
32 import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; 32 import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
33 import org.thingsboard.rule.engine.api.MailService; 33 import org.thingsboard.rule.engine.api.MailService;
  34 +import org.thingsboard.rule.engine.api.TbEmail;
34 import org.thingsboard.server.common.data.AdminSettings; 35 import org.thingsboard.server.common.data.AdminSettings;
35 import org.thingsboard.server.common.data.ApiFeature; 36 import org.thingsboard.server.common.data.ApiFeature;
36 import org.thingsboard.server.common.data.ApiUsageRecordKey; 37 import org.thingsboard.server.common.data.ApiUsageRecordKey;
@@ -250,35 +251,35 @@ public class DefaultMailService implements MailService { @@ -250,35 +251,35 @@ public class DefaultMailService implements MailService {
250 } 251 }
251 252
252 @Override 253 @Override
253 - public void send(TenantId tenantId, CustomerId customerId, String from, String to, String cc, String bcc, String subject, String body, boolean isHtml, Map<String, String> images) throws ThingsboardException {  
254 - sendMail(tenantId, customerId, from, to, cc, bcc, subject, body, isHtml, images, this.mailSender); 254 + public void send(TenantId tenantId, CustomerId customerId, TbEmail tbEmail) throws ThingsboardException {
  255 + sendMail(tenantId, customerId, tbEmail, this.mailSender);
255 } 256 }
256 257
257 @Override 258 @Override
258 - public void send(TenantId tenantId, CustomerId customerId, String from, String to, String cc, String bcc, String subject, String body, boolean isHtml, Map<String, String> images, JavaMailSender javaMailSender) throws ThingsboardException {  
259 - sendMail(tenantId, customerId, from, to, cc, bcc, subject, body, isHtml, images, javaMailSender); 259 + public void send(TenantId tenantId, CustomerId customerId, TbEmail tbEmail, JavaMailSender javaMailSender) throws ThingsboardException {
  260 + sendMail(tenantId, customerId, tbEmail, javaMailSender);
260 } 261 }
261 262
262 - private void sendMail(TenantId tenantId, CustomerId customerId, String from, String to, String cc, String bcc, String subject, String body, boolean isHtml, Map<String, String> images, JavaMailSender javaMailSender) throws ThingsboardException { 263 + private void sendMail(TenantId tenantId, CustomerId customerId, TbEmail tbEmail, JavaMailSender javaMailSender) throws ThingsboardException {
263 if (apiUsageStateService.getApiUsageState(tenantId).isEmailSendEnabled()) { 264 if (apiUsageStateService.getApiUsageState(tenantId).isEmailSendEnabled()) {
264 try { 265 try {
265 MimeMessage mailMsg = javaMailSender.createMimeMessage(); 266 MimeMessage mailMsg = javaMailSender.createMimeMessage();
266 - boolean multipart = (images != null && !images.isEmpty()); 267 + boolean multipart = (tbEmail.getImages() != null && !tbEmail.getImages().isEmpty());
267 MimeMessageHelper helper = new MimeMessageHelper(mailMsg, multipart, "UTF-8"); 268 MimeMessageHelper helper = new MimeMessageHelper(mailMsg, multipart, "UTF-8");
268 - helper.setFrom(StringUtils.isBlank(from) ? mailFrom : from);  
269 - helper.setTo(to.split("\\s*,\\s*"));  
270 - if (!StringUtils.isBlank(cc)) {  
271 - helper.setCc(cc.split("\\s*,\\s*")); 269 + helper.setFrom(StringUtils.isBlank(tbEmail.getFrom()) ? mailFrom : tbEmail.getFrom());
  270 + helper.setTo(tbEmail.getTo().split("\\s*,\\s*"));
  271 + if (!StringUtils.isBlank(tbEmail.getCc())) {
  272 + helper.setCc(tbEmail.getCc().split("\\s*,\\s*"));
272 } 273 }
273 - if (!StringUtils.isBlank(bcc)) {  
274 - helper.setBcc(bcc.split("\\s*,\\s*")); 274 + if (!StringUtils.isBlank(tbEmail.getBcc())) {
  275 + helper.setBcc(tbEmail.getBcc().split("\\s*,\\s*"));
275 } 276 }
276 - helper.setSubject(subject);  
277 - helper.setText(body, isHtml); 277 + helper.setSubject(tbEmail.getSubject());
  278 + helper.setText(tbEmail.getBody(), tbEmail.isHtml());
278 279
279 if (multipart) { 280 if (multipart) {
280 - for (String imgId : images.keySet()) {  
281 - String imgValue = images.get(imgId); 281 + for (String imgId : tbEmail.getImages().keySet()) {
  282 + String imgValue = tbEmail.getImages().get(imgId);
282 String value = imgValue.replaceFirst("^data:image/[^;]*;base64,?", ""); 283 String value = imgValue.replaceFirst("^data:image/[^;]*;base64,?", "");
283 byte[] bytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(value); 284 byte[] bytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(value);
284 String contentType = helper.getFileTypeMap().getContentType(imgId); 285 String contentType = helper.getFileTypeMap().getContentType(imgId);
@@ -46,9 +46,9 @@ public interface MailService { @@ -46,9 +46,9 @@ public interface MailService {
46 46
47 void sendAccountLockoutEmail(String lockoutEmail, String email, Integer maxFailedLoginAttempts) throws ThingsboardException; 47 void sendAccountLockoutEmail(String lockoutEmail, String email, Integer maxFailedLoginAttempts) throws ThingsboardException;
48 48
49 - void send(TenantId tenantId, CustomerId customerId, String from, String to, String cc, String bcc, String subject, String body, boolean isHtml, Map<String, String> images) throws ThingsboardException; 49 + void send(TenantId tenantId, CustomerId customerId, TbEmail tbEmail) throws ThingsboardException;
50 50
51 - void send(TenantId tenantId, CustomerId customerId, String from, String to, String cc, String bcc, String subject, String body, boolean isHtml, Map<String, String> images, JavaMailSender javaMailSender) throws ThingsboardException; 51 + void send(TenantId tenantId, CustomerId customerId, TbEmail tbEmail, JavaMailSender javaMailSender) throws ThingsboardException;
52 52
53 void sendApiFeatureStateEmail(ApiFeature apiFeature, ApiUsageStateValue stateValue, String email, ApiUsageStateMailMessage msg) throws ThingsboardException; 53 void sendApiFeatureStateEmail(ApiFeature apiFeature, ApiUsageStateValue stateValue, String email, ApiUsageStateMailMessage msg) throws ThingsboardException;
54 54
rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbEmail.java renamed from rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mail/EmailPojo.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.rule.engine.mail; 16 +package org.thingsboard.rule.engine.api;
17 17
18 import lombok.Builder; 18 import lombok.Builder;
19 import lombok.Data; 19 import lombok.Data;
@@ -22,7 +22,7 @@ import java.util.Map; @@ -22,7 +22,7 @@ import java.util.Map;
22 22
23 @Data 23 @Data
24 @Builder 24 @Builder
25 -class EmailPojo { 25 +public class TbEmail {
26 26
27 private final String from; 27 private final String from;
28 private final String to; 28 private final String to;
@@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j; @@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j;
22 import org.springframework.util.StringUtils; 22 import org.springframework.util.StringUtils;
23 import org.thingsboard.rule.engine.api.RuleNode; 23 import org.thingsboard.rule.engine.api.RuleNode;
24 import org.thingsboard.rule.engine.api.TbContext; 24 import org.thingsboard.rule.engine.api.TbContext;
  25 +import org.thingsboard.rule.engine.api.TbEmail;
25 import org.thingsboard.rule.engine.api.TbNode; 26 import org.thingsboard.rule.engine.api.TbNode;
26 import org.thingsboard.rule.engine.api.TbNodeConfiguration; 27 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
27 import org.thingsboard.rule.engine.api.TbNodeException; 28 import org.thingsboard.rule.engine.api.TbNodeException;
@@ -65,7 +66,7 @@ public class TbMsgToEmailNode implements TbNode { @@ -65,7 +66,7 @@ public class TbMsgToEmailNode implements TbNode {
65 @Override 66 @Override
66 public void onMsg(TbContext ctx, TbMsg msg) { 67 public void onMsg(TbContext ctx, TbMsg msg) {
67 try { 68 try {
68 - EmailPojo email = convert(msg); 69 + TbEmail email = convert(msg);
69 TbMsg emailMsg = buildEmailMsg(ctx, msg, email); 70 TbMsg emailMsg = buildEmailMsg(ctx, msg, email);
70 ctx.tellNext(emailMsg, SUCCESS); 71 ctx.tellNext(emailMsg, SUCCESS);
71 } catch (Exception ex) { 72 } catch (Exception ex) {
@@ -74,13 +75,13 @@ public class TbMsgToEmailNode implements TbNode { @@ -74,13 +75,13 @@ public class TbMsgToEmailNode implements TbNode {
74 } 75 }
75 } 76 }
76 77
77 - private TbMsg buildEmailMsg(TbContext ctx, TbMsg msg, EmailPojo email) throws JsonProcessingException { 78 + private TbMsg buildEmailMsg(TbContext ctx, TbMsg msg, TbEmail email) throws JsonProcessingException {
78 String emailJson = MAPPER.writeValueAsString(email); 79 String emailJson = MAPPER.writeValueAsString(email);
79 return ctx.transformMsg(msg, SEND_EMAIL_TYPE, msg.getOriginator(), msg.getMetaData().copy(), emailJson); 80 return ctx.transformMsg(msg, SEND_EMAIL_TYPE, msg.getOriginator(), msg.getMetaData().copy(), emailJson);
80 } 81 }
81 82
82 - private EmailPojo convert(TbMsg msg) throws IOException {  
83 - EmailPojo.EmailPojoBuilder builder = EmailPojo.builder(); 83 + private TbEmail convert(TbMsg msg) throws IOException {
  84 + TbEmail.TbEmailBuilder builder = TbEmail.builder();
84 builder.from(fromTemplate(this.config.getFromTemplate(), msg)); 85 builder.from(fromTemplate(this.config.getFromTemplate(), msg));
85 builder.to(fromTemplate(this.config.getToTemplate(), msg)); 86 builder.to(fromTemplate(this.config.getToTemplate(), msg));
86 builder.cc(fromTemplate(this.config.getCcTemplate(), msg)); 87 builder.cc(fromTemplate(this.config.getCcTemplate(), msg));
@@ -21,6 +21,7 @@ import org.apache.commons.lang3.StringUtils; @@ -21,6 +21,7 @@ import org.apache.commons.lang3.StringUtils;
21 import org.springframework.mail.javamail.JavaMailSenderImpl; 21 import org.springframework.mail.javamail.JavaMailSenderImpl;
22 import org.thingsboard.rule.engine.api.RuleNode; 22 import org.thingsboard.rule.engine.api.RuleNode;
23 import org.thingsboard.rule.engine.api.TbContext; 23 import org.thingsboard.rule.engine.api.TbContext;
  24 +import org.thingsboard.rule.engine.api.TbEmail;
24 import org.thingsboard.rule.engine.api.TbNode; 25 import org.thingsboard.rule.engine.api.TbNode;
25 import org.thingsboard.rule.engine.api.TbNodeConfiguration; 26 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
26 import org.thingsboard.rule.engine.api.TbNodeException; 27 import org.thingsboard.rule.engine.api.TbNodeException;
@@ -71,7 +72,7 @@ public class TbSendEmailNode implements TbNode { @@ -71,7 +72,7 @@ public class TbSendEmailNode implements TbNode {
71 public void onMsg(TbContext ctx, TbMsg msg) { 72 public void onMsg(TbContext ctx, TbMsg msg) {
72 try { 73 try {
73 validateType(msg.getType()); 74 validateType(msg.getType());
74 - EmailPojo email = getEmail(msg); 75 + TbEmail email = getEmail(msg);
75 withCallback(ctx.getMailExecutor().executeAsync(() -> { 76 withCallback(ctx.getMailExecutor().executeAsync(() -> {
76 sendEmail(ctx, msg, email); 77 sendEmail(ctx, msg, email);
77 return null; 78 return null;
@@ -83,18 +84,16 @@ public class TbSendEmailNode implements TbNode { @@ -83,18 +84,16 @@ public class TbSendEmailNode implements TbNode {
83 } 84 }
84 } 85 }
85 86
86 - private void sendEmail(TbContext ctx, TbMsg msg, EmailPojo email) throws Exception { 87 + private void sendEmail(TbContext ctx, TbMsg msg, TbEmail email) throws Exception {
87 if (this.config.isUseSystemSmtpSettings()) { 88 if (this.config.isUseSystemSmtpSettings()) {
88 - ctx.getMailService().send(ctx.getTenantId(), msg.getCustomerId(), email.getFrom(), email.getTo(), email.getCc(),  
89 - email.getBcc(), email.getSubject(), email.getBody(), email.isHtml(), email.getImages()); 89 + ctx.getMailService().send(ctx.getTenantId(), msg.getCustomerId(), email);
90 } else { 90 } else {
91 - ctx.getMailService().send(ctx.getTenantId(), msg.getCustomerId(), email.getFrom(), email.getTo(), email.getCc(),  
92 - email.getBcc(), email.getSubject(), email.getBody(), email.isHtml(), email.getImages(), this.mailSender); 91 + ctx.getMailService().send(ctx.getTenantId(), msg.getCustomerId(), email, this.mailSender);
93 } 92 }
94 } 93 }
95 94
96 - private EmailPojo getEmail(TbMsg msg) throws IOException {  
97 - EmailPojo email = MAPPER.readValue(msg.getData(), EmailPojo.class); 95 + private TbEmail getEmail(TbMsg msg) throws IOException {
  96 + TbEmail email = MAPPER.readValue(msg.getData(), TbEmail.class);
98 if (StringUtils.isBlank(email.getTo())) { 97 if (StringUtils.isBlank(email.getTo())) {
99 throw new IllegalStateException("Email destination can not be blank [" + email.getTo() + "]"); 98 throw new IllegalStateException("Email destination can not be blank [" + email.getTo() + "]");
100 } 99 }
@@ -23,6 +23,7 @@ import org.mockito.ArgumentCaptor; @@ -23,6 +23,7 @@ import org.mockito.ArgumentCaptor;
23 import org.mockito.Mock; 23 import org.mockito.Mock;
24 import org.mockito.junit.MockitoJUnitRunner; 24 import org.mockito.junit.MockitoJUnitRunner;
25 import org.thingsboard.rule.engine.api.TbContext; 25 import org.thingsboard.rule.engine.api.TbContext;
  26 +import org.thingsboard.rule.engine.api.TbEmail;
26 import org.thingsboard.rule.engine.api.TbNodeConfiguration; 27 import org.thingsboard.rule.engine.api.TbNodeConfiguration;
27 import org.thingsboard.rule.engine.api.TbNodeException; 28 import org.thingsboard.rule.engine.api.TbNodeException;
28 import org.thingsboard.server.common.data.id.DeviceId; 29 import org.thingsboard.server.common.data.id.DeviceId;
@@ -79,9 +80,9 @@ public class TbMsgToEmailNodeTest { @@ -79,9 +80,9 @@ public class TbMsgToEmailNodeTest {
79 assertEquals("oreo", metadataCaptor.getValue().getValue("username")); 80 assertEquals("oreo", metadataCaptor.getValue().getValue("username"));
80 assertNotSame(metaData, metadataCaptor.getValue()); 81 assertNotSame(metaData, metadataCaptor.getValue());
81 82
82 - EmailPojo actual = new ObjectMapper().readValue(dataCaptor.getValue().getBytes(), EmailPojo.class); 83 + TbEmail actual = new ObjectMapper().readValue(dataCaptor.getValue().getBytes(), TbEmail.class);
83 84
84 - EmailPojo expected = new EmailPojo.EmailPojoBuilder() 85 + TbEmail expected = TbEmail.builder()
85 .from("test@mail.org") 86 .from("test@mail.org")
86 .to("user@email.io") 87 .to("user@email.io")
87 .subject("Hi oreo there") 88 .subject("Hi oreo there")