Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SES configurationSetName is configurable via properties Fixes gh-1006 #1007

Merged
merged 2 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/main/asciidoc/_configprops.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
|spring.cloud.aws.ses.endpoint | | Overrides the default endpoint.
|spring.cloud.aws.ses.region | | Overrides the default region.
|spring.cloud.aws.ses.source-arn | | Configures source ARN. Used only for sending authorization.
|spring.cloud.aws.ses.configuration-set-name | The configuration set name used for every message.
|spring.cloud.aws.sns.enabled | `+++true+++` | Enables SNS integration.
|spring.cloud.aws.sns.endpoint | | Overrides the default endpoint.
|spring.cloud.aws.sns.region | | Overrides the default region.
Expand Down
9 changes: 7 additions & 2 deletions docs/src/main/asciidoc/ses.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ The Spring Boot Starter for SES provides the following configuration options:
| `spring.cloud.aws.ses.enabled` | Enables the SES integration. | No | `true`
| `spring.cloud.aws.ses.endpoint` | Configures endpoint used by `SesClient`. | No |
| `spring.cloud.aws.ses.region` | Configures region used by `SesClient`. | No |
| `spring.cloud.aws.ses.sourceArn` | Configures source ARN, used only for sending authorization. | No |
| `spring.cloud.aws.ses.source-arn` | Configures source ARN, used only for sending authorization. | No |
| `spring.cloud.aws.ses.configuration-set-name` | The configuration set name used for every message | No |
|===

