From 5727f0ffc5f4b63ca67726a59199295a73a2b518 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 10 Oct 2026 08:05:05 +0000
Subject: [PATCH 1/4] build(deps): bump the all-maven group in /services with 6
updates
Bumps the all-maven group in /services with 6 updates:
| Package | From | To |
| --- | --- | --- |
| [com.github.siom79.japicmp:japicmp-maven-plugin](https://github.com/siom79/japicmp) | `0.26.2` | `0.26.3` |
| [com.redis:testcontainers-redis](https://github.com/redis-field-engineering/testcontainers-redis) | `2.2.4` | `3.0.0` |
| org.redisson:redisson-spring-boot-starter | `4.7.0` | `4.8.0` |
| [com.meilisearch.sdk:meilisearch-java](https://github.com/meilisearch/meilisearch-java) | `0.21.0` | `0.22.1` |
| org.flywaydb:flyway-core | `13.8.1` | `13.9.0` |
| org.flywaydb:flyway-mysql | `13.8.1` | `13.9.0` |
Updates `com.github.siom79.japicmp:japicmp-maven-plugin` from 0.26.2 to 0.26.3
- [Release notes](https://github.com/siom79/japicmp/releases)
- [Changelog](https://github.com/siom79/japicmp/blob/master/release.py)
- [Commits](https://github.com/siom79/japicmp/compare/japicmp-base-0.26.2...japicmp-base-0.26.3)
Updates `com.redis:testcontainers-redis` from 2.2.4 to 3.0.0
- [Release notes](https://github.com/redis-field-engineering/testcontainers-redis/releases)
- [Commits](https://github.com/redis-field-engineering/testcontainers-redis/compare/v2.2.4...v3.0.0)
Updates `org.redisson:redisson-spring-boot-starter` from 4.7.0 to 4.8.0
Updates `com.meilisearch.sdk:meilisearch-java` from 0.21.0 to 0.22.1
- [Release notes](https://github.com/meilisearch/meilisearch-java/releases)
- [Commits](https://github.com/meilisearch/meilisearch-java/compare/v0.21.0...v0.22.1)
Updates `org.flywaydb:flyway-core` from 13.8.1 to 13.9.0
Updates `org.flywaydb:flyway-mysql` from 13.8.1 to 13.9.0
---
updated-dependencies:
- dependency-name: com.github.siom79.japicmp:japicmp-maven-plugin
dependency-version: 0.26.3
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: all-maven
- dependency-name: com.redis:testcontainers-redis
dependency-version: 3.0.0
dependency-type: direct:development
update-type: version-update:semver-major
dependency-group: all-maven
- dependency-name: org.redisson:redisson-spring-boot-starter
dependency-version: 4.8.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: all-maven
- dependency-name: com.meilisearch.sdk:meilisearch-java
dependency-version: 0.22.1
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: all-maven
- dependency-name: org.flywaydb:flyway-core
dependency-version: 13.9.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: all-maven
- dependency-name: org.flywaydb:flyway-mysql
dependency-version: 13.9.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: all-maven
...
Signed-off-by: dependabot[bot]
---
services/app/app-web/pom.xml | 6 +++---
services/core/pom.xml | 4 ++--
services/platform/web-security/pom.xml | 2 +-
services/pom.xml | 4 ++--
services/search/pom.xml | 2 +-
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/services/app/app-web/pom.xml b/services/app/app-web/pom.xml
index 2507ea074..e7852a8b2 100644
--- a/services/app/app-web/pom.xml
+++ b/services/app/app-web/pom.xml
@@ -91,7 +91,7 @@
com.meilisearch.sdk
meilisearch-java
- 0.21.0
+ 0.22.1
com.ulticode
@@ -230,7 +230,7 @@
org.flywaydb
flyway-core
- 13.8.1
+ 13.9.0
test
4.12.0
- 0.26.2
+ 0.26.3
0.50
diff --git a/services/search/pom.xml b/services/search/pom.xml
index 43316014a..dc359bdd6 100644
--- a/services/search/pom.xml
+++ b/services/search/pom.xml
@@ -90,7 +90,7 @@
com.meilisearch.sdk
meilisearch-java
- 0.21.0
+ 0.22.1
From 0a4462959b263ced2e96f295ae5f8fab0263a227 Mon Sep 17 00:00:00 2001
From: DavidHLP
Date: Sat, 10 Oct 2026 22:09:47 -0700
Subject: [PATCH 2/4] fix(deps): migrate backend to patched Spring Boot
baseline
---
docs/OPERATIONS.md | 4 ++
scripts/test/observability-contract.sh | 10 +++
scripts/test/supply-chain-contract.sh | 2 +-
services/admin/pom.xml | 20 ++++--
.../admin/src/main/resources/application.yml | 22 ++++---
.../ulticode/BackendAdminApplicationTest.java | 13 ++--
.../BackendAdminDatasourceContextIT.java | 7 +-
.../admin/config/AdminCacheConfigTest.java | 2 +-
.../AdminRouteAuthorizationContractTest.java | 2 +-
.../AdminAccountControllerTest.java | 4 +-
.../AdminContestControllerTest.java | 4 +-
.../AdminProblemListControllerTest.java | 4 +-
.../AdminSettingsControllerTest.java | 4 +-
.../AdminSubmissionControllerTest.java | 4 +-
.../controller/AdminTagControllerTest.java | 4 +-
.../controller/AuditControllerFormatTest.java | 4 +-
.../admin/outbox/AuditSinkTransactionIT.java | 7 +-
.../modules/backup/BackupRepositoryIT.java | 7 +-
services/app/app-web/pom.xml | 22 +++++--
.../src/main/resources/application.yml | 22 ++++---
.../ulticode/BackendAppApplicationTest.java | 4 +-
.../app/config/AppCacheConfigTest.java | 2 +-
.../app/config/AppRedisRoleConfigTest.java | 4 +-
.../app/dubbo/DubboBoot4LocalRoundTripIT.java | 64 +++++++++++++++++++
.../app/dubbo/boot4fixture/LocalEchoPort.java | 6 ++
.../dubbo/boot4fixture/LocalEchoService.java | 15 +++++
.../ContestAdministrationWiringIT.java | 10 +--
.../ProblemListAdministrationWiringIT.java | 10 +--
.../AppRouteAuthorizationContractTest.java | 2 +-
.../userprofile/ProfileWriteProviderIT.java | 12 ++--
.../ContestPublicControllerTest.java | 4 +-
.../ContestAdjudicationWiringIT.java | 10 +--
.../controller/ModerationControllerTest.java | 4 +-
.../controller/ProblemControllerTest.java | 4 +-
.../src/test/resources/application.yml | 4 +-
services/app/modules/contest/pom.xml | 2 +-
services/app/modules/moderation/pom.xml | 2 +-
services/app/modules/problem/pom.xml | 2 +-
services/auth/pom.xml | 21 +++++-
.../security/oauth/GithubOAuthClient.java | 2 +-
.../security/oauth/GoogleOAuthClient.java | 2 +-
.../security/oauth/OAuthAuthorizationUrl.java | 22 +++++++
.../auth/src/main/resources/application.yml | 17 +++--
.../ulticode/BackendAuthApplicationTest.java | 4 +-
.../error/AuthWebExceptionHandlerTest.java | 4 +-
.../AuthSecurityConfigContractTest.java | 2 +-
.../oauth/OAuthAuthorizationUrlTest.java | 23 +++++++
.../auth/src/test/resources/application.yml | 7 +-
services/core/pom.xml | 12 +++-
.../com/ulticode/core/CoreApplication.java | 12 ++--
.../core/CoreOwnerBootConfigurations.java | 4 +-
.../CoreOwnerDataSourceConfiguration.java | 2 +-
.../core/src/main/resources/application.yml | 3 +
.../core/CoreEnabledOwnerJourneyIT.java | 2 +-
services/judge-runtime/pom.xml | 2 +-
services/judge/pom.xml | 4 +-
.../judge/src/main/resources/application.yml | 22 ++++---
services/notification/pom.xml | 12 ++--
.../src/main/resources/application.yml | 20 ++++--
...icationRouteAuthorizationContractTest.java | 2 +-
services/platform/integration-inbox/pom.xml | 4 +-
services/platform/observability/pom.xml | 6 +-
.../config/OtlpSecurityAutoConfiguration.java | 11 ++--
.../OtlpSecurityAutoConfigurationTest.java | 25 +++++++-
services/platform/storage/pom.xml | 2 +-
services/platform/web-security/pom.xml | 15 +++--
.../config/WebSecurityAutoConfiguration.java | 4 +-
.../com/ulticode/websecurity/RateLimitIT.java | 8 +--
services/pom.xml | 8 +--
services/search/pom.xml | 10 ++-
.../search/src/main/resources/application.yml | 22 ++++---
services/submission/pom.xml | 6 +-
.../src/main/resources/application.yml | 15 +++--
.../BackendSubmissionApplicationTest.java | 2 +-
...ternalDelegationAssertionVerifierTest.java | 23 +++----
75 files changed, 480 insertions(+), 211 deletions(-)
create mode 100644 services/app/app-web/src/test/java/com/ulticode/app/dubbo/DubboBoot4LocalRoundTripIT.java
create mode 100644 services/app/app-web/src/test/java/com/ulticode/app/dubbo/boot4fixture/LocalEchoPort.java
create mode 100644 services/app/app-web/src/test/java/com/ulticode/app/dubbo/boot4fixture/LocalEchoService.java
create mode 100644 services/auth/src/main/java/com/ulticode/auth/security/oauth/OAuthAuthorizationUrl.java
create mode 100644 services/auth/src/test/java/com/ulticode/auth/security/oauth/OAuthAuthorizationUrlTest.java
diff --git a/docs/OPERATIONS.md b/docs/OPERATIONS.md
index e5c45b6d8..79c34b812 100644
--- a/docs/OPERATIONS.md
+++ b/docs/OPERATIONS.md
@@ -28,6 +28,8 @@ Trivy JSON reports are uploaded per candidate even when scanning fails; a failed
Runtime images retain pinned base-image digests and apply `apk upgrade --no-cache` for Alpine security updates. Both Verify and Publish bypass cache only for the final `runtime` (backend) or `production` (frontend) stage, so cached upgrade layers cannot retain newly vulnerable packages; builder caches remain enabled. Backend dependencies use Spring Boot's BOM with narrowly scoped security overrides; verify final dependency resolution and image scan results before release.
+Backend services retain Java 17 and use the Spring Boot 4 BOM for Spring Framework 7 and Tomcat 11. Existing JSON wire and persisted payload contracts remain on the documented `spring-boot-jackson2` compatibility module, selected by `spring.http.converters.preferred-json-mapper=jackson2`; Jackson 2 security overrides use `jackson-2-bom.version`, not the Jackson 3 BOM property. Do not mix Spring Framework 7 into a Boot 3 parent or retain a Tomcat 10 override under Boot 4. Dependency upgrades must pass owner-context, serialization, security and RPC checks as well as all nine image scans; reverting code must not rewrite application data or applied migrations.
+
`host-deploy` 在任何 migration、Redis ACL materialization、Judge sandbox provisioning 或 Compose mutation 前检查:
- approved source commit;
@@ -322,6 +324,8 @@ backup、restore-drill、prune 使用同一 fenced database lease(`admin:owner
可选的 `docker/docker-compose.observability.yml` 提供 loopback-only、digest-pinned 的 OpenTelemetry Collector、Prometheus、Alertmanager、Grafana、Tempo 和 Loki。HTTP Owner 暴露 metrics;无 HTTP 的 Judge/Search worker 通过 Micrometer OTLP 输出。日志携带 trace/span 关联,Grafana 可从 Loki 跳转 Tempo。
+Boot 4 tracing binds OTLP export settings under `management.opentelemetry.tracing.export.otlp`; the existing `MANAGEMENT_OTLP_TRACING_ENDPOINT` and `MANAGEMENT_OTLP_AUTHORIZATION` environment inputs remain unchanged. The shared observability module enables the tracing integration and validates the effective endpoint/header pair before export: a configured authorization header requires HTTPS. OTLP metrics configuration and the opt-in Collector overlays remain separate from tracing.
+
生产 telemetry receiver、存储、保留周期、通知 webhook、阈值调优和真实流量 SLO 由外部运维平台负责;仓库 overlay 默认不启动,也不公开 management endpoint 或 secret。
### 关键指标
diff --git a/scripts/test/observability-contract.sh b/scripts/test/observability-contract.sh
index 3732bd0ae..20c80dc7a 100755
--- a/scripts/test/observability-contract.sh
+++ b/scripts/test/observability-contract.sh
@@ -93,6 +93,16 @@ for service in services:
raise SystemExit(f"{path}: sampling default must be between 0 and 1")
if "Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}" not in text:
raise SystemExit(f"{path}: OTLP authorization header mapping is missing")
+ if service in ("notification", "search", "judge"):
+ metrics = re.search(
+ r"^ otlp:\n metrics:\n export:\n"
+ r" enabled: \$\{MANAGEMENT_OTLP_METRICS_ENABLED:false\}\n"
+ r" url: \$\{MANAGEMENT_OTLP_METRICS_ENDPOINT:http://localhost:4318/v1/metrics\}\n"
+ r" step: \$\{MANAGEMENT_OTLP_METRICS_STEP:30s\}$",
+ text, re.MULTILINE,
+ )
+ if metrics is None:
+ raise SystemExit(f"{path}: OTLP metrics must retain management.otlp.metrics.export bindings")
PY
printf 'owner OTLP sampling and authorization bindings: PASS\n'
contains .github/services-matrix.json '"artifact": "backend-search-exec.jar"'
diff --git a/scripts/test/supply-chain-contract.sh b/scripts/test/supply-chain-contract.sh
index 9b4ba55c0..513f62ef3 100755
--- a/scripts/test/supply-chain-contract.sh
+++ b/scripts/test/supply-chain-contract.sh
@@ -165,7 +165,7 @@ python3 "$ROOT_DIR/scripts/test/promote-release-contract.py"
contains .github/workflows/_docker.yml 'load: true'
contains .github/workflows/_docker.yml 'TRIVY_IMAGE_SRC: docker'
contains .github/workflows/_docker.yml 'name: trivy-verify-${{ matrix.service.name }}'
-contains services/pom.xml '2.21.7'
+contains services/pom.xml '2.21.7'
contains .github/workflows/docker-publish.yml 'sbom: true'
for entry in '_docker.yml:verify' 'docker-publish.yml:publish'; do
diff --git a/services/admin/pom.xml b/services/admin/pom.xml
index e2b4d6464..5a0c7e441 100644
--- a/services/admin/pom.xml
+++ b/services/admin/pom.xml
@@ -75,7 +75,7 @@
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-webmvc
org.springframework.boot
@@ -154,7 +154,7 @@
com.baomidou
- mybatis-plus-spring-boot3-starter
+ mybatis-plus-spring-boot4-starter
${mybatis-plus.version}
@@ -172,12 +172,12 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
- org.springframework.security
- spring-security-test
+ org.springframework.boot
+ spring-boot-starter-security-test
test
@@ -196,6 +196,16 @@
mysql
test
+
+ org.springframework.boot
+ spring-boot-resttestclient
+ test
+
+
+ org.springframework.boot
+ spring-boot-restclient
+ test
+
diff --git a/services/admin/src/main/resources/application.yml b/services/admin/src/main/resources/application.yml
index 3761cc4d1..9c254b630 100644
--- a/services/admin/src/main/resources/application.yml
+++ b/services/admin/src/main/resources/application.yml
@@ -3,6 +3,9 @@ server:
shutdown: graceful
spring:
+ http:
+ converters:
+ preferred-json-mapper: jackson2
application:
name: backend-admin
servlet:
@@ -13,9 +16,10 @@ spring:
timeout-per-shutdown-phase: ${SPRING_LIFECYCLE_TIMEOUT_PER_SHUTDOWN_PHASE:45s}
autoconfigure:
exclude:
- - org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
- - org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
- - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
+ - org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration
+ - org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.UserDetailsServiceAutoConfiguration
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${ADMIN_DB_URL:jdbc:mysql://${ADMIN_DB_HOST}:${ADMIN_DB_PORT}/${ADMIN_DB_NAME}?useUnicode=true&characterEncoding=UTF-8&characterSetResults=utf8mb4&connectionCollation=utf8mb4_unicode_ci&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&sslMode=${ADMIN_DB_SSL_MODE:REQUIRED}}
@@ -119,12 +123,14 @@ management:
tracing:
sampling:
probability: ${MANAGEMENT_TRACING_SAMPLING_PROBABILITY:1.0}
- otlp:
+ opentelemetry:
tracing:
- endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
- headers:
- Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
- timeout: 5s
+ export:
+ otlp:
+ endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
+ headers:
+ Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
+ timeout: 5s
security:
internal-delegation:
diff --git a/services/admin/src/test/java/com/ulticode/BackendAdminApplicationTest.java b/services/admin/src/test/java/com/ulticode/BackendAdminApplicationTest.java
index 50a2b153d..defd38781 100644
--- a/services/admin/src/test/java/com/ulticode/BackendAdminApplicationTest.java
+++ b/services/admin/src/test/java/com/ulticode/BackendAdminApplicationTest.java
@@ -7,7 +7,8 @@
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.web.client.TestRestTemplate;
+import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate;
+import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -20,17 +21,19 @@
* infrastructure that is not available in a plain unit test.
*/
@Disabled("Requires Redis/MySQL infrastructure — convert to Testcontainers IT (P7-RELOCATE-ADMIN-001)")
+@AutoConfigureTestRestTemplate
@SpringBootTest(
classes = BackendAdminApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {
"spring.main.allow-bean-definition-overriding=true",
"spring.autoconfigure.exclude="
- + "org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,"
- + "org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,"
- + "org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,"
+ + "org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration,"
+ + "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration,"
+ + "org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration,"
+ "org.redisson.spring.starter.RedissonAutoConfigurationV2,"
- + "org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,"
+ + "org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration,"
+ + "org.springframework.boot.security.autoconfigure.UserDetailsServiceAutoConfiguration,"
+ "org.apache.dubbo.spring.boot.autoconfigure.DubboAutoConfiguration,"
+ "com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapAutoConfiguration",
"spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver",
diff --git a/services/admin/src/test/java/com/ulticode/admin/BackendAdminDatasourceContextIT.java b/services/admin/src/test/java/com/ulticode/admin/BackendAdminDatasourceContextIT.java
index fee0ca121..955f44446 100644
--- a/services/admin/src/test/java/com/ulticode/admin/BackendAdminDatasourceContextIT.java
+++ b/services/admin/src/test/java/com/ulticode/admin/BackendAdminDatasourceContextIT.java
@@ -22,9 +22,10 @@
import org.testcontainers.junit.jupiter.Testcontainers;
@SpringBootTest(classes = BackendAdminApplication.class, properties = "spring.autoconfigure.exclude="
- + "org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,"
- + "org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,"
- + "org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,"
+ + "org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration,"
+ + "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration,"
+ + "org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration,"
+ + "org.springframework.boot.security.autoconfigure.UserDetailsServiceAutoConfiguration,"
+ "org.apache.dubbo.spring.boot.autoconfigure.DubboAutoConfiguration,"
+ "com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapAutoConfiguration")
@Testcontainers
diff --git a/services/admin/src/test/java/com/ulticode/admin/config/AdminCacheConfigTest.java b/services/admin/src/test/java/com/ulticode/admin/config/AdminCacheConfigTest.java
index daf178b4f..3a5cecbd2 100644
--- a/services/admin/src/test/java/com/ulticode/admin/config/AdminCacheConfigTest.java
+++ b/services/admin/src/test/java/com/ulticode/admin/config/AdminCacheConfigTest.java
@@ -35,7 +35,7 @@ void cacheClearEvictsThroughScan() {
when(connectionFactory.getConnection()).thenReturn(connection);
when(connection.keyCommands()).thenReturn(keyCommands);
AtomicReference scan = new AtomicReference<>();
- when(connection.scan(any(ScanOptions.class))).thenAnswer(call -> {
+ when(keyCommands.scan(any(ScanOptions.class))).thenAnswer(call -> {
scan.set(call.getArgument(0));
throw new IllegalStateException("scan reached");
});
diff --git a/services/admin/src/test/java/com/ulticode/admin/security/AdminRouteAuthorizationContractTest.java b/services/admin/src/test/java/com/ulticode/admin/security/AdminRouteAuthorizationContractTest.java
index 8aebde941..5c70e81d0 100644
--- a/services/admin/src/test/java/com/ulticode/admin/security/AdminRouteAuthorizationContractTest.java
+++ b/services/admin/src/test/java/com/ulticode/admin/security/AdminRouteAuthorizationContractTest.java
@@ -7,7 +7,7 @@
import com.ulticode.websecurity.jwt.AccessTokenVerifier;
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.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.MockMvc;
diff --git a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminAccountControllerTest.java b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminAccountControllerTest.java
index 3cd70bfa1..41d1263e5 100644
--- a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminAccountControllerTest.java
+++ b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminAccountControllerTest.java
@@ -17,8 +17,8 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
diff --git a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminContestControllerTest.java b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminContestControllerTest.java
index ddae6a739..1a07bf0b3 100644
--- a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminContestControllerTest.java
+++ b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminContestControllerTest.java
@@ -11,8 +11,8 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
diff --git a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminProblemListControllerTest.java b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminProblemListControllerTest.java
index f8c57181d..fc31322dc 100644
--- a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminProblemListControllerTest.java
+++ b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminProblemListControllerTest.java
@@ -14,8 +14,8 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
diff --git a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminSettingsControllerTest.java b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminSettingsControllerTest.java
index a3cc71f4a..ac8541ba4 100644
--- a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminSettingsControllerTest.java
+++ b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminSettingsControllerTest.java
@@ -15,8 +15,8 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
diff --git a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminSubmissionControllerTest.java b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminSubmissionControllerTest.java
index bba00df10..d090f9d88 100644
--- a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminSubmissionControllerTest.java
+++ b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminSubmissionControllerTest.java
@@ -13,8 +13,8 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
diff --git a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminTagControllerTest.java b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminTagControllerTest.java
index 9646ab80c..54d3e36f6 100644
--- a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminTagControllerTest.java
+++ b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AdminTagControllerTest.java
@@ -11,8 +11,8 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
diff --git a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AuditControllerFormatTest.java b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AuditControllerFormatTest.java
index b1bfa03d0..23d1c0410 100644
--- a/services/admin/src/test/java/com/ulticode/modules/admin/controller/AuditControllerFormatTest.java
+++ b/services/admin/src/test/java/com/ulticode/modules/admin/controller/AuditControllerFormatTest.java
@@ -8,8 +8,8 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+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.context.ContextConfiguration;
diff --git a/services/admin/src/test/java/com/ulticode/modules/admin/outbox/AuditSinkTransactionIT.java b/services/admin/src/test/java/com/ulticode/modules/admin/outbox/AuditSinkTransactionIT.java
index 12b5640e9..ffb8ecbb2 100644
--- a/services/admin/src/test/java/com/ulticode/modules/admin/outbox/AuditSinkTransactionIT.java
+++ b/services/admin/src/test/java/com/ulticode/modules/admin/outbox/AuditSinkTransactionIT.java
@@ -24,9 +24,10 @@
import org.testcontainers.junit.jupiter.Testcontainers;
@SpringBootTest(properties = "spring.autoconfigure.exclude="
- + "org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,"
- + "org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,"
- + "org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,"
+ + "org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration,"
+ + "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration,"
+ + "org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration,"
+ + "org.springframework.boot.security.autoconfigure.UserDetailsServiceAutoConfiguration,"
+ "org.apache.dubbo.spring.boot.autoconfigure.DubboAutoConfiguration,"
+ "com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapAutoConfiguration")
@Testcontainers
diff --git a/services/admin/src/test/java/com/ulticode/modules/backup/BackupRepositoryIT.java b/services/admin/src/test/java/com/ulticode/modules/backup/BackupRepositoryIT.java
index 03c5f71f0..1540d6dbd 100644
--- a/services/admin/src/test/java/com/ulticode/modules/backup/BackupRepositoryIT.java
+++ b/services/admin/src/test/java/com/ulticode/modules/backup/BackupRepositoryIT.java
@@ -40,9 +40,10 @@
* MyBatis-Plus {@link BackupMapper} against a real MySQL 8.0 container.
*/
@SpringBootTest(properties = "spring.autoconfigure.exclude="
- + "org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,"
- + "org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,"
- + "org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,"
+ + "org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration,"
+ + "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration,"
+ + "org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration,"
+ + "org.springframework.boot.security.autoconfigure.UserDetailsServiceAutoConfiguration,"
+ "org.apache.dubbo.spring.boot.autoconfigure.DubboAutoConfiguration,"
+ "com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapAutoConfiguration")
@Testcontainers
diff --git a/services/app/app-web/pom.xml b/services/app/app-web/pom.xml
index 2507ea074..15164cbe8 100644
--- a/services/app/app-web/pom.xml
+++ b/services/app/app-web/pom.xml
@@ -101,7 +101,7 @@
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-webmvc
org.springframework.boot
@@ -114,7 +114,7 @@
org.springframework.boot
- spring-boot-starter-aop
+ spring-boot-starter-aspectj
@@ -128,7 +128,7 @@
com.baomidou
- mybatis-plus-spring-boot3-starter
+ mybatis-plus-spring-boot4-starter
${mybatis-plus.version}
@@ -202,12 +202,12 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
- org.springframework.security
- spring-security-test
+ org.springframework.boot
+ spring-boot-starter-security-test
test
@@ -256,6 +256,16 @@
org.springframework.boot
spring-boot-starter-websocket
+
+ org.springframework.boot
+ spring-boot-resttestclient
+ test
+
+
+ org.springframework.boot
+ spring-boot-restclient
+ test
+
diff --git a/services/app/app-web/src/main/resources/application.yml b/services/app/app-web/src/main/resources/application.yml
index 248ffe611..01ed5e594 100644
--- a/services/app/app-web/src/main/resources/application.yml
+++ b/services/app/app-web/src/main/resources/application.yml
@@ -3,6 +3,9 @@ server:
shutdown: graceful
spring:
+ http:
+ converters:
+ preferred-json-mapper: jackson2
application:
name: backend-app
servlet:
@@ -13,9 +16,10 @@ spring:
timeout-per-shutdown-phase: ${SPRING_LIFECYCLE_TIMEOUT_PER_SHUTDOWN_PHASE:45s}
autoconfigure:
exclude:
- - org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
- - org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
- - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
+ - org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration
+ - org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.UserDetailsServiceAutoConfiguration
# P7-MIGRATE-PROBLEM-001: enable datasource for problem domain
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
@@ -152,12 +156,14 @@ management:
tracing:
sampling:
probability: ${MANAGEMENT_TRACING_SAMPLING_PROBABILITY:1.0}
- otlp:
+ opentelemetry:
tracing:
- endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
- headers:
- Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
- timeout: 5s
+ export:
+ otlp:
+ endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
+ headers:
+ Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
+ timeout: 5s
security:
internal-delegation:
diff --git a/services/app/app-web/src/test/java/com/ulticode/BackendAppApplicationTest.java b/services/app/app-web/src/test/java/com/ulticode/BackendAppApplicationTest.java
index 0fd3c9069..c3d48b1a2 100644
--- a/services/app/app-web/src/test/java/com/ulticode/BackendAppApplicationTest.java
+++ b/services/app/app-web/src/test/java/com/ulticode/BackendAppApplicationTest.java
@@ -22,8 +22,9 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
-import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
@@ -33,6 +34,7 @@
/**
* P1-INFRA-005: verify the app service shell boots and exposes health.
*/
+@AutoConfigureTestRestTemplate
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
class BackendAppApplicationTest {
diff --git a/services/app/app-web/src/test/java/com/ulticode/app/config/AppCacheConfigTest.java b/services/app/app-web/src/test/java/com/ulticode/app/config/AppCacheConfigTest.java
index 6509f5f9d..c3ddb0c0e 100644
--- a/services/app/app-web/src/test/java/com/ulticode/app/config/AppCacheConfigTest.java
+++ b/services/app/app-web/src/test/java/com/ulticode/app/config/AppCacheConfigTest.java
@@ -36,7 +36,7 @@ void cacheClearEvictsThroughScan() {
when(connectionFactory.getConnection()).thenReturn(connection);
when(connection.keyCommands()).thenReturn(keyCommands);
AtomicReference scan = new AtomicReference<>();
- when(connection.scan(any(ScanOptions.class))).thenAnswer(call -> {
+ when(keyCommands.scan(any(ScanOptions.class))).thenAnswer(call -> {
scan.set(call.getArgument(0));
throw new IllegalStateException("scan reached");
});
diff --git a/services/app/app-web/src/test/java/com/ulticode/app/config/AppRedisRoleConfigTest.java b/services/app/app-web/src/test/java/com/ulticode/app/config/AppRedisRoleConfigTest.java
index ffa73644e..51670240c 100644
--- a/services/app/app-web/src/test/java/com/ulticode/app/config/AppRedisRoleConfigTest.java
+++ b/services/app/app-web/src/test/java/com/ulticode/app/config/AppRedisRoleConfigTest.java
@@ -2,7 +2,7 @@
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
-import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.data.redis.connection.RedisConnectionFactory;
@@ -12,7 +12,7 @@ class AppRedisRoleConfigTest {
private final ApplicationContextRunner runner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
- RedisAutoConfiguration.class,
+ DataRedisAutoConfiguration.class,
AppRedisRoleConfig.class));
@Test
diff --git a/services/app/app-web/src/test/java/com/ulticode/app/dubbo/DubboBoot4LocalRoundTripIT.java b/services/app/app-web/src/test/java/com/ulticode/app/dubbo/DubboBoot4LocalRoundTripIT.java
new file mode 100644
index 000000000..d8b8b7891
--- /dev/null
+++ b/services/app/app-web/src/test/java/com/ulticode/app/dubbo/DubboBoot4LocalRoundTripIT.java
@@ -0,0 +1,64 @@
+package com.ulticode.app.dubbo;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.ulticode.app.dubbo.boot4fixture.LocalEchoPort;
+import com.ulticode.app.dubbo.boot4fixture.LocalEchoService;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.apache.dubbo.spring.boot.autoconfigure.DubboAutoConfiguration;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.annotation.DirtiesContext;
+
+@SpringBootTest(
+ classes = DubboBoot4LocalRoundTripIT.TestApplication.class,
+ properties = {
+ "dubbo.application.name=boot4-dubbo-local-roundtrip-test",
+ "dubbo.application.qos-enable=false",
+ "dubbo.registry.address=N/A",
+ "dubbo.protocol.port=-1"
+ })
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+class DubboBoot4LocalRoundTripIT {
+
+ @Autowired
+ private EchoClient client;
+
+ @Test
+ @Timeout(15)
+ void bootAutoConfigurationWiresLocalServiceReferenceWithoutRegistry() {
+ assertThat(client.echo("boot4")).isEqualTo("echo:boot4");
+ }
+
+ @SpringBootConfiguration(proxyBeanMethods = false)
+ @EnableDubbo(scanBasePackageClasses = LocalEchoService.class)
+ @ImportAutoConfiguration(DubboAutoConfiguration.class)
+ @Import(ClientConfiguration.class)
+ static class TestApplication {
+ }
+
+ static class EchoClient {
+
+ @DubboReference(interfaceClass = LocalEchoPort.class, scope = "local", check = false, retries = 0)
+ private LocalEchoPort echoPort;
+
+ String echo(String value) {
+ return echoPort.echo(value);
+ }
+ }
+
+ static class ClientConfiguration {
+
+ @Bean
+ EchoClient echoClient() {
+ return new EchoClient();
+ }
+ }
+}
diff --git a/services/app/app-web/src/test/java/com/ulticode/app/dubbo/boot4fixture/LocalEchoPort.java b/services/app/app-web/src/test/java/com/ulticode/app/dubbo/boot4fixture/LocalEchoPort.java
new file mode 100644
index 000000000..9e62d97e9
--- /dev/null
+++ b/services/app/app-web/src/test/java/com/ulticode/app/dubbo/boot4fixture/LocalEchoPort.java
@@ -0,0 +1,6 @@
+package com.ulticode.app.dubbo.boot4fixture;
+
+public interface LocalEchoPort {
+
+ String echo(String value);
+}
diff --git a/services/app/app-web/src/test/java/com/ulticode/app/dubbo/boot4fixture/LocalEchoService.java b/services/app/app-web/src/test/java/com/ulticode/app/dubbo/boot4fixture/LocalEchoService.java
new file mode 100644
index 000000000..380fbcee1
--- /dev/null
+++ b/services/app/app-web/src/test/java/com/ulticode/app/dubbo/boot4fixture/LocalEchoService.java
@@ -0,0 +1,15 @@
+package com.ulticode.app.dubbo.boot4fixture;
+
+import org.apache.dubbo.config.annotation.DubboService;
+
+@DubboService(
+ interfaceClass = LocalEchoPort.class,
+ scope = "local",
+ register = false)
+public class LocalEchoService implements LocalEchoPort {
+
+ @Override
+ public String echo(String value) {
+ return "echo:" + value;
+ }
+}
diff --git a/services/app/app-web/src/test/java/com/ulticode/app/dubbo/provider/ContestAdministrationWiringIT.java b/services/app/app-web/src/test/java/com/ulticode/app/dubbo/provider/ContestAdministrationWiringIT.java
index 28ed5b326..a70a5c256 100644
--- a/services/app/app-web/src/test/java/com/ulticode/app/dubbo/provider/ContestAdministrationWiringIT.java
+++ b/services/app/app-web/src/test/java/com/ulticode/app/dubbo/provider/ContestAdministrationWiringIT.java
@@ -39,10 +39,10 @@
import org.junit.jupiter.api.Test;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
-import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
+import org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -69,7 +69,7 @@
DataSourceTransactionManagerAutoConfiguration.class,
TransactionAutoConfiguration.class,
MybatisPlusAutoConfiguration.class,
- JacksonAutoConfiguration.class
+ Jackson2AutoConfiguration.class
},
properties = {
"spring.flyway.enabled=false",
diff --git a/services/app/app-web/src/test/java/com/ulticode/app/dubbo/provider/ProblemListAdministrationWiringIT.java b/services/app/app-web/src/test/java/com/ulticode/app/dubbo/provider/ProblemListAdministrationWiringIT.java
index 9d5f133db..fb550d827 100644
--- a/services/app/app-web/src/test/java/com/ulticode/app/dubbo/provider/ProblemListAdministrationWiringIT.java
+++ b/services/app/app-web/src/test/java/com/ulticode/app/dubbo/provider/ProblemListAdministrationWiringIT.java
@@ -30,10 +30,10 @@
import java.util.UUID;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
-import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
+import org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.junit.jupiter.api.BeforeEach;
@@ -59,7 +59,7 @@
DataSourceTransactionManagerAutoConfiguration.class,
TransactionAutoConfiguration.class,
MybatisPlusAutoConfiguration.class,
- JacksonAutoConfiguration.class
+ Jackson2AutoConfiguration.class
},
properties = {
"spring.flyway.enabled=false",
diff --git a/services/app/app-web/src/test/java/com/ulticode/app/security/AppRouteAuthorizationContractTest.java b/services/app/app-web/src/test/java/com/ulticode/app/security/AppRouteAuthorizationContractTest.java
index fb3b2b599..5f8164dfc 100644
--- a/services/app/app-web/src/test/java/com/ulticode/app/security/AppRouteAuthorizationContractTest.java
+++ b/services/app/app-web/src/test/java/com/ulticode/app/security/AppRouteAuthorizationContractTest.java
@@ -10,7 +10,7 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.MockMvc;
diff --git a/services/app/app-web/src/test/java/com/ulticode/app/userprofile/ProfileWriteProviderIT.java b/services/app/app-web/src/test/java/com/ulticode/app/userprofile/ProfileWriteProviderIT.java
index 05c3d202e..fcffcc711 100644
--- a/services/app/app-web/src/test/java/com/ulticode/app/userprofile/ProfileWriteProviderIT.java
+++ b/services/app/app-web/src/test/java/com/ulticode/app/userprofile/ProfileWriteProviderIT.java
@@ -44,11 +44,11 @@
import org.junit.jupiter.api.Test;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
-import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
+import org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration;
+import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
@@ -85,7 +85,7 @@
TransactionAutoConfiguration.class,
JdbcTemplateAutoConfiguration.class,
MybatisPlusAutoConfiguration.class,
- JacksonAutoConfiguration.class
+ Jackson2AutoConfiguration.class
},
properties = {
"spring.flyway.enabled=false",
diff --git a/services/app/app-web/src/test/java/com/ulticode/modules/contest/controller/ContestPublicControllerTest.java b/services/app/app-web/src/test/java/com/ulticode/modules/contest/controller/ContestPublicControllerTest.java
index 8002c3ca2..d2185df03 100644
--- a/services/app/app-web/src/test/java/com/ulticode/modules/contest/controller/ContestPublicControllerTest.java
+++ b/services/app/app-web/src/test/java/com/ulticode/modules/contest/controller/ContestPublicControllerTest.java
@@ -15,8 +15,8 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
diff --git a/services/app/app-web/src/test/java/com/ulticode/modules/contest/integration/ContestAdjudicationWiringIT.java b/services/app/app-web/src/test/java/com/ulticode/modules/contest/integration/ContestAdjudicationWiringIT.java
index cade00052..1837cf7c1 100644
--- a/services/app/app-web/src/test/java/com/ulticode/modules/contest/integration/ContestAdjudicationWiringIT.java
+++ b/services/app/app-web/src/test/java/com/ulticode/modules/contest/integration/ContestAdjudicationWiringIT.java
@@ -22,10 +22,10 @@
import org.junit.jupiter.api.Test;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
-import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
+import org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -77,7 +77,7 @@
DataSourceTransactionManagerAutoConfiguration.class,
TransactionAutoConfiguration.class,
MybatisPlusAutoConfiguration.class,
- JacksonAutoConfiguration.class,
+ Jackson2AutoConfiguration.class,
ScoringStrategyResolver.class,
ScoreStrategy.class,
IcpcStrategy.class,
diff --git a/services/app/app-web/src/test/java/com/ulticode/modules/moderation/controller/ModerationControllerTest.java b/services/app/app-web/src/test/java/com/ulticode/modules/moderation/controller/ModerationControllerTest.java
index 87194835c..751278279 100644
--- a/services/app/app-web/src/test/java/com/ulticode/modules/moderation/controller/ModerationControllerTest.java
+++ b/services/app/app-web/src/test/java/com/ulticode/modules/moderation/controller/ModerationControllerTest.java
@@ -14,8 +14,8 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
diff --git a/services/app/app-web/src/test/java/com/ulticode/modules/problem/controller/ProblemControllerTest.java b/services/app/app-web/src/test/java/com/ulticode/modules/problem/controller/ProblemControllerTest.java
index d030e5948..1dedcf5fa 100644
--- a/services/app/app-web/src/test/java/com/ulticode/modules/problem/controller/ProblemControllerTest.java
+++ b/services/app/app-web/src/test/java/com/ulticode/modules/problem/controller/ProblemControllerTest.java
@@ -11,8 +11,8 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
diff --git a/services/app/app-web/src/test/resources/application.yml b/services/app/app-web/src/test/resources/application.yml
index a4c1ce338..2a2e56e35 100644
--- a/services/app/app-web/src/test/resources/application.yml
+++ b/services/app/app-web/src/test/resources/application.yml
@@ -6,8 +6,8 @@ spring:
active: test
autoconfigure:
exclude:
- - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
- - org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
+ - org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration
+ - org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration
- org.redisson.spring.starter.RedissonAutoConfigurationV2
- org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
diff --git a/services/app/modules/contest/pom.xml b/services/app/modules/contest/pom.xml
index 6edace681..03e0b4a76 100644
--- a/services/app/modules/contest/pom.xml
+++ b/services/app/modules/contest/pom.xml
@@ -49,7 +49,7 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
diff --git a/services/app/modules/moderation/pom.xml b/services/app/modules/moderation/pom.xml
index af347ab08..7955c0c9d 100644
--- a/services/app/modules/moderation/pom.xml
+++ b/services/app/modules/moderation/pom.xml
@@ -35,7 +35,7 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
diff --git a/services/app/modules/problem/pom.xml b/services/app/modules/problem/pom.xml
index 83dedec99..2dfdad529 100644
--- a/services/app/modules/problem/pom.xml
+++ b/services/app/modules/problem/pom.xml
@@ -50,7 +50,7 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
diff --git a/services/auth/pom.xml b/services/auth/pom.xml
index a4bd35587..31c16dbce 100644
--- a/services/auth/pom.xml
+++ b/services/auth/pom.xml
@@ -55,7 +55,7 @@
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-webmvc
org.springframework.boot
@@ -81,7 +81,7 @@
com.baomidou
- mybatis-plus-spring-boot3-starter
+ mybatis-plus-spring-boot4-starter
${mybatis-plus.version}
@@ -165,7 +165,22 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-security-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-resttestclient
+ test
+
+
+ org.springframework.boot
+ spring-boot-restclient
test
diff --git a/services/auth/src/main/java/com/ulticode/auth/security/oauth/GithubOAuthClient.java b/services/auth/src/main/java/com/ulticode/auth/security/oauth/GithubOAuthClient.java
index 05d0625ce..d55ab77fd 100644
--- a/services/auth/src/main/java/com/ulticode/auth/security/oauth/GithubOAuthClient.java
+++ b/services/auth/src/main/java/com/ulticode/auth/security/oauth/GithubOAuthClient.java
@@ -37,7 +37,7 @@ public String getProviderName() {
@Override
public String buildAuthorizationUrl(String state, String redirectUri) {
OAuthProperties.OAuthProvider config = oauthProperties.getGithub();
- return UriComponentsBuilder.fromHttpUrl(config.getAuthorizeUrl())
+ return OAuthAuthorizationUrl.fromTrustedHttpUrl(config.getAuthorizeUrl())
.queryParam("client_id", config.getClientId())
.queryParam("redirect_uri", redirectUri)
.queryParam("scope", config.getScopes())
diff --git a/services/auth/src/main/java/com/ulticode/auth/security/oauth/GoogleOAuthClient.java b/services/auth/src/main/java/com/ulticode/auth/security/oauth/GoogleOAuthClient.java
index 79865416a..3fa419dbd 100644
--- a/services/auth/src/main/java/com/ulticode/auth/security/oauth/GoogleOAuthClient.java
+++ b/services/auth/src/main/java/com/ulticode/auth/security/oauth/GoogleOAuthClient.java
@@ -37,7 +37,7 @@ public String getProviderName() {
@Override
public String buildAuthorizationUrl(String state, String redirectUri) {
OAuthProperties.OAuthProvider config = oauthProperties.getGoogle();
- return UriComponentsBuilder.fromHttpUrl(config.getAuthorizeUrl())
+ return OAuthAuthorizationUrl.fromTrustedHttpUrl(config.getAuthorizeUrl())
.queryParam("client_id", config.getClientId())
.queryParam("redirect_uri", redirectUri)
.queryParam("response_type", "code")
diff --git a/services/auth/src/main/java/com/ulticode/auth/security/oauth/OAuthAuthorizationUrl.java b/services/auth/src/main/java/com/ulticode/auth/security/oauth/OAuthAuthorizationUrl.java
new file mode 100644
index 000000000..0025cbcc7
--- /dev/null
+++ b/services/auth/src/main/java/com/ulticode/auth/security/oauth/OAuthAuthorizationUrl.java
@@ -0,0 +1,22 @@
+package com.ulticode.auth.security.oauth;
+
+import java.net.URI;
+
+import org.springframework.web.util.UriComponentsBuilder;
+
+/** Validates trusted provider authorization endpoints before URI construction. */
+final class OAuthAuthorizationUrl {
+
+ private OAuthAuthorizationUrl() {
+ }
+
+ static UriComponentsBuilder fromTrustedHttpUrl(String value) {
+ URI endpoint = URI.create(value);
+ String scheme = endpoint.getScheme();
+ if (!endpoint.isAbsolute() || endpoint.getHost() == null
+ || !("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme))) {
+ throw new IllegalArgumentException("OAuth authorization URL must be an absolute HTTP(S) URL");
+ }
+ return UriComponentsBuilder.fromUriString(value);
+ }
+}
diff --git a/services/auth/src/main/resources/application.yml b/services/auth/src/main/resources/application.yml
index cb1d55c65..0de22d93f 100644
--- a/services/auth/src/main/resources/application.yml
+++ b/services/auth/src/main/resources/application.yml
@@ -13,6 +13,9 @@ cors:
allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:9002,http://localhost:9003}
spring:
+ http:
+ converters:
+ preferred-json-mapper: jackson2
application:
name: backend-auth
lifecycle:
@@ -49,7 +52,7 @@ spring:
max-idle: 8
min-idle: 0
- jackson:
+ jackson2:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: Asia/Shanghai
flyway:
@@ -188,12 +191,14 @@ management:
tracing:
sampling:
probability: ${MANAGEMENT_TRACING_SAMPLING_PROBABILITY:1.0}
- otlp:
+ opentelemetry:
tracing:
- endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
- headers:
- Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
- timeout: 5s
+ export:
+ otlp:
+ endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
+ headers:
+ Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
+ timeout: 5s
security:
internal-delegation:
# Base64-encoded X509 public key; Auth never receives Admin private material.
diff --git a/services/auth/src/test/java/com/ulticode/BackendAuthApplicationTest.java b/services/auth/src/test/java/com/ulticode/BackendAuthApplicationTest.java
index f6e66a1e4..b5ea5f807 100644
--- a/services/auth/src/test/java/com/ulticode/BackendAuthApplicationTest.java
+++ b/services/auth/src/test/java/com/ulticode/BackendAuthApplicationTest.java
@@ -6,7 +6,8 @@
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.web.client.TestRestTemplate;
+import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate;
+import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -15,6 +16,7 @@
* P1-INFRA-005: verify the populated auth service boots and exposes health.
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@AutoConfigureTestRestTemplate
class BackendAuthApplicationTest {
@LocalServerPort
diff --git a/services/auth/src/test/java/com/ulticode/auth/error/AuthWebExceptionHandlerTest.java b/services/auth/src/test/java/com/ulticode/auth/error/AuthWebExceptionHandlerTest.java
index f3b48bb3e..b45d95743 100644
--- a/services/auth/src/test/java/com/ulticode/auth/error/AuthWebExceptionHandlerTest.java
+++ b/services/auth/src/test/java/com/ulticode/auth/error/AuthWebExceptionHandlerTest.java
@@ -67,7 +67,7 @@ void omitsRetryAfterWhenRateLimitMessageHasNoValidSeconds() {
ResponseEntity> response = handler.handleBusinessException(exception);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.TOO_MANY_REQUESTS);
- assertThat(response.getHeaders()).doesNotContainKey(HttpHeaders.RETRY_AFTER);
+ assertThat(response.getHeaders().containsHeader(HttpHeaders.RETRY_AFTER)).isFalse();
assertThat(response.getBody()).isNotNull();
assertThat(response.getBody().getCode()).isEqualTo(42900);
}
@@ -83,7 +83,7 @@ void preservesAuthErrorCodesAndStatuses(AuthErrorCode errorCode, HttpStatus stat
ResponseEntity> response = handler.handleAuthBusinessException(exception);
assertThat(response.getStatusCode()).isEqualTo(status);
- assertThat(response.getHeaders()).doesNotContainKey(HttpHeaders.RETRY_AFTER);
+ assertThat(response.getHeaders().containsHeader(HttpHeaders.RETRY_AFTER)).isFalse();
assertThat(response.getBody()).isNotNull();
assertThat(response.getBody().getCode()).isEqualTo(errorCode.code());
assertThat(response.getBody().getMessage()).isEqualTo(errorCode.message());
diff --git a/services/auth/src/test/java/com/ulticode/auth/security/AuthSecurityConfigContractTest.java b/services/auth/src/test/java/com/ulticode/auth/security/AuthSecurityConfigContractTest.java
index 081d3c820..68f168665 100644
--- a/services/auth/src/test/java/com/ulticode/auth/security/AuthSecurityConfigContractTest.java
+++ b/services/auth/src/test/java/com/ulticode/auth/security/AuthSecurityConfigContractTest.java
@@ -3,7 +3,7 @@
import com.ulticode.auth.security.jwt.AuthAccessTokenVerifier;
import com.ulticode.auth.security.jwt.AuthJwtFilterConfiguration;
import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.GetMapping;
diff --git a/services/auth/src/test/java/com/ulticode/auth/security/oauth/OAuthAuthorizationUrlTest.java b/services/auth/src/test/java/com/ulticode/auth/security/oauth/OAuthAuthorizationUrlTest.java
new file mode 100644
index 000000000..16f8409a2
--- /dev/null
+++ b/services/auth/src/test/java/com/ulticode/auth/security/oauth/OAuthAuthorizationUrlTest.java
@@ -0,0 +1,23 @@
+package com.ulticode.auth.security.oauth;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+
+class OAuthAuthorizationUrlTest {
+
+ @Test
+ void preservesConfiguredHttpAuthorizationEndpointAndQuery() {
+ String endpoint = "https://provider.example/oauth/authorize?prompt=consent";
+
+ assertThat(OAuthAuthorizationUrl.fromTrustedHttpUrl(endpoint).build().toUriString())
+ .isEqualTo(endpoint);
+ }
+
+ @Test
+ void rejectsNonHttpProviderEndpoints() {
+ assertThatIllegalArgumentException()
+ .isThrownBy(() -> OAuthAuthorizationUrl.fromTrustedHttpUrl("ftp://provider.example/authorize"));
+ }
+}
diff --git a/services/auth/src/test/resources/application.yml b/services/auth/src/test/resources/application.yml
index c1735550f..63db1e5e9 100644
--- a/services/auth/src/test/resources/application.yml
+++ b/services/auth/src/test/resources/application.yml
@@ -25,11 +25,12 @@ spring:
enabled: false
autoconfigure:
exclude:
- - org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
+ - org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration
- org.redisson.spring.starter.RedissonAutoConfigurationV2
- org.redisson.spring.starter.RedissonAutoConfigurationV4
- - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
- - org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.UserDetailsServiceAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.actuate.web.servlet.ManagementWebSecurityAutoConfiguration
mail:
host: localhost
port: 1025
diff --git a/services/core/pom.xml b/services/core/pom.xml
index 11b7a28ea..ea6c5b236 100644
--- a/services/core/pom.xml
+++ b/services/core/pom.xml
@@ -43,7 +43,7 @@
com.baomidou
- mybatis-plus-spring-boot3-starter
+ mybatis-plus-spring-boot4-starter
${mybatis-plus.version}
@@ -70,11 +70,17 @@
com.ulticode
backend-search
${service.version.search}
+
+
+ org.springframework.boot
+ spring-boot-grpc-server
+
+
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-webmvc
org.springframework.boot
@@ -87,7 +93,7 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
diff --git a/services/core/src/main/java/com/ulticode/core/CoreApplication.java b/services/core/src/main/java/com/ulticode/core/CoreApplication.java
index 6a5698c61..f9d609987 100644
--- a/services/core/src/main/java/com/ulticode/core/CoreApplication.java
+++ b/services/core/src/main/java/com/ulticode/core/CoreApplication.java
@@ -9,10 +9,10 @@
import org.springframework.context.annotation.FilterType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringBootConfiguration;
-import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
-import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration;
+import org.springframework.boot.data.redis.autoconfigure.DataRedisRepositoriesAutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootConfiguration
@@ -21,8 +21,8 @@
exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
- RedisAutoConfiguration.class,
- RedisRepositoriesAutoConfiguration.class,
+ DataRedisAutoConfiguration.class,
+ DataRedisRepositoriesAutoConfiguration.class,
MybatisPlusAutoConfiguration.class,
RedissonAutoConfigurationV2.class,
RedissonAutoConfigurationV4.class
diff --git a/services/core/src/main/java/com/ulticode/core/CoreOwnerBootConfigurations.java b/services/core/src/main/java/com/ulticode/core/CoreOwnerBootConfigurations.java
index ccff9fc74..564aefb27 100644
--- a/services/core/src/main/java/com/ulticode/core/CoreOwnerBootConfigurations.java
+++ b/services/core/src/main/java/com/ulticode/core/CoreOwnerBootConfigurations.java
@@ -157,8 +157,8 @@ static class Notification {
@EnableAutoConfiguration(
excludeName = "org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration",
exclude = {
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class,
- org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration.class,
+ org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration.class,
+ org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration.class,
com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration.class
})
@ComponentScan({"com.ulticode.search", "com.ulticode.common"})
diff --git a/services/core/src/main/java/com/ulticode/core/CoreOwnerDataSourceConfiguration.java b/services/core/src/main/java/com/ulticode/core/CoreOwnerDataSourceConfiguration.java
index 8a4329fba..269220f6e 100644
--- a/services/core/src/main/java/com/ulticode/core/CoreOwnerDataSourceConfiguration.java
+++ b/services/core/src/main/java/com/ulticode/core/CoreOwnerDataSourceConfiguration.java
@@ -4,7 +4,7 @@
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
+import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/services/core/src/main/resources/application.yml b/services/core/src/main/resources/application.yml
index 66a7e3cf0..6e1160edc 100644
--- a/services/core/src/main/resources/application.yml
+++ b/services/core/src/main/resources/application.yml
@@ -1,4 +1,7 @@
spring:
+ http:
+ converters:
+ preferred-json-mapper: jackson2
application:
name: ${CORE_APPLICATION_NAME:ulticode-core}
main:
diff --git a/services/core/src/test/java/com/ulticode/core/CoreEnabledOwnerJourneyIT.java b/services/core/src/test/java/com/ulticode/core/CoreEnabledOwnerJourneyIT.java
index 7b70cce99..0aa5c8451 100644
--- a/services/core/src/test/java/com/ulticode/core/CoreEnabledOwnerJourneyIT.java
+++ b/services/core/src/test/java/com/ulticode/core/CoreEnabledOwnerJourneyIT.java
@@ -257,7 +257,7 @@ private static void startOwnerContexts(KeyPair delegationKeyPair) {
.withProperty("spring.main.lazy-initialization", "true")
.withProperty("ulticode.app.inbox.enabled", "false")
.withProperty("spring.autoconfigure.exclude",
- "org.springframework.boot.actuate.autoconfigure.metrics.SystemMetricsAutoConfiguration");
+ "org.springframework.boot.micrometer.metrics.autoconfigure.system.SystemMetricsAutoConfiguration");
ownerContexts = new CoreOwnerContextManager(new CoreModuleRegistry(), environment, true, 60_000L);
ownerContexts.startOwnerModules();
awaitOwnerStartup();
diff --git a/services/judge-runtime/pom.xml b/services/judge-runtime/pom.xml
index c844831ae..6cfdcd9e7 100644
--- a/services/judge-runtime/pom.xml
+++ b/services/judge-runtime/pom.xml
@@ -75,7 +75,7 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
diff --git a/services/judge/pom.xml b/services/judge/pom.xml
index d331da7aa..801378ed1 100644
--- a/services/judge/pom.xml
+++ b/services/judge/pom.xml
@@ -52,7 +52,7 @@
org.springframework.boot
- spring-boot-starter
+ spring-boot-starter-classic
org.springframework.boot
@@ -111,7 +111,7 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
diff --git a/services/judge/src/main/resources/application.yml b/services/judge/src/main/resources/application.yml
index b48222a8b..5ff30e2fc 100644
--- a/services/judge/src/main/resources/application.yml
+++ b/services/judge/src/main/resources/application.yml
@@ -13,12 +13,13 @@ spring:
web-application-type: none
autoconfigure:
exclude:
- - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
+ - org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration
- org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
- com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
- - org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
- - org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
- - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
+ - org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration
+ - org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.UserDetailsServiceAutoConfiguration
data:
redis:
url: ${JUDGE_REDIS_URL:redis://${REDIS_USERNAME:}:${REDIS_PASSWORD:}@${REDIS_HOST:localhost}:${REDIS_PORT:26379}/${REDIS_DB:0}}
@@ -99,12 +100,15 @@ management:
tracing:
sampling:
probability: ${MANAGEMENT_TRACING_SAMPLING_PROBABILITY:1.0}
- otlp:
+ opentelemetry:
tracing:
- endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
- headers:
- Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
- timeout: 5s
+ export:
+ otlp:
+ endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
+ headers:
+ Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
+ timeout: 5s
+ otlp:
metrics:
export:
enabled: ${MANAGEMENT_OTLP_METRICS_ENABLED:false}
diff --git a/services/notification/pom.xml b/services/notification/pom.xml
index 8c11b4b10..c7e684efd 100644
--- a/services/notification/pom.xml
+++ b/services/notification/pom.xml
@@ -62,7 +62,7 @@
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-webmvc
org.springframework.boot
@@ -88,7 +88,7 @@
org.springframework.boot
- spring-boot-starter-aop
+ spring-boot-starter-aspectj
org.springframework.boot
@@ -104,7 +104,7 @@
com.baomidou
- mybatis-plus-spring-boot3-starter
+ mybatis-plus-spring-boot4-starter
${mybatis-plus.version}
@@ -153,12 +153,12 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
- org.springframework.security
- spring-security-test
+ org.springframework.boot
+ spring-boot-starter-security-test
test
diff --git a/services/notification/src/main/resources/application.yml b/services/notification/src/main/resources/application.yml
index a62c10429..bb64769b2 100644
--- a/services/notification/src/main/resources/application.yml
+++ b/services/notification/src/main/resources/application.yml
@@ -3,14 +3,17 @@ server:
shutdown: graceful
spring:
+ http:
+ converters:
+ preferred-json-mapper: jackson2
application:
name: backend-notification
lifecycle:
timeout-per-shutdown-phase: ${SPRING_LIFECYCLE_TIMEOUT_PER_SHUTDOWN_PHASE:45s}
autoconfigure:
exclude:
- - org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
- - org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+ - org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration
+ - org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${NOTIFICATION_DB_URL:jdbc:mysql://${NOTIFICATION_DB_HOST}:${NOTIFICATION_DB_PORT}/${NOTIFICATION_DB_NAME}?useUnicode=true&characterEncoding=UTF-8&characterSetResults=utf8mb4&connectionCollation=utf8mb4_unicode_ci&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&sslMode=${NOTIFICATION_DB_SSL_MODE:REQUIRED}&useAffectedRows=true}
@@ -168,12 +171,15 @@ management:
tracing:
sampling:
probability: ${MANAGEMENT_TRACING_SAMPLING_PROBABILITY:1.0}
- otlp:
+ opentelemetry:
tracing:
- endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
- headers:
- Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
- timeout: 5s
+ export:
+ otlp:
+ endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
+ headers:
+ Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
+ timeout: 5s
+ otlp:
metrics:
export:
enabled: ${MANAGEMENT_OTLP_METRICS_ENABLED:false}
diff --git a/services/notification/src/test/java/com/ulticode/notification/security/NotificationRouteAuthorizationContractTest.java b/services/notification/src/test/java/com/ulticode/notification/security/NotificationRouteAuthorizationContractTest.java
index 69e55fe07..3e0c9ab3f 100644
--- a/services/notification/src/test/java/com/ulticode/notification/security/NotificationRouteAuthorizationContractTest.java
+++ b/services/notification/src/test/java/com/ulticode/notification/security/NotificationRouteAuthorizationContractTest.java
@@ -7,7 +7,7 @@
import com.ulticode.websecurity.jwt.AccessTokenVerifier;
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.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.MockMvc;
diff --git a/services/platform/integration-inbox/pom.xml b/services/platform/integration-inbox/pom.xml
index 670a9788e..12f857636 100644
--- a/services/platform/integration-inbox/pom.xml
+++ b/services/platform/integration-inbox/pom.xml
@@ -21,7 +21,7 @@
com.baomidou
- mybatis-plus-spring-boot3-starter
+ mybatis-plus-spring-boot4-starter
${mybatis-plus.version}
@@ -39,7 +39,7 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
diff --git a/services/platform/observability/pom.xml b/services/platform/observability/pom.xml
index b953c44a5..2b08d0578 100644
--- a/services/platform/observability/pom.xml
+++ b/services/platform/observability/pom.xml
@@ -20,7 +20,11 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-opentelemetry
+
+
+ org.springframework.boot
+ spring-boot-starter-test-classic
test
diff --git a/services/platform/observability/src/main/java/com/ulticode/observability/config/OtlpSecurityAutoConfiguration.java b/services/platform/observability/src/main/java/com/ulticode/observability/config/OtlpSecurityAutoConfiguration.java
index 3d4d1ad6f..efccf2a34 100644
--- a/services/platform/observability/src/main/java/com/ulticode/observability/config/OtlpSecurityAutoConfiguration.java
+++ b/services/platform/observability/src/main/java/com/ulticode/observability/config/OtlpSecurityAutoConfiguration.java
@@ -12,8 +12,9 @@ public class OtlpSecurityAutoConfiguration {
@Bean
OtlpEndpointSecurityPolicy otlpEndpointSecurityPolicy(Environment environment) {
- String endpoint = environment.getProperty("management.otlp.tracing.endpoint");
- String authorization = environment.getProperty("management.otlp.tracing.headers.Authorization");
+ String endpoint = environment.getProperty("management.opentelemetry.tracing.export.otlp.endpoint");
+ String authorization = environment.getProperty(
+ "management.opentelemetry.tracing.export.otlp.headers.Authorization");
return OtlpEndpointSecurityPolicy.validate(endpoint, authorization);
}
@@ -25,17 +26,17 @@ static OtlpEndpointSecurityPolicy validate(String endpoint, String authorization
}
if (endpoint == null || endpoint.isBlank()) {
throw new IllegalStateException(
- "management.otlp.tracing.endpoint is required when authorization is configured");
+ "management.opentelemetry.tracing.export.otlp.endpoint is required when authorization is configured");
}
try {
URI uri = URI.create(endpoint.trim());
if (!"https".equalsIgnoreCase(uri.getScheme())) {
throw new IllegalStateException(
- "management.otlp.tracing.endpoint must use https when authorization is configured");
+ "management.opentelemetry.tracing.export.otlp.endpoint must use https when authorization is configured");
}
} catch (IllegalArgumentException exception) {
throw new IllegalStateException(
- "management.otlp.tracing.endpoint is not a valid URI", exception);
+ "management.opentelemetry.tracing.export.otlp.endpoint is not a valid URI", exception);
}
return new OtlpEndpointSecurityPolicy();
}
diff --git a/services/platform/observability/src/test/java/com/ulticode/observability/config/OtlpSecurityAutoConfigurationTest.java b/services/platform/observability/src/test/java/com/ulticode/observability/config/OtlpSecurityAutoConfigurationTest.java
index c4b78d998..da9656e31 100644
--- a/services/platform/observability/src/test/java/com/ulticode/observability/config/OtlpSecurityAutoConfigurationTest.java
+++ b/services/platform/observability/src/test/java/com/ulticode/observability/config/OtlpSecurityAutoConfigurationTest.java
@@ -1,8 +1,11 @@
package com.ulticode.observability.config;
import org.junit.jupiter.api.Test;
+import org.springframework.boot.context.properties.bind.Binder;
+import org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.otlp.OtlpTracingProperties;
import org.springframework.mock.env.MockEnvironment;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -33,12 +36,30 @@ void httpsEndpointIsAllowedWhenAuthorizationIsConfigured() {
@Test
void autoConfigurationReadsResolvedProperties() {
MockEnvironment environment = new MockEnvironment()
- .withProperty("management.otlp.tracing.endpoint", "http://collector.example/v1/traces")
- .withProperty("management.otlp.tracing.headers.Authorization", "Bearer secret");
+ .withProperty("management.opentelemetry.tracing.export.otlp.endpoint",
+ "http://collector.example/v1/traces")
+ .withProperty("management.opentelemetry.tracing.export.otlp.headers.Authorization",
+ "Bearer secret");
assertThatThrownBy(() -> new OtlpSecurityAutoConfiguration()
.otlpEndpointSecurityPolicy(environment))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("must use https");
}
+
+ @Test
+ void boot4TracingPropertiesBindFromTheManagedOtlpPrefix() {
+ MockEnvironment environment = new MockEnvironment()
+ .withProperty("management.opentelemetry.tracing.export.otlp.endpoint",
+ "https://collector.example/v1/traces")
+ .withProperty("management.opentelemetry.tracing.export.otlp.headers.Authorization",
+ "Bearer secret");
+
+ OtlpTracingProperties properties = Binder.get(environment)
+ .bind("management.opentelemetry.tracing.export.otlp", OtlpTracingProperties.class)
+ .get();
+
+ assertThat(properties.getEndpoint()).isEqualTo("https://collector.example/v1/traces");
+ assertThat(properties.getHeaders()).containsEntry("Authorization", "Bearer secret");
+ }
}
diff --git a/services/platform/storage/pom.xml b/services/platform/storage/pom.xml
index 2fb5c6967..b454fb51e 100644
--- a/services/platform/storage/pom.xml
+++ b/services/platform/storage/pom.xml
@@ -42,7 +42,7 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
diff --git a/services/platform/web-security/pom.xml b/services/platform/web-security/pom.xml
index 809ac29b8..18ee18e20 100644
--- a/services/platform/web-security/pom.xml
+++ b/services/platform/web-security/pom.xml
@@ -34,13 +34,13 @@
org.springframework.boot
- spring-boot-starter-aop
+ spring-boot-starter-aspectj
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-webmvc
org.springframework.boot
@@ -70,6 +70,11 @@
spring-boot-starter-data-redis
+
+ org.springframework.boot
+ spring-boot-jackson2
+
+
org.projectlombok
@@ -80,12 +85,12 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
- org.springframework.security
- spring-security-test
+ org.springframework.boot
+ spring-boot-starter-security-test
test
diff --git a/services/platform/web-security/src/main/java/com/ulticode/websecurity/config/WebSecurityAutoConfiguration.java b/services/platform/web-security/src/main/java/com/ulticode/websecurity/config/WebSecurityAutoConfiguration.java
index 1280d5f0c..ad629ceb0 100644
--- a/services/platform/web-security/src/main/java/com/ulticode/websecurity/config/WebSecurityAutoConfiguration.java
+++ b/services/platform/web-security/src/main/java/com/ulticode/websecurity/config/WebSecurityAutoConfiguration.java
@@ -7,7 +7,7 @@
import com.ulticode.websecurity.util.ClientIpResolver;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
@@ -20,7 +20,7 @@
* adapter and {@code SecurityFilterChain}.
*/
@AutoConfiguration
-@AutoConfigureAfter(RedisAutoConfiguration.class)
+@AutoConfigureAfter(DataRedisAutoConfiguration.class)
public class WebSecurityAutoConfiguration {
@Bean
diff --git a/services/platform/web-security/src/test/java/com/ulticode/websecurity/RateLimitIT.java b/services/platform/web-security/src/test/java/com/ulticode/websecurity/RateLimitIT.java
index 1fab4c003..26b805162 100644
--- a/services/platform/web-security/src/test/java/com/ulticode/websecurity/RateLimitIT.java
+++ b/services/platform/web-security/src/test/java/com/ulticode/websecurity/RateLimitIT.java
@@ -16,9 +16,9 @@
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
-import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
-import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration;
+import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;
+import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -55,7 +55,7 @@
* retry seconds, and Retry-After header.
*/
@SpringBootTest(classes = RateLimitIT.TestConfig.class)
-@ImportAutoConfiguration({RedisAutoConfiguration.class, WebMvcAutoConfiguration.class,
+@ImportAutoConfiguration({DataRedisAutoConfiguration.class, WebMvcAutoConfiguration.class,
WebSecurityAutoConfiguration.class})
@AutoConfigureMockMvc(addFilters = false)
@Testcontainers
diff --git a/services/pom.xml b/services/pom.xml
index d4ef0d60c..b55590df5 100644
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.5.16
+ 4.1.1
com.ulticode
@@ -61,14 +61,12 @@
1.0.1
17
- 2.21.7
- 4.1.137.Final
- 10.1.59
+ 2.21.7
UTF-8
3.5.17
0.13.0
4.7.0
- 2.9.1
+ 3.1.1
3.3.6
5.8.47
1.18.48
diff --git a/services/search/pom.xml b/services/search/pom.xml
index 43316014a..2bf44d6c6 100644
--- a/services/search/pom.xml
+++ b/services/search/pom.xml
@@ -47,7 +47,7 @@
(judge worker precedent: web-application-type=none). -->
org.springframework.boot
- spring-boot-starter
+ spring-boot-starter-classic
org.springframework.boot
@@ -79,7 +79,11 @@
org.springframework.boot
- spring-boot-starter-json
+ spring-boot-starter-jackson
+
+
+ org.springframework.boot
+ spring-boot-jackson2
com.fasterxml.jackson.datatype
@@ -95,7 +99,7 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
diff --git a/services/search/src/main/resources/application.yml b/services/search/src/main/resources/application.yml
index aa731095b..8c8ef1ee1 100644
--- a/services/search/src/main/resources/application.yml
+++ b/services/search/src/main/resources/application.yml
@@ -13,12 +13,13 @@ spring:
web-application-type: none
autoconfigure:
exclude:
- - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
+ - org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration
- org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
- com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
- - org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
- - org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
- - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
+ - org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration
+ - org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration
+ - org.springframework.boot.security.autoconfigure.UserDetailsServiceAutoConfiguration
data:
redis:
url: ${SEARCH_REDIS_URL:redis://${REDIS_USERNAME:}:${REDIS_PASSWORD:}@${REDIS_HOST:localhost}:${REDIS_PORT:26379}/${REDIS_DB:0}}
@@ -76,12 +77,15 @@ management:
tracing:
sampling:
probability: ${MANAGEMENT_TRACING_SAMPLING_PROBABILITY:1.0}
- otlp:
+ opentelemetry:
tracing:
- endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
- headers:
- Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
- timeout: 5s
+ export:
+ otlp:
+ endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
+ headers:
+ Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
+ timeout: 5s
+ otlp:
metrics:
export:
enabled: ${MANAGEMENT_OTLP_METRICS_ENABLED:false}
diff --git a/services/submission/pom.xml b/services/submission/pom.xml
index ae079c844..817a8ba36 100644
--- a/services/submission/pom.xml
+++ b/services/submission/pom.xml
@@ -38,7 +38,7 @@
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-webmvc
org.springframework.boot
@@ -74,7 +74,7 @@
com.baomidou
- mybatis-plus-spring-boot3-starter
+ mybatis-plus-spring-boot4-starter
${mybatis-plus.version}
@@ -129,7 +129,7 @@
org.springframework.boot
- spring-boot-starter-test
+ spring-boot-starter-test-classic
test
diff --git a/services/submission/src/main/resources/application.yml b/services/submission/src/main/resources/application.yml
index 9364cbfa1..8432d91bf 100644
--- a/services/submission/src/main/resources/application.yml
+++ b/services/submission/src/main/resources/application.yml
@@ -3,6 +3,9 @@ server:
shutdown: graceful
spring:
+ http:
+ converters:
+ preferred-json-mapper: jackson2
application:
name: backend-submission
lifecycle:
@@ -75,12 +78,14 @@ management:
tracing:
sampling:
probability: ${MANAGEMENT_TRACING_SAMPLING_PROBABILITY:1.0}
- otlp:
+ opentelemetry:
tracing:
- endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
- headers:
- Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
- timeout: 5s
+ export:
+ otlp:
+ endpoint: ${MANAGEMENT_OTLP_TRACING_ENDPOINT:http://localhost:4318/v1/traces}
+ headers:
+ Authorization: ${MANAGEMENT_OTLP_AUTHORIZATION:}
+ timeout: 5s
metrics:
export:
enabled: ${MANAGEMENT_OTLP_METRICS_ENABLED:false}
diff --git a/services/submission/src/test/java/com/ulticode/submission/BackendSubmissionApplicationTest.java b/services/submission/src/test/java/com/ulticode/submission/BackendSubmissionApplicationTest.java
index 4d530797b..5b36d4ea1 100644
--- a/services/submission/src/test/java/com/ulticode/submission/BackendSubmissionApplicationTest.java
+++ b/services/submission/src/test/java/com/ulticode/submission/BackendSubmissionApplicationTest.java
@@ -23,7 +23,7 @@
"spring.autoconfigure.exclude="
+ "org.apache.dubbo.spring.boot.autoconfigure.DubboAutoConfiguration,"
+ "com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapAutoConfiguration,"
- + "org.springframework.boot.actuate.autoconfigure.metrics.SystemMetricsAutoConfiguration",
+ + "org.springframework.boot.micrometer.metrics.autoconfigure.system.SystemMetricsAutoConfiguration",
"SUBMISSION_DB_HOST=localhost",
"SUBMISSION_DB_PORT=1",
"SUBMISSION_DB_NAME=none",
diff --git a/services/submission/src/test/java/com/ulticode/submission/security/InternalDelegationAssertionVerifierTest.java b/services/submission/src/test/java/com/ulticode/submission/security/InternalDelegationAssertionVerifierTest.java
index 8db9d7710..0291cf5b2 100644
--- a/services/submission/src/test/java/com/ulticode/submission/security/InternalDelegationAssertionVerifierTest.java
+++ b/services/submission/src/test/java/com/ulticode/submission/security/InternalDelegationAssertionVerifierTest.java
@@ -12,7 +12,6 @@
import java.security.KeyPairGenerator;
import java.time.Clock;
import java.time.Instant;
-import java.time.ZoneOffset;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;
@@ -24,7 +23,7 @@ class InternalDelegationAssertionVerifierTest {
private static final String KEY_ID = "admin-delegation-v1";
private static final String ACTOR_ID = "admin-1";
private static final String AUDIENCE = "backend-submission";
- private static final Instant NOW = Instant.now();
+ private Instant now;
private KeyPair keyPair;
private InternalDelegationAssertionVerifier verifier;
@@ -32,13 +31,15 @@ class InternalDelegationAssertionVerifierTest {
@BeforeEach
void setUp() throws Exception {
keyPair = rsaKeyPair();
+ Clock clock = Clock.systemUTC();
+ now = clock.instant();
verifier = new InternalDelegationAssertionVerifier(
encode(keyPair.getPublic()),
KEY_ID,
DelegationAssertionContract.ISSUER,
AUDIENCE,
(audience, jti, ttl) -> true,
- Clock.systemUTC());
+ clock);
}
@AfterEach
@@ -49,32 +50,32 @@ void tearDown() {
@Test
void acceptsFreshAssertionBoundToAdminActorAndOwnerAudience() {
- putAssertion(ACTOR_ID, NOW.plusSeconds(20), AUDIENCE, false);
+ putAssertion(ACTOR_ID, now.plusSeconds(20), AUDIENCE, false);
assertThat(verifier.isTrusted(actor("ADMIN", ACTOR_ID))).isTrue();
}
@Test
void rejectsWrongAudienceExpiredBootstrapAndNonAdminAssertions() {
- putAssertion(ACTOR_ID, NOW.plusSeconds(20), "backend-app", false);
+ putAssertion(ACTOR_ID, now.plusSeconds(20), "backend-app", false);
assertThat(verifier.isTrusted(actor("ADMIN", ACTOR_ID))).isFalse();
- putAssertion(ACTOR_ID, NOW.minusSeconds(1), AUDIENCE, false);
+ putAssertion(ACTOR_ID, now.minusSeconds(1), AUDIENCE, false);
assertThat(verifier.isTrusted(actor("ADMIN", ACTOR_ID))).isFalse();
- putAssertion(ACTOR_ID, NOW.plusSeconds(20), AUDIENCE, true);
+ putAssertion(ACTOR_ID, now.plusSeconds(20), AUDIENCE, true);
assertThat(verifier.isTrusted(actor("ADMIN", ACTOR_ID))).isFalse();
- putAssertion(ACTOR_ID, NOW.plusSeconds(20), AUDIENCE, false);
+ putAssertion(ACTOR_ID, now.plusSeconds(20), AUDIENCE, false);
assertThat(verifier.isTrusted(actor("USER", ACTOR_ID))).isFalse();
}
@Test
void rejectsLongLivedAndNonSelfDelegation() {
- putAssertion(ACTOR_ID, NOW.plusSeconds(120), AUDIENCE, false);
+ putAssertion(ACTOR_ID, now.plusSeconds(120), AUDIENCE, false);
assertThat(verifier.isTrusted(actor("ADMIN", ACTOR_ID))).isFalse();
- putAssertion(ACTOR_ID, NOW.plusSeconds(20), AUDIENCE, false);
+ putAssertion(ACTOR_ID, now.plusSeconds(20), AUDIENCE, false);
assertThat(verifier.isTrusted(
new ActorDelegation("ADMIN", ACTOR_ID, "different-delegator", "test"))).isFalse();
}
@@ -92,7 +93,7 @@ private void putAssertion(String subject, Instant expiresAt, String audience, bo
.claim(DelegationAssertionContract.ACTOR_TYPE_CLAIM, "ADMIN")
.issuer(DelegationAssertionContract.ISSUER)
.audience().add(audience).and()
- .issuedAt(Date.from(NOW))
+ .issuedAt(Date.from(now))
.expiration(Date.from(expiresAt));
if (bootstrap) {
builder.claim(DelegationAssertionContract.BOOTSTRAP_CLAIM, true);
From 20b912eb31f669f9f1234ede3c82ca2273688526 Mon Sep 17 00:00:00 2001
From: DavidHLP
Date: Sat, 10 Oct 2026 22:15:50 -0700
Subject: [PATCH 3/4] fix(deps): pin patched Tomcat and Jackson dependencies
---
services/pom.xml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/services/pom.xml b/services/pom.xml
index b55590df5..770561c18 100644
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -62,6 +62,8 @@
17
2.21.7
+ 3.1.7
+ 11.0.25
UTF-8
3.5.17
0.13.0
From 70df4fb4ff678e663c3f4bdfe72fff299020780e Mon Sep 17 00:00:00 2001
From: DavidHLP
Date: Sat, 10 Oct 2026 22:41:04 -0700
Subject: [PATCH 4/4] fix(security): use injected clock for delegation JWT
parsing
---
.../jwt/DelegationAssertionVerifierSupport.java | 1 +
.../DelegationAssertionVerifierSupportTest.java | 15 +++++++++++++--
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/services/platform/web-security/src/main/java/com/ulticode/websecurity/jwt/DelegationAssertionVerifierSupport.java b/services/platform/web-security/src/main/java/com/ulticode/websecurity/jwt/DelegationAssertionVerifierSupport.java
index 7d5e1c216..5f41b8292 100644
--- a/services/platform/web-security/src/main/java/com/ulticode/websecurity/jwt/DelegationAssertionVerifierSupport.java
+++ b/services/platform/web-security/src/main/java/com/ulticode/websecurity/jwt/DelegationAssertionVerifierSupport.java
@@ -41,6 +41,7 @@ public static Claims verify(
}
Jws signed = Jwts.parser()
+ .clock(() -> Date.from(clock.instant()))
.verifyWith(publicKey)
.requireIssuer(expectedIssuer)
.requireAudience(expectedAudience)
diff --git a/services/platform/web-security/src/test/java/com/ulticode/websecurity/jwt/DelegationAssertionVerifierSupportTest.java b/services/platform/web-security/src/test/java/com/ulticode/websecurity/jwt/DelegationAssertionVerifierSupportTest.java
index 48247ee62..e3766ad0a 100644
--- a/services/platform/web-security/src/test/java/com/ulticode/websecurity/jwt/DelegationAssertionVerifierSupportTest.java
+++ b/services/platform/web-security/src/test/java/com/ulticode/websecurity/jwt/DelegationAssertionVerifierSupportTest.java
@@ -11,7 +11,6 @@
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneOffset;
-import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.UUID;
import org.junit.jupiter.api.Test;
@@ -19,7 +18,7 @@
class DelegationAssertionVerifierSupportTest {
private static final String KEY_ID = "admin-delegation-v1";
- private static final Instant NOW = Instant.now().truncatedTo(ChronoUnit.SECONDS);
+ private static final Instant NOW = Instant.parse("2020-01-01T00:00:00Z");
@Test
void validatesRs256HeaderAndBoundClaims() throws Exception {
@@ -38,6 +37,18 @@ void validatesRs256HeaderAndBoundClaims() throws Exception {
assertThat(claims.getId()).isNotBlank();
}
+ @Test
+ void rejectsExpiredAssertionUsingSuppliedClock() throws Exception {
+ KeyPair keyPair = rsaKeyPair();
+ String assertion = assertion(keyPair, KEY_ID, NOW.plusSeconds(30), NOW);
+
+ assertThatThrownBy(() -> DelegationAssertionVerifierSupport.verify(
+ assertion, keyPair.getPublic(), KEY_ID,
+ DelegationAssertionContract.ISSUER, "backend-app",
+ Clock.fixed(NOW.plusSeconds(31), ZoneOffset.UTC)))
+ .isInstanceOf(io.jsonwebtoken.ExpiredJwtException.class);
+ }
+
@Test
void rejectsWrongKidFutureIssuedAtAndExcessiveLifetime() throws Exception {
KeyPair keyPair = rsaKeyPair();