From 57621c19aa2f516a0f4b773ee2892a9a99123a19 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sun, 1 Nov 2026 02:58:08 +0000
Subject: [PATCH 1/2] fix(deps): update dependency
org.springframework.boot:spring-boot-starter-parent to v4
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 2746b3ba..c4251c80 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.5.16
+ 4.1.2
onyxia-model
From 7b43d3ae9a7da6ff7c5de58c83e917561ab4f6e4 Mon Sep 17 00:00:00 2001
From: Dylan Decrulle <81740200+ddecrulle@users.noreply.github.com>
Date: Wed, 4 Nov 2026 10:31:19 +0100
Subject: [PATCH 2/2] chore: migrate to Spring Boot 4
- Replace removed AntPathRequestMatcher with PathPatternRequestMatcher
- Bump springdoc to 3.2.0 (Spring Boot 4.1 compatible) in api and model
- Keep Jackson 2 for HTTP messages (spring-boot-jackson2 +
spring.http.converters.preferred-json-mapper=jackson2) so the custom
ObjectMapper keeps being used
- Tests: @MockBean -> @MockitoBean, new WebMvcTest/AutoConfigureRestDocs
packages, add spring-boot-webmvc-test and spring-boot-restdocs
Co-Authored-By: Claude Opus 5.5
---
onyxia-api/pom.xml | 18 +++++-
.../api/security/OIDCConfiguration.java | 58 ++++++++++---------
.../src/main/resources/application.properties | 3 +
.../insee/onyxia/api/UserControllerTest.java | 14 ++---
.../onyxia/api/configuration/BaseTest.java | 2 +-
.../checks/DisableChecksForTests.java | 4 +-
.../onboarding/OnboardingControllerTest.java | 16 ++---
.../api/user/OnyxiaUserProviderTest.java | 6 +-
onyxia-model/pom.xml | 2 +-
9 files changed, 73 insertions(+), 50 deletions(-)
diff --git a/onyxia-api/pom.xml b/onyxia-api/pom.xml
index 56238fa2..e371f375 100644
--- a/onyxia-api/pom.xml
+++ b/onyxia-api/pom.xml
@@ -36,6 +36,16 @@
spring-restdocs-mockmvc
test
+
+ org.springframework.boot
+ spring-boot-webmvc-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-restdocs
+ test
+
org.springframework.boot
spring-boot-starter-webflux
@@ -43,7 +53,7 @@
org.springdoc
springdoc-openapi-starter-webmvc-ui
- 2.10.0
+ 3.2.0
@@ -99,6 +109,12 @@
com.fasterxml.jackson.core
jackson-databind
+
+
+ org.springframework.boot
+ spring-boot-jackson2
+
com.github.erosb
diff --git a/onyxia-api/src/main/java/fr/insee/onyxia/api/security/OIDCConfiguration.java b/onyxia-api/src/main/java/fr/insee/onyxia/api/security/OIDCConfiguration.java
index dc5d934e..205f8dd6 100644
--- a/onyxia-api/src/main/java/fr/insee/onyxia/api/security/OIDCConfiguration.java
+++ b/onyxia-api/src/main/java/fr/insee/onyxia/api/security/OIDCConfiguration.java
@@ -1,6 +1,6 @@
package fr.insee.onyxia.api.security;
-import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
+import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern;
import fr.insee.onyxia.api.services.UserProvider;
import fr.insee.onyxia.api.services.utils.HttpRequestUtils;
@@ -121,43 +121,47 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
configurer -> {
configurer.requestMatchers(HttpMethod.OPTIONS).permitAll();
// configuration pour Swagger
- configurer.requestMatchers(antMatcher("/")).permitAll();
- configurer.requestMatchers(antMatcher("/swagger-ui**")).permitAll();
- configurer.requestMatchers(antMatcher("/swagger-ui/**")).permitAll();
- configurer.requestMatchers(antMatcher("/v2/api-docs")).permitAll();
- configurer.requestMatchers(antMatcher("/v3/api-docs")).permitAll();
- configurer.requestMatchers(antMatcher("/v3/api-docs/*")).permitAll();
- configurer.requestMatchers(antMatcher("/csrf")).permitAll();
- configurer.requestMatchers(antMatcher("/webjars/**")).permitAll();
+ configurer.requestMatchers(pathPattern("/")).permitAll();
+ configurer.requestMatchers(pathPattern("/swagger-ui**")).permitAll();
+ configurer.requestMatchers(pathPattern("/swagger-ui/**")).permitAll();
+ configurer.requestMatchers(pathPattern("/v2/api-docs")).permitAll();
+ configurer.requestMatchers(pathPattern("/v3/api-docs")).permitAll();
+ configurer.requestMatchers(pathPattern("/v3/api-docs/*")).permitAll();
+ configurer.requestMatchers(pathPattern("/csrf")).permitAll();
+ configurer.requestMatchers(pathPattern("/webjars/**")).permitAll();
configurer
- .requestMatchers(antMatcher("/swagger-resources/**"))
+ .requestMatchers(pathPattern("/swagger-resources/**"))
.permitAll();
- configurer.requestMatchers(antMatcher("/actuator/**")).permitAll();
- configurer.requestMatchers(antMatcher("/actuator")).permitAll();
- configurer.requestMatchers(antMatcher("/api")).permitAll();
- configurer.requestMatchers(antMatcher("/api/swagger-ui**")).permitAll();
+ configurer.requestMatchers(pathPattern("/actuator/**")).permitAll();
+ configurer.requestMatchers(pathPattern("/actuator")).permitAll();
+ configurer.requestMatchers(pathPattern("/api")).permitAll();
configurer
- .requestMatchers(antMatcher("/api/swagger-ui/**"))
+ .requestMatchers(pathPattern("/api/swagger-ui**"))
.permitAll();
- configurer.requestMatchers(antMatcher("/api/v2/api-docs")).permitAll();
- configurer.requestMatchers(antMatcher("/api/v3/api-docs")).permitAll();
configurer
- .requestMatchers(antMatcher("/api/v3/api-docs/*"))
+ .requestMatchers(pathPattern("/api/swagger-ui/**"))
.permitAll();
- configurer.requestMatchers(antMatcher("/api/csrf")).permitAll();
- configurer.requestMatchers(antMatcher("/api/webjars/**")).permitAll();
+ configurer.requestMatchers(pathPattern("/api/v2/api-docs")).permitAll();
+ configurer.requestMatchers(pathPattern("/api/v3/api-docs")).permitAll();
configurer
- .requestMatchers(antMatcher("/api/swagger-resources/**"))
+ .requestMatchers(pathPattern("/api/v3/api-docs/*"))
.permitAll();
- configurer.requestMatchers(antMatcher("/api/actuator/**")).permitAll();
- configurer.requestMatchers(antMatcher("/api/actuator")).permitAll();
- configurer.requestMatchers(antMatcher("/configuration/**")).permitAll();
+ configurer.requestMatchers(pathPattern("/api/csrf")).permitAll();
+ configurer.requestMatchers(pathPattern("/api/webjars/**")).permitAll();
configurer
- .requestMatchers(antMatcher("/swagger-resources/**"))
+ .requestMatchers(pathPattern("/api/swagger-resources/**"))
+ .permitAll();
+ configurer.requestMatchers(pathPattern("/api/actuator/**")).permitAll();
+ configurer.requestMatchers(pathPattern("/api/actuator")).permitAll();
+ configurer
+ .requestMatchers(pathPattern("/configuration/**"))
+ .permitAll();
+ configurer
+ .requestMatchers(pathPattern("/swagger-resources/**"))
.permitAll();
// configuration pour public
- configurer.requestMatchers(antMatcher("/public/**")).permitAll();
- configurer.requestMatchers(antMatcher("/api/public/**")).permitAll();
+ configurer.requestMatchers(pathPattern("/public/**")).permitAll();
+ configurer.requestMatchers(pathPattern("/api/public/**")).permitAll();
configurer.anyRequest().authenticated();
})
.oauth2ResourceServer(
diff --git a/onyxia-api/src/main/resources/application.properties b/onyxia-api/src/main/resources/application.properties
index 2be3b8a8..c4774739 100644
--- a/onyxia-api/src/main/resources/application.properties
+++ b/onyxia-api/src/main/resources/application.properties
@@ -64,3 +64,6 @@ health.custom-crd.checks[0].kind=Cluster
health.custom-crd.checks[0].strategy=FIELDS
health.custom-crd.checks[0].desired-field=instances
health.custom-crd.checks[0].ready-field=readyInstances
+
+# Spring Boot 4 defaults to Jackson 3 for HTTP messages; keep using our Jackson 2 ObjectMapper (see CustomObjectMapper)
+spring.http.converters.preferred-json-mapper=jackson2
diff --git a/onyxia-api/src/test/java/fr/insee/onyxia/api/UserControllerTest.java b/onyxia-api/src/test/java/fr/insee/onyxia/api/UserControllerTest.java
index 35452393..e32df02a 100644
--- a/onyxia-api/src/test/java/fr/insee/onyxia/api/UserControllerTest.java
+++ b/onyxia-api/src/test/java/fr/insee/onyxia/api/UserControllerTest.java
@@ -22,8 +22,8 @@
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
@@ -34,15 +34,15 @@ public class UserControllerTest extends BaseTest {
@Autowired private ObjectMapper mapper;
- @MockBean private HttpRequestUtils httpRequestUtils;
+ @MockitoBean private HttpRequestUtils httpRequestUtils;
- @MockBean private RegionsConfiguration regionsConfiguration;
+ @MockitoBean private RegionsConfiguration regionsConfiguration;
- @MockBean private SecurityConfig securityConfig;
+ @MockitoBean private SecurityConfig securityConfig;
- @MockBean private OnyxiaUserProvider onyxiaUserProvider;
+ @MockitoBean private OnyxiaUserProvider onyxiaUserProvider;
- @MockBean private UserProvider userProvider;
+ @MockitoBean private UserProvider userProvider;
@BeforeEach
public void setUp() {
diff --git a/onyxia-api/src/test/java/fr/insee/onyxia/api/configuration/BaseTest.java b/onyxia-api/src/test/java/fr/insee/onyxia/api/configuration/BaseTest.java
index 17ac4d94..589cde52 100644
--- a/onyxia-api/src/test/java/fr/insee/onyxia/api/configuration/BaseTest.java
+++ b/onyxia-api/src/test/java/fr/insee/onyxia/api/configuration/BaseTest.java
@@ -2,7 +2,7 @@
import fr.insee.onyxia.api.security.NoSecurityConfiguration;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
+import org.springframework.boot.restdocs.test.autoconfigure.AutoConfigureRestDocs;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
diff --git a/onyxia-api/src/test/java/fr/insee/onyxia/api/configuration/checks/DisableChecksForTests.java b/onyxia-api/src/test/java/fr/insee/onyxia/api/configuration/checks/DisableChecksForTests.java
index ac8f1d82..4ef90e72 100644
--- a/onyxia-api/src/test/java/fr/insee/onyxia/api/configuration/checks/DisableChecksForTests.java
+++ b/onyxia-api/src/test/java/fr/insee/onyxia/api/configuration/checks/DisableChecksForTests.java
@@ -1,12 +1,12 @@
package fr.insee.onyxia.api.configuration.checks;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
@Configuration
public class DisableChecksForTests {
- @MockBean CompatibilityChecks compatibilityChecks;
+ @MockitoBean CompatibilityChecks compatibilityChecks;
public CompatibilityChecks getCompatibilityChecks() {
return compatibilityChecks;
diff --git a/onyxia-api/src/test/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingControllerTest.java b/onyxia-api/src/test/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingControllerTest.java
index 4302b347..b0897c60 100644
--- a/onyxia-api/src/test/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingControllerTest.java
+++ b/onyxia-api/src/test/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingControllerTest.java
@@ -19,8 +19,8 @@
import fr.insee.onyxia.model.region.Region;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
@WebMvcTest(OnboardingController.class)
@@ -29,13 +29,13 @@ class OnboardingControllerTest extends BaseTest {
@Autowired private MockMvc mockMvc;
@Autowired private ObjectMapper mapper;
- @MockBean private UserProvider userProvider;
- @MockBean private RegionsConfiguration regionsConfiguration;
+ @MockitoBean private UserProvider userProvider;
+ @MockitoBean private RegionsConfiguration regionsConfiguration;
- @MockBean private HttpRequestUtils httpRequestUtils;
- @MockBean private SecurityConfig securityConfig;
- @MockBean private OnyxiaUserProvider onyxiaUserProvider;
- @MockBean private KubernetesService kubernetesService;
+ @MockitoBean private HttpRequestUtils httpRequestUtils;
+ @MockitoBean private SecurityConfig securityConfig;
+ @MockitoBean private OnyxiaUserProvider onyxiaUserProvider;
+ @MockitoBean private KubernetesService kubernetesService;
@Test
public void should_not_create_namespace_when_single_project() throws Exception {
diff --git a/onyxia-api/src/test/java/fr/insee/onyxia/api/user/OnyxiaUserProviderTest.java b/onyxia-api/src/test/java/fr/insee/onyxia/api/user/OnyxiaUserProviderTest.java
index c3a917ee..1c3c824a 100644
--- a/onyxia-api/src/test/java/fr/insee/onyxia/api/user/OnyxiaUserProviderTest.java
+++ b/onyxia-api/src/test/java/fr/insee/onyxia/api/user/OnyxiaUserProviderTest.java
@@ -18,16 +18,16 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
@SpringBootTest(classes = {OnyxiaUserProvider.class, UserProvider.class})
public class OnyxiaUserProviderTest {
@Autowired OnyxiaUserProvider onyxiaUserProvider;
- @MockBean private KubernetesService kubernetesService;
+ @MockitoBean private KubernetesService kubernetesService;
- @MockBean private UserProvider userProvider;
+ @MockitoBean private UserProvider userProvider;
Region region;
User user;
diff --git a/onyxia-model/pom.xml b/onyxia-model/pom.xml
index 0a7f2cb8..2e4fc40e 100644
--- a/onyxia-model/pom.xml
+++ b/onyxia-model/pom.xml
@@ -39,7 +39,7 @@
org.springdoc
springdoc-openapi-starter-common
- 2.10.0
+ 3.2.0