Latest blog

  • Spring Boot Send Email Example

    Now that you got your monitoring up and running, what’s next? Do you relax, put your feet up and read Jack Reacher Tripwire? I’m sure your boss will say “Can this notify us when something is wrong? Like send an email or something. There you go. This bit is about adding that send email functionality.

    The code is in here, Crowsnest and here’s what changed, pull request. Anyway, let’s talk about what was added for this monitoring app to be able to send an email.

    Additional Dependency

    With the addition of below in the pom.xml, you receive Spring’s sending email bells and whistles. Spring Boot will provide auto-configuration and abstraction for sending email by using the JavaMailSender interface.

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-mail</artifactId>
    </dependency>

    Spring Mail Properties Configuration

    You might want to customized the configuration of JavaMarlSender. It can be added in the application.properties file using the spring.mail namespace. Some default timeout values are infinite, so you might want to add some properties like below to avoid freezing your app because of an unresponsive SMTP server.

    email.feature.enabled=true
    email.recipients = joel@example.net
    email.sender.proxy = noreply.joel@example.net
    
    spring.mail.host=localhost
    spring.mail.port=25
    
    spring.mail.properties.mail.smtp.connectiontimeout=5000
    spring.mail.properties.mail.smtp.timeout=3000
    spring.mail.properties.mail.smtp.writetimeout.=5000

    Spring Boot Send Email Component

    Here’s the meat of the send email operation. By default, if spring.mail.host and the Spring Mail libraries are defined, you can inject JavaMailSender automatically. The email sender proxy defined will be the sender. I think the variables are descriptive enough as to what it is for, isn’t it? We got a “to”, our destination email. Subject of the email and the text which will be the body of the email. Clear enough? Great!

    package net.codesamples.crowsnest;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.mail.SimpleMailMessage;
    import org.springframework.mail.javamail.JavaMailSender;
    import org.springframework.stereotype.Component;
    
    @Component
    public class EmailService {
    
        @Autowired
        private JavaMailSender mailSender;
    
        @Value("${email.sender.proxy}")
        private String emailSenderProxy;
    
        public void sendEmailMessage(String to, String subject, String text) {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(emailSenderProxy);
            message.setTo(to);
            message.setSubject(subject);
            message.setText(text);
    
            mailSender.send(message);
        }
    }

    Spring Boot Send Email Trigger

    Next is when do we want it to send an email? Of course as soon as something goes down. Fairly simple, just @Autowire the EmailService component and call the send email message method in our SchedulePings class.

    package net.codesamples.crowsnest;
    
    // ... impoerts snipped
    
        @Autowired
        private WebClient webClient;
    
        @Autowired
        private EmailService emailService;
    
        @Value("${email.recipients}")
        private List<String> emailRecipients;
    
        @Value("${email.feature.enabled}")
        private boolean emailFeatureEnabled;
    
        @Value("${awry.payloads}")
        private List<String> awryPayloads;
    
        @Value("${awry.payload.feature.enabled}")
        private boolean awryPayloadFeatureEnabled;
    
    // ... snipped
    
    
                                sendEmailMessage("Monitored Service UNREACHABLE - " + app.getName(),
                                        app.getUrl() + "\r\n" + exception.getMessage());
    
                                return Mono.empty();
                            });
                    mono.subscribe(body -> {
                        if (hasAwryPayloads(body)) {
                            app.setStatus("down");
                            sendEmailMessage("Monitored Service Gone AWRY? - " + app.getName(),
                                app.getUrl() + "\r\n" +
                                "Payload: \r\n" + body);
                        }
                    });
    
    // ... snipped
    
    	private boolean hasAwryPayloads(String body) {
            if (awryPayloadFeatureEnabled) {
                if (body.isBlank() || body.length() < 9) {
                    return true;
                }
    
                for (String awryPayload : awryPayloads) {
                    if (body.toLowerCase().startsWith(awryPayload.toLowerCase())) {
                        return true;
                    }
                }
            }
    
            return false;
        }
    
        private void sendEmailMessage(String subject, String text) {
            if (emailFeatureEnabled) {
                for (String emailRecipient : emailRecipients) {
                    // Rnwood.smtp4dev
                    emailService.sendEmailMessage(
                            emailRecipient,
                            subject,
                            text);
                }
            }
        }
    
    // ... snipped

    We have a feature flag as well. So if emailFeatureEnabled is set to true, we send the email. Otherwise we don’t.

    Spring Boot Send Email Test

    Alright, time to see if this send email thing works. First thing we’ll need is an SMTP server that will handle emails being sent. I’m using an old version of smtp4dev but there is a new one which is definitely better. Anyway, run Crowsnest and bring a system down that it is monitoring. You should be able to figure that out. Smtp4dev will look like below.

    Spring Boot Send Email – smtp4dev

    Email details will look like below.

    Spring Boot Send Email – smtp4dev inspect

    Spring Boot Send Email Wrap Up

    Congratulations. Your app can now spam the hell out of the monitoring team. To recap, we added Spring Boot’s starter mail dependency. Then added the properties. After that, created a component to handle the email service. Lastly, find an entry point in our monitoring code as to when to invoke sending the email. Short and sweet.

    Email me more tips…