Skip to content

Commit 54a4e90

Browse files
authored
Bump spring-boot-starter-parent from 3.5.6 to 4.0.0 in Spring Batch Notion (#191)
Signed-off-by: Stefano Cordio <stefano.cordio@gmail.com>
1 parent c76f364 commit 54a4e90

File tree

12 files changed

+207
-142
lines changed

12 files changed

+207
-142
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
2+
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
3+
--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
4+
--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
5+
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
6+
--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
7+
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
8+
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
9+
--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
10+
--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED

spring-batch-notion/README.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This project provides a [Spring Batch][] extension module that adds support for
66

77
## Compatibility
88

9-
Spring Batch Notion is based on Spring Batch 5 and tested on Spring Boot 3, thus requiring at least Java 17.
9+
Spring Batch Notion is based on Spring Batch 6 and tested on Spring Boot 4, thus requiring at least Java 17.
1010

1111
Compatibility is guaranteed only with the Spring Batch versions under [OSS support](https://spring.io/projects/spring-batch#support).
1212

@@ -36,25 +36,29 @@ A minimal configuration of the item reader is as follows:
3636

3737
```java
3838
NotionDatabaseItemReader<Item> itemReader() {
39-
NotionDatabaseItemReader<Item> reader = new NotionDatabaseItemReader<>();
40-
reader.setToken(System.getenv("NOTION_TOKEN"));
41-
reader.setDatabaseId("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); // UUID
42-
reader.setPropertiesMapper(new CustomPropertyMapper());
43-
return reader;
39+
String token = System.getenv("NOTION_TOKEN");
40+
String databaseId = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"; // UUID
41+
PropertyMapper<Item> propertyMapper = new CustomPropertyMapper();
42+
return new NotionDatabaseItemReader<>(token, databaseId, propertyMapper);
4443
}
4544
```
4645

47-
The following configuration options are available:
46+
The following constructor parameters should be provided:
47+
48+
| Property | Description |
49+
|------------------|---------------------------------------------------------------------------------------------------------------------------|
50+
| `token` | The Notion integration token. |
51+
| `databaseId` | UUID of the database to read from. |
52+
| `propertyMapper` | The `PropertyMapper` responsible for mapping properties of a Notion item into a Java object. |
53+
54+
and the following configuration options are available:
4855

4956
| Property | Required | Default | Description |
5057
|------------------|----------|-----------------------------|---------------------------------------------------------------------------------------------------------------------------|
5158
| `baseUrl` | no | `https://api.notion.com/v1` | Base URL of the Notion API. A custom value can be provided for testing purposes (e.g., the URL of a [WireMock][] server). |
52-
| `databaseId` | yes | - | UUID of the database to read from. |
5359
| `filter` | no | `null` | `Filter` condition to limit the returned items. |
5460
| `pageSize` | no | `100` | Number of items to be read with each page. Must be greater than zero and less than or equal to 100. |
55-
| `propertyMapper` | yes | - | The `PropertyMapper` responsible for mapping properties of a Notion item into a Java object. |
5661
| `sorts` | no | `null` | `Sort` conditions to order the returned items. Each condition is applied following the declaration order. |
57-
| `token` | yes | - | The Notion integration token. |
5862

5963
In addition to the Notion-specific configuration, all the configuration options of the Spring Batch
6064
[`AbstractPaginatedDataItemReader`](https://docs.spring.io/spring-batch/docs/current/api/org/springframework/batch/item/data/AbstractPaginatedDataItemReader.html)

spring-batch-notion/pom.xml

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>org.springframework.boot</groupId>
77
<artifactId>spring-boot-starter-parent</artifactId>
8-
<version>3.5.6</version>
8+
<version>4.0.0</version>
99
<relativePath/>
1010
</parent>
1111

@@ -160,8 +160,31 @@ limitations under the License.
160160
<artifactId>maven-compiler-plugin</artifactId>
161161
<configuration>
162162
<compilerArgs>
163-
<arg>-Xlint:all,-varargs</arg>
163+
<compilerArg>-Xlint:all,-varargs</compilerArg>
164+
<!-- https://errorprone.info/docs/installation#maven -->
165+
<compilerArg>-XDcompilePolicy=simple</compilerArg>
166+
<compilerArg>--should-stop=ifError=FLOW</compilerArg>
167+
<compilerArg>
168+
-Xplugin:ErrorProne
169+
-XepDisableAllChecks
170+
<!-- Check JSpecify annotations -->
171+
-Xep:NullAway
172+
-XepOpt:NullAway:OnlyNullMarked
173+
-XepOpt:NullAway:SuppressionNameAliases=DataFlowIssue
174+
</compilerArg>
164175
</compilerArgs>
176+
<annotationProcessorPaths>
177+
<path>
178+
<groupId>com.google.errorprone</groupId>
179+
<artifactId>error_prone_core</artifactId>
180+
<version>2.43.0</version>
181+
</path>
182+
<path>
183+
<groupId>com.uber.nullaway</groupId>
184+
<artifactId>nullaway</artifactId>
185+
<version>0.12.11</version>
186+
</path>
187+
</annotationProcessorPaths>
165188
<failOnWarning>true</failOnWarning>
166189
</configuration>
167190
</plugin>
@@ -178,8 +201,8 @@ limitations under the License.
178201
</additionalDependencies>
179202
<failOnWarnings>true</failOnWarnings>
180203
<links>
181-
<link>https://docs.spring.io/spring-batch/docs/${spring-batch.version}/api/</link>
182204
<link>https://docs.spring.io/spring-framework/docs/${spring-framework.version}/javadoc-api/</link>
205+
<link>https://javadoc.io/static/org.springframework.batch/spring-batch-core/${spring-batch.version}/</link>
183206
</links>
184207
</configuration>
185208
<executions>

spring-batch-notion/src/main/java/org/springframework/batch/extensions/notion/NotionDatabaseItemReader.java

Lines changed: 40 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
import notion.api.v1.model.pages.PageProperty;
2626
import notion.api.v1.model.pages.PageProperty.RichText;
2727
import notion.api.v1.request.databases.QueryDatabaseRequest;
28+
import org.jspecify.annotations.Nullable;
2829
import org.springframework.batch.extensions.notion.mapping.PropertyMapper;
29-
import org.springframework.batch.item.ExecutionContext;
30-
import org.springframework.batch.item.ItemReader;
31-
import org.springframework.batch.item.data.AbstractPaginatedDataItemReader;
32-
import org.springframework.beans.factory.InitializingBean;
30+
import org.springframework.batch.infrastructure.item.ExecutionContext;
31+
import org.springframework.batch.infrastructure.item.ItemReader;
32+
import org.springframework.batch.infrastructure.item.data.AbstractPaginatedDataItemReader;
3333
import org.springframework.util.Assert;
3434

3535
import java.util.Collections;
@@ -57,39 +57,41 @@
5757
* @author Stefano Cordio
5858
* @param <T> Type of item to be read
5959
*/
60-
public class NotionDatabaseItemReader<T> extends AbstractPaginatedDataItemReader<T> implements InitializingBean {
61-
62-
private static final String DEFAULT_BASE_URL = "https://api.notion.com/v1";
60+
public class NotionDatabaseItemReader<T> extends AbstractPaginatedDataItemReader<T> {
6361

6462
private static final int DEFAULT_PAGE_SIZE = 100;
6563

66-
private String baseUrl;
64+
private static final String DEFAULT_BASE_URL = "https://api.notion.com/v1";
65+
66+
private final String token;
6767

68-
private String token;
68+
private final String databaseId;
6969

70-
private String databaseId;
70+
private final PropertyMapper<T> propertyMapper;
7171

72-
private PropertyMapper<T> propertyMapper;
72+
private String baseUrl = DEFAULT_BASE_URL;
7373

74-
private QueryTopLevelFilter filter;
74+
private @Nullable QueryTopLevelFilter filter;
7575

76-
private List<QuerySort> sorts;
76+
private @Nullable List<QuerySort> sorts;
7777

78-
private NotionClient client;
78+
private @Nullable NotionClient client;
7979

8080
private boolean hasMore;
8181

82-
private String nextCursor;
82+
private @Nullable String nextCursor;
8383

8484
/**
85-
* Create a new {@link NotionDatabaseItemReader} with the following defaults:
86-
* <ul>
87-
* <li>{@code baseUrl} = {@value #DEFAULT_BASE_URL}</li>
88-
* <li>{@code pageSize} = {@value #DEFAULT_PAGE_SIZE}</li>
89-
* </ul>
85+
* Create a new {@link NotionDatabaseItemReader}.
86+
* @param token the Notion integration token
87+
* @param databaseId UUID of the database to read from
88+
* @param propertyMapper the {@link PropertyMapper} responsible for mapping properties
89+
* of a Notion item into a Java object
9090
*/
91-
public NotionDatabaseItemReader() {
92-
this.baseUrl = DEFAULT_BASE_URL;
91+
public NotionDatabaseItemReader(String token, String databaseId, PropertyMapper<T> propertyMapper) {
92+
this.token = Objects.requireNonNull(token);
93+
this.databaseId = Objects.requireNonNull(databaseId);
94+
this.propertyMapper = Objects.requireNonNull(propertyMapper);
9395
this.pageSize = DEFAULT_PAGE_SIZE;
9496
}
9597

@@ -106,37 +108,6 @@ public void setBaseUrl(String baseUrl) {
106108
this.baseUrl = Objects.requireNonNull(baseUrl);
107109
}
108110

109-
/**
110-
* The Notion integration token.
111-
* <p>
112-
* Always required.
113-
* @param token the token
114-
*/
115-
public void setToken(String token) {
116-
this.token = Objects.requireNonNull(token);
117-
}
118-
119-
/**
120-
* UUID of the database to read from.
121-
* <p>
122-
* Always required.
123-
* @param databaseId the database UUID
124-
*/
125-
public void setDatabaseId(String databaseId) {
126-
this.databaseId = Objects.requireNonNull(databaseId);
127-
}
128-
129-
/**
130-
* The {@link PropertyMapper} responsible for mapping Notion item properties into a
131-
* Java object.
132-
* <p>
133-
* Always required.
134-
* @param propertyMapper the property mapper
135-
*/
136-
public void setPropertyMapper(PropertyMapper<T> propertyMapper) {
137-
this.propertyMapper = Objects.requireNonNull(propertyMapper);
138-
}
139-
140111
/**
141112
* {@link Filter} condition to limit the returned items.
142113
* <p>
@@ -175,6 +146,19 @@ public void setPageSize(int pageSize) {
175146
super.setPageSize(pageSize);
176147
}
177148

149+
/**
150+
* {@inheritDoc}
151+
*/
152+
@Override
153+
protected void doOpen() {
154+
client = new NotionClient(token);
155+
client.setHttpClient(new JavaNetHttpClient());
156+
client.setLogger(new Slf4jLogger());
157+
client.setBaseUrl(baseUrl);
158+
159+
hasMore = true;
160+
}
161+
178162
/**
179163
* {@inheritDoc}
180164
*/
@@ -190,6 +174,7 @@ protected Iterator<T> doPageRead() {
190174
request.setStartCursor(nextCursor);
191175
request.setPageSize(pageSize);
192176

177+
@SuppressWarnings("DataFlowIssue")
193178
QueryResults queryResults = client.queryDatabase(request);
194179

195180
hasMore = queryResults.getHasMore();
@@ -198,7 +183,7 @@ protected Iterator<T> doPageRead() {
198183
return queryResults.getResults()
199184
.stream()
200185
.map(NotionDatabaseItemReader::getProperties)
201-
.map(properties -> propertyMapper.map(properties))
186+
.map(propertyMapper::map)
202187
.iterator();
203188
}
204189

@@ -224,19 +209,7 @@ private static String getPlainText(List<RichText> texts) {
224209
/**
225210
* {@inheritDoc}
226211
*/
227-
@Override
228-
protected void doOpen() {
229-
client = new NotionClient(token);
230-
client.setHttpClient(new JavaNetHttpClient());
231-
client.setLogger(new Slf4jLogger());
232-
client.setBaseUrl(baseUrl);
233-
234-
hasMore = true;
235-
}
236-
237-
/**
238-
* {@inheritDoc}
239-
*/
212+
@SuppressWarnings("DataFlowIssue")
240213
@Override
241214
protected void doClose() {
242215
client.close();
@@ -255,14 +228,4 @@ protected void jumpToItem(int itemIndex) throws Exception {
255228
}
256229
}
257230

258-
/**
259-
* {@inheritDoc}
260-
*/
261-
@Override
262-
public void afterPropertiesSet() {
263-
Assert.state(token != null, "'token' must be set");
264-
Assert.state(databaseId != null, "'databaseId' must be set");
265-
Assert.state(propertyMapper != null, "'propertyMapper' must be set");
266-
}
267-
268231
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2024-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Infrastructure to map the properties of a Notion item into a Java object.
19+
*/
20+
@NullMarked
21+
package org.springframework.batch.extensions.notion.mapping;
22+
23+
import org.jspecify.annotations.NullMarked;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2024-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Spring Batch extension for Notion.
19+
*/
20+
@NullMarked
21+
package org.springframework.batch.extensions.notion;
22+
23+
import org.jspecify.annotations.NullMarked;

0 commit comments

Comments
 (0)