diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index 065a1d90723..c5184d61096 100644 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -380,6 +380,11 @@ jms-api true + + javax.mail + mail + true + org.aspectj aspectjweaver 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 new file mode 100644 index 00000000000..287e21f6419 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java @@ -0,0 +1,89 @@ +/* + * Copyright 2012-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.mail; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Configuration properties for email support. + * + * @author Oliver Gierke + * @author Stephane Nicoll + */ +@ConfigurationProperties(prefix = "spring.mail") +public class MailProperties { + + private String host; + + private Integer port; + + private String username; + + private String password; + + private String defaultEncoding = "UTF-8"; + + private Map properties = new HashMap(); + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getDefaultEncoding() { + return defaultEncoding; + } + + public void setDefaultEncoding(String defaultEncoding) { + this.defaultEncoding = defaultEncoding; + } + + public Map getProperties() { + return properties; + } + +} 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 new file mode 100644 index 00000000000..2ad247515fa --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.mail; + +import java.util.Map; +import java.util.Properties; +import javax.activation.MimeType; +import javax.mail.internet.MimeMessage; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +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.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.MailSender; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; + +/** + * {@link EnableAutoConfiguration Auto configuration} for email support. + * + * @author Oliver Gierke + * @author Stephane Nicoll + */ +@Configuration +@ConditionalOnClass({MimeMessage.class, MimeType.class}) +@ConditionalOnProperty(prefix = "spring.mail", value = "host") +@ConditionalOnMissingBean(MailSender.class) +@EnableConfigurationProperties(MailProperties.class) +public class MailSenderAutoConfiguration { + + @Autowired MailProperties properties; + + @Bean + public JavaMailSender mailSender() { + JavaMailSenderImpl sender = new JavaMailSenderImpl(); + sender.setHost(this.properties.getHost()); + if (this.properties.getPort() != null) { + sender.setPort(this.properties.getPort()); + } + sender.setUsername(this.properties.getUsername()); + sender.setPassword(this.properties.getPassword()); + sender.setDefaultEncoding(this.properties.getDefaultEncoding()); + Map properties = this.properties.getProperties(); + if (!properties.isEmpty()) { + Properties javaMailProperties= new Properties(); + for (Map.Entry entry : properties.entrySet()) { + javaMailProperties.setProperty(entry.getKey(), entry.getValue()); + } + sender.setJavaMailProperties(javaMailProperties); + } + return sender; + } + +} \ No newline at end of file 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 b549c5db27b..9b88304c1a5 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -38,6 +38,7 @@ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\ org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\ +org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\ 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 new file mode 100644 index 00000000000..e730273ac73 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java @@ -0,0 +1,123 @@ +/* + * Copyright 2012-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.mail; + +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import org.springframework.boot.test.EnvironmentTestUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; + +import static org.junit.Assert.*; + +/** + * Tests for {@link MailSenderAutoConfiguration}. + * + * @author Stephane Nicoll + */ +public class MailSenderAutoConfigurationTests { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private AnnotationConfigApplicationContext context; + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void smtpHostSet() { + String host = "192.168.1.234"; + load(EmptyConfig.class, "spring.mail.host:" + host); + JavaMailSenderImpl bean = (JavaMailSenderImpl) context.getBean(JavaMailSender.class); + assertEquals(host, bean.getHost()); + } + + @Test + public void smptHostWithSettings() { + String host = "192.168.1.234"; + load(EmptyConfig.class, "spring.mail.host:" + host, "spring.mail.port:42", + "spring.mail.username:john", "spring.mail.password:secret", "spring.mail.default-encoding:ISO-9"); + JavaMailSenderImpl bean = (JavaMailSenderImpl) context.getBean(JavaMailSender.class); + assertEquals(host, bean.getHost()); + assertEquals(42, bean.getPort()); + assertEquals("john", bean.getUsername()); + assertEquals("secret", bean.getPassword()); + assertEquals("ISO-9", bean.getDefaultEncoding()); + } + + @Test + public void smptHostWithJavaMailProperties() { + load(EmptyConfig.class, "spring.mail.host:localhost", "spring.mail.properties.mail.smtp.auth:true"); + JavaMailSenderImpl bean = (JavaMailSenderImpl) context.getBean(JavaMailSender.class); + assertEquals("true", bean.getJavaMailProperties().get("mail.smtp.auth")); + } + + @Test + public void smtpHostNotSet() { + load(EmptyConfig.class); + assertEquals(0, context.getBeansOfType(JavaMailSender.class).size()); + } + + @Test + public void mailSenderBackOff() { + load(ManualMailConfiguration.class, "spring.mail.host:smtp.acme.org", + "spring.mail.user:user", "spring.mail.password:secret"); + JavaMailSenderImpl bean = (JavaMailSenderImpl) context.getBean(JavaMailSender.class); + assertNull(bean.getUsername()); + assertNull(bean.getPassword()); + } + + + private void load(Class config, String... environment) { + this.context = doLoad(new Class[] {config}, environment); + } + + private AnnotationConfigApplicationContext doLoad(Class[] configs, + String... environment) { + AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(applicationContext, environment); + applicationContext.register(configs); + applicationContext.register(MailSenderAutoConfiguration.class); + applicationContext.refresh(); + return applicationContext; + } + + @Configuration + static class EmptyConfig { + + } + + @Configuration + static class ManualMailConfiguration { + + @Bean + JavaMailSender customMailSender() { + return new JavaMailSenderImpl(); + } + } +} diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index 63e9724ae18..a6d67a498b6 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -300,6 +300,11 @@ spring-boot-starter-logging 1.2.0.BUILD-SNAPSHOT + + org.springframework.boot + spring-boot-starter-mail + 1.2.0.BUILD-SNAPSHOT + org.springframework.boot spring-boot-starter-mobile @@ -545,6 +550,11 @@ jms-api 1.1-rev-1 + + javax.mail + mail + 1.5.0-b01 + javax.servlet javax.servlet-api diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index 1c9b81d3ba5..014017a453d 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -43,6 +43,7 @@ spring-boot-starter-logging spring-boot-starter-log4j spring-boot-starter-log4j2 + spring-boot-starter-mail spring-boot-starter-mobile spring-boot-starter-actuator spring-boot-starter-parent diff --git a/spring-boot-starters/spring-boot-starter-mail/pom.xml b/spring-boot-starters/spring-boot-starter-mail/pom.xml new file mode 100644 index 00000000000..42993a9c626 --- /dev/null +++ b/spring-boot-starters/spring-boot-starter-mail/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starters + 1.2.0.BUILD-SNAPSHOT + + spring-boot-starter-mail + Spring Boot Mail Starter + Spring Boot Mail Starter + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + + + + org.springframework.boot + spring-boot-starter + + + org.springframework + spring-core + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + + + org.springframework + spring-context-support + + + javax.mail + mail + + + diff --git a/spring-boot-starters/spring-boot-starter-mail/src/main/resources/META-INF/spring.provides b/spring-boot-starters/spring-boot-starter-mail/src/main/resources/META-INF/spring.provides new file mode 100644 index 00000000000..0f1f2f9abd0 --- /dev/null +++ b/spring-boot-starters/spring-boot-starter-mail/src/main/resources/META-INF/spring.provides @@ -0,0 +1 @@ +provides: spring-context-support,mail \ No newline at end of file