Reputation: 337
I have a requirement to implement failover email service. Means if one goes down, service can failover to a different provider.
provider
I am using spring boot, maven.
Is it possible using application properties only like
spring.mail.host=smtp.mailgun.org, smtp.sendgrid.org
?
Till Now: application.properties
spring.mail.host=smtp.mailgun.org
spring.mail.port=587
spring.mail.username=some-username
spring.mail.password=some-password
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
Mail sending method implementation:
@Override
public void sendMails(MailDomain mailDomain) { // MailDomain is class that contains fields useful to configure mail attributes
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
try {
helper.setTo(mailDomain.getSendTo());
helper.setText(mailDomain.getMailBody());
helper.setSubject(mailDomain.getSubject());
} catch (MessagingException e) {
LOG.debug("Unable to set details of message " + e.getMessage());
}
try {
mailSender.send(message); // send mail....
} catch (MailException e) {
LOG.debug("Unable to sendmail " + e.getMessage());
}
}
Upvotes: 0
Views: 826
Reputation: 7231
This is Very Late Answer But I Found an easy solution for that.
You can try something like this to handle failover.
application.properties
hostFirst=email-smtp.us-west-2.amazonaws.com
hostSecond=smtp.gmail.com
portFirst=25
portSecond=587
username=email
password=password
protocol=smtp
mail.auth=true
starttls=true
EmailService.java
package com.emailservice.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;
import java.util.Properties;
@Service
public class EmailService {
@Value("${hostFirst}")
private String hostFirst;
@Value("${hostSecond}")
private String hostSecond;
@Value("${portFirst}")
private int portFirst;
@Value("${portSecond}")
private int portSecond;
@Value("${username}")
private String username;
@Value("${password}")
private String password;
@Value("${protocol}")
private String protocol;
@Value("${mail.auth}")
private boolean auth;
@Value("${starttls}")
private boolean starttls;
public void sendSimpleMessage(String from, String to) {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setUsername(username);
javaMailSender.setPassword(password);
javaMailSender.setJavaMailProperties(getMailProperties());
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject("Spring Boot Email");
message.setText("Greetings for the Day :)");
try {
System.out.println("Trying To Send from first mail");
javaMailSender.setHost(hostFirst);
javaMailSender.setPort(portFirst);
javaMailSender.send(message);
} catch (MailException e) {
System.out.println(e.getLocalizedMessage());
System.out.println("Trying To Send from second mail");
javaMailSender.setHost(hostSecond);
javaMailSender.setPort(portSecond);
javaMailSender.send(message);
}
}
private Properties getMailProperties() {
Properties properties = new Properties();
properties.setProperty("mail.transport.protocol", protocol);
properties.setProperty("mail.smtp.auth", auth?"true":"false");
properties.setProperty("mail.smtp.starttls.enable", starttls?"true":"false");
return properties;
}
}
Upvotes: 0
Reputation: 4403
As spring boot will not do the failover when you provide two hosts, you will have to define a second mailSender and handle the failover yourself. Springs makes this easy:
@Bean
@ConfigurationProperties(prefix = "second.mail")
public MailSender secondMailSender() {
return new JavaMailSenderImpl();
}
This will create a new mail sender initialized from properties like:
second.mail.host=mail.mymail.org
Now, the presence of this bean will suppress the auto configuration of the default mail sender, so you'll need to define both yourself:
@Bean
@ConfigurationProperties(prefix = "first.mail")
public MailSender firstMailSender() {
return new JavaMailSenderImpl();
}
After that:
@Autowired
private MailSender secondMailSender;
@Autowired
private MailSender firstMailSender;
try {
firstMailSender.send(message); // send mail....
} catch (MailException e) {
LOG.debug("Unable to sendmail " + e.getMessage());
try {
secondMailSender.send(message);
....
}
Upvotes: 2