DefaultMailService with timeout by mail-service-watchdog

This commit is contained in:
Sergey Matvienko 2024-05-06 16:06:08 +02:00
parent b8480cd456
commit 38d37224f3

View File

@ -16,6 +16,7 @@
package org.thingsboard.server.service.mail; package org.thingsboard.server.service.mail;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.util.concurrent.Futures;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.Template; import freemarker.template.Template;
import jakarta.xml.bind.DatatypeConverter; import jakarta.xml.bind.DatatypeConverter;
@ -32,6 +33,7 @@ import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.rule.engine.api.TbEmail; import org.thingsboard.rule.engine.api.TbEmail;
import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.cache.limits.RateLimitService;
@ -53,11 +55,14 @@ import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMessage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -94,6 +99,8 @@ public class DefaultMailService implements MailService {
@Value("${mail.per_tenant_rate_limits:}") @Value("${mail.per_tenant_rate_limits:}")
private String perTenantRateLimitConfig; private String perTenantRateLimitConfig;
private final ScheduledExecutorService scheduler;
private TbMailSender mailSender; private TbMailSender mailSender;
private String mailFrom; private String mailFrom;
@ -105,6 +112,7 @@ public class DefaultMailService implements MailService {
this.freemarkerConfig = freemarkerConfig; this.freemarkerConfig = freemarkerConfig;
this.adminSettingsService = adminSettingsService; this.adminSettingsService = adminSettingsService;
this.apiUsageClient = apiUsageClient; this.apiUsageClient = apiUsageClient;
this.scheduler = Executors.newScheduledThreadPool(1, ThingsBoardThreadFactory.forName("mail-service-watchdog"));
} }
@PostConstruct @PostConstruct
@ -112,6 +120,13 @@ public class DefaultMailService implements MailService {
updateMailConfiguration(); updateMailConfiguration();
} }
@PreDestroy
public void destroy() {
if (scheduler != null) {
scheduler.shutdownNow();
}
}
@Override @Override
public void updateMailConfiguration() { public void updateMailConfiguration() {
AdminSettings settings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"); AdminSettings settings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail");
@ -429,8 +444,11 @@ public class DefaultMailService implements MailService {
} }
private void sendMailWithTimeout(JavaMailSender mailSender, MimeMessage msg, long timeout) { private void sendMailWithTimeout(JavaMailSender mailSender, MimeMessage msg, long timeout) {
var submittedMail = Futures.withTimeout(
mailExecutorService.submit(() -> mailSender.send(msg)),
timeout, TimeUnit.MILLISECONDS, scheduler);
try { try {
mailExecutorService.submit(() -> mailSender.send(msg)).get(timeout, TimeUnit.MILLISECONDS); submittedMail.get(timeout, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) { } catch (TimeoutException e) {
log.debug("Error during mail submission", e); log.debug("Error during mail submission", e);
throw new RuntimeException("Timeout!"); throw new RuntimeException("Timeout!");