diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index d5aeb2b9ab..cb3bfab9db 100644 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -155,6 +155,11 @@ groovy-templates true + + com.sendgrid + sendgrid-java + true + com.zaxxer HikariCP-java6 diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfiguration.java new file mode 100644 index 0000000000..bdc8c5958c --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfiguration.java @@ -0,0 +1,66 @@ +/* + * 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. + * 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.sendgrid; + +import org.apache.http.HttpHost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +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 com.sendgrid.SendGrid; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for SendGrid + * + * @author Maciej Walkowiak + * @since 1.3.0 + */ +@Configuration +@ConditionalOnClass(SendGrid.class) +@ConditionalOnProperty(prefix = "spring.sendgrid", value = "username") +@EnableConfigurationProperties(SendGridProperties.class) +public class SendGridAutoConfiguration { + + @Autowired + private SendGridProperties properties; + + @Bean + @ConditionalOnMissingBean(SendGrid.class) + public SendGrid sendGrid() { + SendGrid sendGrid = new SendGrid(this.properties.getUsername(), + this.properties.getPassword()); + + if (this.properties.isProxyConfigured()) { + HttpHost proxy = new HttpHost(this.properties.getProxy().getHost(), + this.properties.getProxy().getPort()); + CloseableHttpClient http = HttpClientBuilder.create().setProxy(proxy) + .setUserAgent("sendgrid/" + sendGrid.getVersion() + ";java").build(); + + sendGrid.setClient(http); + } + + return sendGrid; + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridProperties.java new file mode 100644 index 0000000000..480933a8fb --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridProperties.java @@ -0,0 +1,104 @@ +/* + * 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. + * 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.sendgrid; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * {@link ConfigurationProperties} for SendGrid. + * + * @author Maciej Walkowiak + * @since 1.3.0 + */ +@ConfigurationProperties(prefix = "spring.sendgrid") +public class SendGridProperties { + + /** + * SendGrid username. + */ + private String username; + + /** + * SendGrid password. + */ + private String password; + + /** + * Proxy configuration. + */ + private Proxy proxy; + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Proxy getProxy() { + return this.proxy; + } + + public void setProxy(Proxy proxy) { + this.proxy = proxy; + } + + public boolean isProxyConfigured() { + return this.proxy != null && this.proxy.getHost() != null + && this.proxy.getPort() != null; + } + + public static class Proxy { + + /** + * SendGrid proxy host. + */ + private String host; + + /** + * SendGrid proxy port. + */ + private Integer port; + + public String getHost() { + return this.host; + } + + public void setHost(String host) { + this.host = host; + } + + public Integer getPort() { + return this.port; + } + + public void setPort(Integer port) { + this.port = port; + } + + } + +} 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 f3f3ca601e..2042b37de2 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -50,6 +50,7 @@ org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\ org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration,\ org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\ +org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\ org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\ org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\ org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\ diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfigurationTests.java new file mode 100644 index 0000000000..5ae23bea0f --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfigurationTests.java @@ -0,0 +1,109 @@ +/* + * 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. + * 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.sendgrid; + +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.conn.DefaultProxyRoutePlanner; +import org.junit.After; +import org.junit.Test; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +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.test.util.ReflectionTestUtils; + +import com.sendgrid.SendGrid; + +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +/** + * Tests for {@link SendGridAutoConfiguration}. + * + * @author Maciej Walkowiak + */ +public class SendGridAutoConfigurationTests { + private AnnotationConfigApplicationContext context; + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void expectedSendGridBeanCreated() { + loadContext("spring.sendgrid.username:user", "spring.sendgrid.password:secret"); + SendGrid sendGrid = this.context.getBean(SendGrid.class); + assertEquals("user", ReflectionTestUtils.getField(sendGrid, "username")); + assertEquals("secret", ReflectionTestUtils.getField(sendGrid, "password")); + } + + @Test(expected = NoSuchBeanDefinitionException.class) + public void autoConfigurationNotFiredWhenPropertiesNotSet() { + loadContext(); + this.context.getBean(SendGrid.class); + } + + @Test + public void autoConfigurationNotFiredWhenBeanAlreadyCreated() { + loadContext(ManualSendGridConfiguration.class, "spring.sendgrid.username:user", + "spring.sendgrid.password:secret"); + SendGrid sendGrid = this.context.getBean(SendGrid.class); + assertEquals("manual-user", ReflectionTestUtils.getField(sendGrid, "username")); + assertEquals("manual-secret", ReflectionTestUtils.getField(sendGrid, "password")); + } + + @Test + public void expectedSendGridBeanWithProxyCreated() { + loadContext("spring.sendgrid.username:user", "spring.sendgrid.password:secret", + "spring.sendgrid.proxy.host:localhost", "spring.sendgrid.proxy.port:5678"); + SendGrid sendGrid = this.context.getBean(SendGrid.class); + CloseableHttpClient client = (CloseableHttpClient) ReflectionTestUtils.getField( + sendGrid, "client"); + HttpRoutePlanner routePlanner = (HttpRoutePlanner) ReflectionTestUtils.getField( + client, "routePlanner"); + assertThat(routePlanner, instanceOf(DefaultProxyRoutePlanner.class)); + } + + private void loadContext(String... environment) { + this.loadContext(null, environment); + } + + private void loadContext(Class additionalConfiguration, String... environment) { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, environment); + this.context.register(SendGridAutoConfiguration.class); + if (additionalConfiguration != null) { + this.context.register(additionalConfiguration); + } + this.context.refresh(); + } + + @Configuration + static class ManualSendGridConfiguration { + + @Bean + SendGrid sendGrid() { + return new SendGrid("manual-user", "manual-secret"); + } + } +} \ No newline at end of file diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index 033d05e2f7..485ec2666e 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -128,6 +128,7 @@ 1.0.1.RELEASE 1.1.0.RELEASE 2.2.0.RELEASE + 2.1.0 ${javax-mail.version} 2.1.4.RELEASE 2.1.1.RELEASE @@ -512,6 +513,11 @@ jmustache ${jmustache.version} + + com.sendgrid + sendgrid-java + ${sendgrid.version} + com.sun.mail javax.mail 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 c06a2559e5..82c39f5353 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -573,6 +573,12 @@ content into your application; rather pick only the properties that you need. shell.auth.simple.user.password= shell.auth.spring.roles= + # SENDGRID ({sc-spring-boot-autoconfigure}/sendgrid/SendGridAutoConfiguration.{sc-ext}[SendGridAutoConfiguration]) + spring.sendgrid.username= # SendGrid account username + spring.sendgrid.password= # SendGrid account password + spring.sendgrid.proxy.host= # SendGrid proxy host + spring.sendgrid.proxy.port= # SendGrid proxy port + # GIT INFO spring.git.properties= # resource ref to generated git info properties file ---- diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index 2411eeca43..ac8f2599fd 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -54,6 +54,11 @@ jackson-databind true + + com.sendgrid + sendgrid-java + true + com.google.code.gson gson