Amazon SES is not available in all https://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html[regions] of the
Expand All @@ -147,10 +148,14 @@ an SES service where the client is overridden to use a valid region (`EU-WEST-1`
`sourceArn` is the ARN of the identity that is associated with the sending authorization policy. For information about when to use this parameter, see the
description see https://docs.aws.amazon.com/ses/latest/dg/sending-authorization-delegate-sender-tasks-email.html[Amazon SES Developer Guide].

`configurationSetName` sets the configuration set name on mail sender level and applies to every mail. For information about when to use this parameter, see the
description https://docs.aws.amazon.com/ses/latest/dg/using-configuration-sets.html[Using configuration sets in Amazon SES].

[source,properties,indent=0]
----
spring.cloud.aws.ses.region=eu-west-1
spring.cloud.aws.ses.sourceArn=arn:aws:ses:eu-west-1:123456789012:identity/example.com
spring.cloud.aws.ses.source-arn=arn:aws:ses:eu-west-1:123456789012:identity/example.com
spring.cloud.aws.ses.configuration-set-name=ConfigSet
----

=== IAM Permissions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ public SesClient sesClient(SesProperties properties, AwsClientBuilderConfigurer
@Bean
@ConditionalOnMissingClass("jakarta.mail.Session")
public MailSender simpleMailSender(SesClient sesClient, SesProperties properties) {
return new SimpleEmailServiceMailSender(sesClient, properties.getSourceArn());
return new SimpleEmailServiceMailSender(sesClient, properties.getSourceArn(), properties.getConfigurationSetName());
}

@Bean
@ConditionalOnClass(name = "jakarta.mail.Session")
public JavaMailSender javaMailSender(SesClient sesClient, SesProperties properties) {
return new SimpleEmailServiceJavaMailSender(sesClient, properties.getSourceArn());
return new SimpleEmailServiceJavaMailSender(sesClient, properties.getSourceArn(), properties.getConfigurationSetName());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,27 @@ public class SesProperties extends AwsClientProperties {
@Nullable
private String sourceArn;

/**
* Configures configuration set name.
*/
@Nullable
private String configurationSetName;

@Nullable
public String getSourceArn() {
return sourceArn;
}

@Nullable
public String getConfigurationSetName() {
return configurationSetName;
}

public void setSourceArn(@Nullable String sourceArn) {
this.sourceArn = sourceArn;
}

public void setConfigurationSetName(@Nullable String configurationSetName) {
this.configurationSetName = configurationSetName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ public SimpleEmailServiceJavaMailSender(SesClient sesClient) {
}

public SimpleEmailServiceJavaMailSender(SesClient sesClient, @Nullable String sourceArn) {
super(sesClient, sourceArn);
this(sesClient, sourceArn, null);
}

public SimpleEmailServiceJavaMailSender(SesClient sesClient, @Nullable String sourceArn, @Nullable String configurationSetName) {
super(sesClient, sourceArn, configurationSetName);
}

/**
Expand Down Expand Up @@ -206,8 +210,9 @@ public void send(MimeMessage... mimeMessages) throws MailException {
try {
RawMessage rawMessage = createRawMessage(mimeMessage);

SendRawEmailResponse sendRawEmailResponse = getEmailService().sendRawEmail(
SendRawEmailRequest.builder().sourceArn(getSourceArn()).rawMessage(rawMessage).build());
SendRawEmailResponse sendRawEmailResponse = getEmailService()
.sendRawEmail(SendRawEmailRequest.builder().sourceArn(getSourceArn())
.configurationSetName(getConfigurationSetName()).rawMessage(rawMessage).build());

if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Message with id: {} successfully sent", sendRawEmailResponse.messageId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,21 @@ public class SimpleEmailServiceMailSender implements MailSender, DisposableBean
@Nullable
private final String sourceArn;

@Nullable
private final String configurationSetName;

public SimpleEmailServiceMailSender(SesClient sesClient) {
this(sesClient, null);
}

public SimpleEmailServiceMailSender(SesClient sesClient, @Nullable String sourceArn) {
this(sesClient, sourceArn, null);
}

public SimpleEmailServiceMailSender(SesClient sesClient, @Nullable String sourceArn, @Nullable String configurationSetName) {
this.sesClient = sesClient;
this.sourceArn = sourceArn;
this.configurationSetName = configurationSetName;
}

@Override
Expand Down Expand Up @@ -108,6 +116,11 @@ protected String getSourceArn() {
return sourceArn;
}

@Nullable
protected String getConfigurationSetName() {
return configurationSetName;
}

private SendEmailRequest prepareMessage(SimpleMailMessage simpleMailMessage) {
Assert.notNull(simpleMailMessage, "simpleMailMessage are required");
Destination.Builder destinationBuilder = Destination.builder();
Expand All @@ -126,8 +139,8 @@ private SendEmailRequest prepareMessage(SimpleMailMessage simpleMailMessage) {
Message message = Message.builder().body(body).subject(subject).build();

SendEmailRequest.Builder emailRequestBuilder = SendEmailRequest.builder()
.destination(destinationBuilder.build()).source(simpleMailMessage.getFrom()).sourceArn(getSourceArn())
.message(message);
.destination(destinationBuilder.build()).source(simpleMailMessage.getFrom()).sourceArn(getSourceArn())
.configurationSetName(getConfigurationSetName()).message(message);

if (StringUtils.hasText(simpleMailMessage.getReplyTo())) {
emailRequestBuilder.replyToAddresses(simpleMailMessage.getReplyTo());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,20 @@ void testSendMimeMessage() throws MessagingException {
assertThat(request.getValue().sourceArn()).isEqualTo("arn:aws:ses:us-east-1:00000001:identity/domain.com");
}

@Test
void testSendMimeMessageWithConfigurationSetNameSet() throws MessagingException {
SesClient emailService = mock(SesClient.class);
JavaMailSender mailSender = new SimpleEmailServiceJavaMailSender(emailService, null, "Configuration Set");
ArgumentCaptor<SendRawEmailRequest> request = ArgumentCaptor.forClass(SendRawEmailRequest.class);
when(emailService.sendRawEmail(request.capture()))
.thenReturn(SendRawEmailResponse.builder().messageId("123").build());
MimeMessage mimeMessage = createMimeMessage();

mailSender.send(mimeMessage);

assertThat(request.getValue().configurationSetName()).isEqualTo("Configuration Set");
}

@Test
void testSendMultipleMimeMessages() throws Exception {
SesClient emailService = mock(SesClient.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@ void testSendSimpleMailWithMinimalProperties() {
assertThat(sendEmailRequest.sourceArn()).isEqualTo("arn:aws:ses:us-east-1:00000000:identity/domain.com");
}

@Test
void testSendSimpleMailWithConfigurationSetNameSet() {
SesClient emailService = mock(SesClient.class);
SimpleEmailServiceMailSender mailSender = new SimpleEmailServiceMailSender(emailService,
null, "Configuration Set");
SimpleMailMessage simpleMailMessage = createSimpleMailMessage();
ArgumentCaptor<SendEmailRequest> request = ArgumentCaptor.forClass(SendEmailRequest.class);
when(emailService.sendEmail(request.capture()))
.thenReturn(SendEmailResponse.builder().messageId("123").build());

mailSender.send(simpleMailMessage);

SendEmailRequest sendEmailRequest = request.getValue();
assertThat(sendEmailRequest.configurationSetName()).isEqualTo("Configuration Set");
}

@Test
void testSendSimpleMailWithCCandBCC() {
SesClient emailService = mock(SesClient.class);
Expand Down
Loading