Skip to content

Commit 5b9979f

Browse files
committed
make default attachment data source opt-in
1 parent e0a231f commit 5b9979f

6 files changed

Lines changed: 55 additions & 31 deletions

File tree

pom.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
34
<modelVersion>4.0.0</modelVersion>
45

56
<parent>
@@ -11,7 +12,7 @@
1112

1213
<groupId>it.aboutbits.springboot</groupId>
1314
<artifactId>emailservice</artifactId>
14-
<version>1.2.0</version>
15+
<version>BUILD-SNAPSHOT</version>
1516
<description>Spring Boot Email Service</description>
1617

1718
<properties>

readme.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,20 @@ Add the mailer service to the classpath by adding the following maven dependency
1717

1818
### Attachments
1919

20-
Attachments work out of the box. The library ships a default that stores attachment payloads in the
21-
lib-owned table `email_service_attachment_payloads`. The table is created automatically the first time the default is
22-
used, unless `aboutbits.emailservice.migrations.enabled` is set to `false`.
20+
If you want to use attachments, you will have to define a bean implementing this interface: [AttachmentDataSource.java](src%2Fmain%2Fjava%2Fit%2Faboutbits%2Fspringboot%2Femailservice%2Flib%2FAttachmentDataSource.java)
21+
This step is optional. Where the payloads are stored is a decision of the application: you can provide your own
22+
implementation (e.g. S3), or register the ready-made `JdbcAttachmentDataSource` shipped with the library, which stores
23+
payloads in the lib-owned table `email_service_attachment_payloads`:
2324

24-
If you want to store payloads somewhere else (e.g. S3), define your own bean implementing this
25-
interface: [AttachmentDataSource.java](src%2Fmain%2Fjava%2Fit%2Faboutbits%2Fspringboot%2Femailservice%2Flib%2FAttachmentDataSource.java)
26-
The default then backs off and its table is never created.
25+
```java
26+
27+
@Bean
28+
public AttachmentDataSource attachmentDataSource(JdbcTemplate jdbcTemplate) {
29+
return new JdbcAttachmentDataSource(jdbcTemplate);
30+
}
31+
```
32+
33+
The `JdbcAttachmentDataSource` creates its table itself on construction, so no further setup is needed.
2734

2835
#### Inline (CID) attachments
2936

