Create spring-boot-sendgrid module

This commit is contained in:
Moritz Halbritter
2025-03-25 12:19:13 +01:00
committed by Phillip Webb
parent 843867c0f4
commit 8561dd7680
11 changed files with 33 additions and 10 deletions

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2012-2025 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
*
* https://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.sendgrid.autoconfigure;
import com.sendgrid.Client;
import com.sendgrid.SendGrid;
import com.sendgrid.SendGridAPI;
import org.apache.http.HttpHost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.boot.autoconfigure.AutoConfiguration;
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;
/**
* {@link EnableAutoConfiguration Auto-configuration} for SendGrid.
*
* @author Maciej Walkowiak
* @author Patrick Bray
* @author Andy Wilkinson
* @since 4.0.0
*/
@AutoConfiguration
@ConditionalOnClass(SendGrid.class)
@ConditionalOnProperty("spring.sendgrid.api-key")
@EnableConfigurationProperties(SendGridProperties.class)
public class SendGridAutoConfiguration {
@Bean
@ConditionalOnMissingBean(SendGridAPI.class)
public SendGrid sendGrid(SendGridProperties properties) {
if (properties.isProxyConfigured()) {
HttpHost proxy = new HttpHost(properties.getProxy().getHost(), properties.getProxy().getPort());
return new SendGrid(properties.getApiKey(), new Client(HttpClientBuilder.create().setProxy(proxy).build()));
}
return new SendGrid(properties.getApiKey());
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright 2012-2025 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
*
* https://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.sendgrid.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* {@link ConfigurationProperties @ConfigurationProperties} for SendGrid.
*
* @author Maciej Walkowiak
* @author Andy Wilkinson
* @since 4.0.0
*/
@ConfigurationProperties("spring.sendgrid")
public class SendGridProperties {
/**
* SendGrid API key.
*/
private String apiKey;
/**
* Proxy configuration.
*/
private Proxy proxy;
public String getApiKey() {
return this.apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
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;
}
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright 2012-2025 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
*
* https://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.
*/
/**
* Auto-configuration for SendGrid.
*/
package org.springframework.boot.sendgrid.autoconfigure;

View File

@@ -0,0 +1 @@
org.springframework.boot.sendgrid.autoconfigure.SendGridAutoConfiguration

View File

@@ -0,0 +1,105 @@
/*
* Copyright 2012-2025 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
*
* https://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.sendgrid.autoconfigure;
import com.sendgrid.SendGrid;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link SendGridAutoConfiguration}.
*
* @author Maciej Walkowiak
* @author Patrick Bray
*/
class SendGridAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
@AfterEach
void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
void expectedSendGridBeanCreatedApiKey() {
loadContext("spring.sendgrid.api-key:SG.SECRET-API-KEY");
SendGrid sendGrid = this.context.getBean(SendGrid.class);
assertThat(sendGrid.getRequestHeaders()).containsEntry("Authorization", "Bearer SG.SECRET-API-KEY");
}
@Test
void autoConfigurationNotFiredWhenPropertiesNotSet() {
loadContext();
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
.isThrownBy(() -> this.context.getBean(SendGrid.class));
}
@Test
void autoConfigurationNotFiredWhenBeanAlreadyCreated() {
loadContext(ManualSendGridConfiguration.class, "spring.sendgrid.api-key:SG.SECRET-API-KEY");
SendGrid sendGrid = this.context.getBean(SendGrid.class);
assertThat(sendGrid.getRequestHeaders()).containsEntry("Authorization", "Bearer SG.CUSTOM_API_KEY");
}
@Test
void expectedSendGridBeanWithProxyCreated() {
loadContext("spring.sendgrid.api-key:SG.SECRET-API-KEY", "spring.sendgrid.proxy.host:localhost",
"spring.sendgrid.proxy.port:5678");
SendGrid sendGrid = this.context.getBean(SendGrid.class);
assertThat(sendGrid).extracting("client.httpClient.routePlanner").isInstanceOf(DefaultProxyRoutePlanner.class);
}
private void loadContext(String... environment) {
loadContext(null, environment);
}
private void loadContext(Class<?> additionalConfiguration, String... environment) {
this.context = new AnnotationConfigApplicationContext();
TestPropertyValues.of(environment).applyTo(this.context);
ConfigurationPropertySources.attach(this.context.getEnvironment());
this.context.register(SendGridAutoConfiguration.class);
if (additionalConfiguration != null) {
this.context.register(additionalConfiguration);
}
this.context.refresh();
}
@Configuration(proxyBeanMethods = false)
static class ManualSendGridConfiguration {
@Bean
SendGrid sendGrid() {
return new SendGrid("SG.CUSTOM_API_KEY", true);
}
}
}