From 328e07ebf376bf14a7619b2e892b2a3cc2086ac7 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 2 Jun 2015 15:02:29 +0200 Subject: [PATCH] polish mail jndi support Closes gh-2419 --- ...ion.java => JndiSessionConfiguration.java} | 28 +++++------- .../autoconfigure/mail/MailProperties.java | 4 +- .../mail/MailSenderAutoConfiguration.java | 27 +++++++----- .../main/resources/META-INF/spring.factories | 1 - .../MailSenderAutoConfigurationTests.java | 44 ++++++++----------- .../appendix-application-properties.adoc | 2 +- 6 files changed, 47 insertions(+), 59 deletions(-) rename spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/{JndiMailAutoConfiguration.java => JndiSessionConfiguration.java} (69%) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/JndiMailAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/JndiSessionConfiguration.java similarity index 69% rename from spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/JndiMailAutoConfiguration.java rename to spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/JndiSessionConfiguration.java index fce4d035d1e..fda10ceb8eb 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/JndiMailAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/JndiSessionConfiguration.java @@ -16,35 +16,30 @@ package org.springframework.boot.autoconfigure.mail; +import javax.mail.Session; +import javax.naming.NamingException; + import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnJndi; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jndi.JndiLocatorDelegate; -import javax.mail.Session; -import javax.naming.NamingException; - /** - * {@link EnableAutoConfiguration Auto-configuration} for Mail provided from JNDI. + * Auto-configure a {@link Session} available on JNDI. * * @author EddĂș MelĂ©ndez + * @author Stephane Nicoll * @since 1.3.0 */ @Configuration -@AutoConfigureBefore(MailSenderAutoConfiguration.class) @ConditionalOnClass(Session.class) -@ConditionalOnMissingBean(Session.class) @ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name") -@EnableConfigurationProperties(MailProperties.class) @ConditionalOnJndi -public class JndiMailAutoConfiguration { +class JndiSessionConfiguration { @Autowired private MailProperties properties; @@ -54,13 +49,12 @@ public class JndiMailAutoConfiguration { public Session session() { try { return new JndiLocatorDelegate() - .lookup(this.properties.getJndiName(), Session.class); - } catch (NamingException e) { - + .lookup(this.properties.getJndiName(), Session.class); + } + catch (NamingException e) { + throw new IllegalStateException(String.format( + "Unable to find Session in JNDI location %s", this.properties.getJndiName())); } - - throw new IllegalStateException(String - .format("Unable to find Session in JNDI location %s", this.properties.getJndiName())); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java index c7879ed3ec3..7245af925d3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,7 @@ public class MailProperties { private Map properties = new HashMap(); /** - * JNDI location of the session. Host, port, username, password are ignored when set. + * Session JNDI name. When set, takes precedence to others mail settings. */ private String jndiName; diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java index d8dbcfc841a..72f39e38f0b 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java @@ -17,10 +17,9 @@ package org.springframework.boot.autoconfigure.mail; import java.util.Properties; - import javax.activation.MimeType; -import javax.mail.internet.MimeMessage; import javax.mail.Session; +import javax.mail.internet.MimeMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -28,11 +27,12 @@ import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration.PropertiesCondition; +import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration.MailSenderCondition; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.mail.MailSender; import org.springframework.mail.javamail.JavaMailSenderImpl; @@ -47,8 +47,9 @@ import org.springframework.mail.javamail.JavaMailSenderImpl; @Configuration @ConditionalOnClass({ MimeMessage.class, MimeType.class }) @ConditionalOnMissingBean(MailSender.class) -@Conditional(PropertiesCondition.class) +@Conditional(MailSenderCondition.class) @EnableConfigurationProperties(MailProperties.class) +@Import(JndiSessionConfiguration.class) public class MailSenderAutoConfiguration { @Autowired(required = false) @@ -62,7 +63,8 @@ public class MailSenderAutoConfiguration { JavaMailSenderImpl sender = new JavaMailSenderImpl(); if (this.session != null) { sender.setSession(this.session); - } else { + } + else { sender.setHost(this.properties.getHost()); if (this.properties.getPort() != null) { sender.setPort(this.properties.getPort()); @@ -80,22 +82,23 @@ public class MailSenderAutoConfiguration { } /** - * Condition for jndi-name or host property + * Condition to trigger the creation of a {@link JavaMailSenderImpl}. This kicks in + * if either the host or jndi name property is set. */ - static class PropertiesCondition extends AnyNestedCondition { + static class MailSenderCondition extends AnyNestedCondition { - public PropertiesCondition() { + public MailSenderCondition() { super(ConfigurationPhase.PARSE_CONFIGURATION); } - @ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name") - static class JndiNameProperty { - } - @ConditionalOnProperty(prefix = "spring.mail", name = "host") static class HostProperty { } + @ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name") + static class JndiNameProperty { + } + } } diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index d7bedb6c6f2..c5e01733329 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -40,7 +40,6 @@ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfigu org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\ org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\ org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\ -org.springframework.boot.autoconfigure.mail.JndiMailAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\ diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java index c36b57bc3a3..3ab252b8a27 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java @@ -137,57 +137,49 @@ public class MailSenderAutoConfigurationTests { } @Test - public void sessionIsAvailableFromJndiAndJndiNameIsSet() throws IllegalStateException, - NamingException { - Properties properties = new Properties(); - Session session = Session.getDefaultInstance(properties); - configureJndi("foo", session); - - load(JndiMailAutoConfiguration.class, "spring.mail.jndi-name:foo"); + public void jndiSessionAvailable() throws NamingException { + Session session = configureJndiSession("foo"); + load(EmptyConfig.class, "spring.mail.jndi-name:foo"); - assertNotNull(this.context.getBean(Session.class)); - assertEquals(session, this.context.getBean(Session.class)); - assertNotNull(this.context.getBean(JavaMailSender.class)); + Session sessionBean = this.context.getBean(Session.class); + assertEquals(session, sessionBean); + assertEquals(sessionBean, this.context.getBean(JavaMailSenderImpl.class).getSession()); } @Test - public void sessionIsAvailableFromJndiAndHostIsSet() throws IllegalStateException, - NamingException { - Properties properties = new Properties(); - Session session = Session.getDefaultInstance(properties); - configureJndi("foo", session); + public void jndiSessionIgnoredIfJndiNameNotSet() throws NamingException { + configureJndiSession("foo"); - load(JndiMailAutoConfiguration.class, "spring.mail.host:smtp.acme.org"); + load(EmptyConfig.class, "spring.mail.host:smtp.acme.org"); assertEquals(0, this.context.getBeanNamesForType(Session.class).length); assertNotNull(this.context.getBean(JavaMailSender.class)); } @Test - public void sessionIsAvailableFromJndiAndPropertiesNotUsed() throws IllegalStateException, - NamingException { - Properties properties = new Properties(); - Session session = Session.getDefaultInstance(properties); - configureJndi("foo", session); + public void jndiSessionNotUsedIfJndiNameNotSet() throws NamingException { + configureJndiSession("foo"); - load(JndiMailAutoConfiguration.class); + load(EmptyConfig.class); assertEquals(0, this.context.getBeanNamesForType(Session.class).length); assertEquals(0, this.context.getBeanNamesForType(JavaMailSender.class).length); } @Test - public void sessionIsNotAvailableFromJndiAndJndiNameIsSet() throws IllegalStateException, - NamingException { + public void jndiSessionNotAvailableWithJndiName() throws NamingException { thrown.expect(BeanCreationException.class); thrown.expectMessage("Unable to find Session in JNDI location foo"); - load(JndiMailAutoConfiguration.class, "spring.mail.jndi-name:foo"); + load(EmptyConfig.class, "spring.mail.jndi-name:foo"); } - private void configureJndi(String name, Session session) + private Session configureJndiSession(String name) throws IllegalStateException, NamingException { + Properties properties = new Properties(); + Session session = Session.getDefaultInstance(properties); TestableInitialContextFactory.bind(name, session); + return session; } private void load(Class config, String... environment) { diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 557f30359f9..375a0c79b81 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -486,7 +486,7 @@ content into your application; rather pick only the properties that you need. spring.mail.password= spring.mail.default-encoding=UTF-8 # encoding to use for MimeMessages spring.mail.properties.*= # properties to set on the JavaMail session - spring.mail.jndi-name= # For JNDI lookup (host, port, username & password are ignored when set) + spring.mail.jndi-name= # JNDI location of a Mail Session # SPRING BATCH ({sc-spring-boot-autoconfigure}/batch/BatchProperties.{sc-ext}[BatchProperties]) spring.batch.job.names=job1,job2