src/main/java/it/aboutbits/springboot/emailservice/EmailServiceConfiguration.java

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99
import it.aboutbits.springboot.emailservice.lib.application.EmailMapper;
1010
import it.aboutbits.springboot.emailservice.lib.application.EmailMapperImpl;
1111
import it.aboutbits.springboot.emailservice.lib.application.EmailServiceMigrator;
12-
import it.aboutbits.springboot.emailservice.lib.application.JdbcAttachmentDataSource;
1312
import it.aboutbits.springboot.emailservice.lib.application.ManageEmail;
1413
import it.aboutbits.springboot.emailservice.lib.application.QueryEmail;
1514
import it.aboutbits.springboot.emailservice.lib.application.SendScheduledEmails;
15+
import it.aboutbits.springboot.emailservice.lib.application.UnavailableAttachmentDataSource;
1616
import it.aboutbits.springboot.emailservice.lib.jpa.EmailRepository;
1717
import org.jspecify.annotations.NullMarked;
18+
import org.springframework.beans.factory.ObjectProvider;
1819
import org.springframework.beans.factory.annotation.Value;
1920
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
20-
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2121
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2222
import org.springframework.context.annotation.Bean;
2323
import org.springframework.jdbc.core.JdbcTemplate;
@@ -55,7 +55,7 @@ public QueryEmail queryEmail(EmailRepository emailRepository, EmailMapper emailM
5555
public ManageEmail manageEmail(
5656
EmailRepository emailRepository,
5757
JavaMailSender javaMailSender,
58-
AttachmentDataSource attachmentDataSource,
58+
ObjectProvider<AttachmentDataSource> attachmentDataSource,
5959
EmailMapper emailMapper,
6060
@Value("${aboutbits.emailservice.scheduling.max-attempts:3}") int maxAttempts,
6161
@Value("${aboutbits.emailservice.scheduling.interval:30000}") long schedulerIntervalMillis,
@@ -64,7 +64,7 @@ public ManageEmail manageEmail(
6464
return new ManageEmail(
6565
emailRepository,
6666
javaMailSender,
67-
attachmentDataSource,
67+
attachmentDataSource.getIfAvailable(UnavailableAttachmentDataSource::new),
6868
emailMapper,
6969
maxAttempts,
7070
Duration.ofMillis(schedulerIntervalMillis),
@@ -93,17 +93,4 @@ public CleanupAttachmentFiles cleanupAttachments(
9393
) {
9494
return new CleanupAttachmentFiles(queryEmail, manageEmail, callbacks, stuckCleanupRecoveryThreshold);
9595
}
96-
97-
@Bean
98-
@ConditionalOnMissingBean(AttachmentDataSource.class)
99-
public JdbcAttachmentDataSource attachmentDataSource(
100-
JdbcTemplate jdbcTemplate,
101-
@Value("${aboutbits.emailservice.migrations.enabled:true}") boolean migrationsEnabled
102-
) {
103-
var dataSource = new JdbcAttachmentDataSource(jdbcTemplate);
104-
if (migrationsEnabled) {
105-
dataSource.migrate();
106-
}
107-
return dataSource;
108-
}
10996
}

src/main/java/it/aboutbits/springboot/emailservice/lib/application/JdbcAttachmentDataSource.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ public class JdbcAttachmentDataSource implements AttachmentDataSource {
1919

2020
public JdbcAttachmentDataSource(JdbcTemplate jdbcTemplate) {
2121
this.jdbcTemplate = jdbcTemplate;
22+
migrate();
2223
}
2324

24-
public void migrate() {
25+
private void migrate() {
2526
log.info("EmailService: running attachment payload DB migrations...");
2627

2728
jdbcTemplate.execute(
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package it.aboutbits.springboot.emailservice.lib.application;
2+
3+
import it.aboutbits.springboot.emailservice.lib.AttachmentDataSource;
4+
import it.aboutbits.springboot.emailservice.lib.exception.AttachmentException;
5+
import org.jspecify.annotations.NullMarked;
6+
7+
import java.io.InputStream;
8+
9+
@NullMarked
10+
public final class UnavailableAttachmentDataSource implements AttachmentDataSource {
11+
@Override
12+
public InputStream getAttachmentPayload(long fileReference) throws AttachmentException {
13+
throw new AttachmentException("attachments not available");
14+
}
15+
16+
@Override
17+
public long storeAttachmentPayload(InputStream payload) throws AttachmentException {
18+
throw new AttachmentException("attachments not available");
19+
}
20+
21+
@Override
22+
public void releaseAttachment(long fileReference) throws AttachmentException {
23+
throw new AttachmentException("attachments not available");
24+
}
25+
}

src/test/java/it/aboutbits/springboot/emailservice/lib/application/JdbcAttachmentDataSourceTest.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package it.aboutbits.springboot.emailservice.lib.application;
22

3-
import it.aboutbits.springboot.emailservice.lib.AttachmentDataSource;
43
import it.aboutbits.springboot.emailservice.lib.exception.AttachmentException;
54
import it.aboutbits.springboot.emailservice.support.database.WithPostgres;
65
import org.jspecify.annotations.NullMarked;
6+
import org.junit.jupiter.api.BeforeEach;
77
import org.junit.jupiter.api.Test;
88
import org.springframework.beans.factory.annotation.Autowired;
99
import org.springframework.boot.test.context.SpringBootTest;
10+
import org.springframework.jdbc.core.JdbcTemplate;
1011

1112
import java.io.ByteArrayInputStream;
1213

@@ -19,11 +20,13 @@
1920
@NullMarked
2021
class JdbcAttachmentDataSourceTest {
2122
@Autowired
22-
AttachmentDataSource attachmentDataSource;
23+
JdbcTemplate jdbcTemplate;
2324

24-
@Test
25-
void defaultAttachmentDataSource_shouldBeJdbcBased() {
26-
assertThat(attachmentDataSource).isInstanceOf(JdbcAttachmentDataSource.class);
25+
JdbcAttachmentDataSource attachmentDataSource;
26+
27+
@BeforeEach
28+
void setup() {
29+
attachmentDataSource = new JdbcAttachmentDataSource(jdbcTemplate);
2730
}
2831

2932
@Test

0 commit comments

Comments
 (0)