diff --git a/README.md b/README.md index 93d57fa9..7b35cdd6 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ A production-ready Spring Boot REST API for tracking job applications, built wit ## Tech Stack - **Java 21** -- **Spring Boot 3.5** (Web, Data JPA, Security, Validation) -- **Spring AI 1.0.0** — MCP server (`spring-ai-starter-mcp-server-webmvc`, Streamable HTTP transport) +- **Spring Boot 4.1** (Web MVC, Data JPA, Security, Validation) +- **Spring AI 2.0** — MCP server (`spring-ai-starter-mcp-server-webmvc`, Streamable HTTP transport) - **Spring OAuth2 Authorization Server** (JDBC-backed, issues tokens for both GPT Actions and MCP clients) - **Spring Security** with stateless JWT authentication + role-based authorization (`USER`, `BETA`, `ADMIN`) - **JWT + Refresh Tokens** (access: 15 min, refresh: 7 days with rotation) diff --git a/docs/superpowers/plans/2026-09-27-spring-boot-4-migration.md b/docs/superpowers/plans/2026-09-27-spring-boot-4-migration.md new file mode 100644 index 00000000..4b612640 --- /dev/null +++ b/docs/superpowers/plans/2026-09-27-spring-boot-4-migration.md @@ -0,0 +1,113 @@ +# Spring Boot 4.1 / Spring AI 2.0 Migration Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Move the backend to stable Spring Boot 4.1.x and Spring AI 2.0.x, retaining Java 21 and existing application behavior. + +**Architecture:** Keep the current service, API, security, and MCP architecture. Upgrade managed dependencies and Boot-native starters, then adapt only the source/configuration surfaces that fail against the new APIs. Audit third-party libraries and deployment settings after the migration compiles. + +**Tech Stack:** Java 21, Maven, Spring Boot 4.1.x, Spring Security 7.x, Spring AI 2.0.x, Jackson 3, MariaDB/JPA/Flyway. + +**Spec:** `docs/superpowers/specs/2026-09-27-spring-boot-4-migration-design.md` + +## Global Constraints + +- Keep Java 21. +- Use stable Spring Boot 4.1.x and Spring AI 2.0.x; do not use Boot 4.2 milestones or release candidates. +- Do not retain `spring-boot-starter-classic` or Jackson 2 compatibility as the final application architecture. +- Preserve current application API, OAuth/OIDC/PKCE, MCP, OpenAPI, Actuator, Prometheus, and OpenTelemetry behavior. +- Keep MariaDB, JPA, and Flyway; do not require a paid AI provider in CI. +- Remove explicit versions already managed by Boot or Spring AI; keep third-party overrides only when compatibility requires them. + +## Review Focus + +- JSON responses and persisted token/claim serialization preserve current wire formats — cover with existing serialization and JWT tests. +- Authorization server endpoints, OAuth2/OIDC/PKCE, and refresh-token extensions still behave as before — cover with existing auth integration tests. +- MCP initializes and exposes expected resources/tools over WebMVC — cover with MCP auth/resource and assistant tests. +- OpenAPI groups/security schemes and Swagger UI still resolve — cover with `OpenApiDocumentationIT`. +- Actuator, rate limiting, Prometheus, and tracing configuration remain active — inspect dependency tree and startup/property binding; add focused checks only if existing coverage does not expose regressions. + +--- + +### Task 1: Upgrade managed versions and Boot 4 modules + +**Files:** +- Modify: `pom.xml` + +**Interfaces:** +- Consumes: existing application dependency graph and the design's stable-version constraints. +- Produces: a Boot 4.1.x / Spring AI 2.0.x Maven model with Boot 4-native starters and correctly managed Spring Security and Authorization Server artifacts. + +- [ ] Set the Boot parent to the latest stable 4.1.x release and Spring AI BOM to the latest stable 2.0.x release available at implementation time; keep `java.version` at 21. +- [ ] Replace the MVC, OAuth2 client/resource-server, AOP, Flyway, and test starters/modules with their Boot 4-native equivalents required by current code. Do not use classic compatibility starters. +- [ ] Remove the standalone Spring Authorization Server 1.5.x override and use the Security 7 generation managed by the Boot 4.1 BOM where available. +- [ ] Upgrade springdoc to stable 3.1.x and replace `resilience4j-spring-boot3` with the current stable `resilience4j-spring-boot4` artifact. +- [ ] Resolve the dependency model with `./mvnw -q -DskipTests dependency:resolve` and inspect the effective dependency tree for unavailable artifacts and duplicate Spring/Jackson generations. + +### Task 2: Migrate Jackson 3 application usage + +**Files:** +- Modify: Java source and tests identified by Jackson imports/usages, including `src/main/java/com/jobtracker/util/SecurityUtils.java`, `service/export/ExportConfigCodec.java`, Jackson-using DTO/controller/service files, and their focused tests. +- Modify: `pom.xml` only if a direct Jackson dependency is required after the Boot BOM migration. + +**Interfaces:** +- Consumes: Jackson 3 APIs managed by Boot 4; current JSON contracts and JWT serialization behavior. +- Produces: application JSON configuration and serialization using Jackson 3, with no default Jackson 2 compatibility layer. + +- [ ] Search all production and test sources for `com.fasterxml.jackson`, Jackson mapper/customizer APIs, and serialization assertions; classify imports still provided by third-party Jackson 2 dependencies. +- [ ] Update application Jackson package imports, mapper configuration, exception handling, and tests to Jackson 3 equivalents while preserving external JSON shapes. +- [ ] Keep a Jackson 2 compatibility module only if a concrete third-party dependency requires it; isolate it to that boundary and document the reason in the POM. +- [ ] Run focused mapper, export codec, JWT, controller serialization, and Spring context tests. + +### Task 3: Migrate Security 7 and authorization-server configuration + +**Files:** +- Modify: `src/main/java/com/jobtracker/config/SecurityConfig.java`, `AuthorizationServerConfig.java`, `CimdRegisteredClientRepository.java`, `PublicClientRefreshToken*.java`, `OAuth*MetadataController.java`, `DynamicClientRegistrationController.java`, and other compile-identified security classes. +- Modify: related auth integration tests under `src/test/java/com/jobtracker/integration/`. + +**Interfaces:** +- Consumes: Security 7 and Boot-managed authorization-server APIs. +- Produces: existing OAuth2/OIDC/PKCE endpoints, JWT resource-server validation, client registration, and custom refresh-token behavior on Boot 4. + +- [ ] Fix compile errors from Security 7 API and package changes with minimal source edits; preserve filter-chain ordering and authorization rules. +- [ ] Adapt authorization-server extensions to the supported Security 7 APIs without retaining the old separately versioned server implementation. +- [ ] Run targeted authorization-server, PKCE/OIDC, resource-server, passkey, and rate-limit integration tests. + +### Task 4: Migrate Spring AI 2 and MCP integrations + +**Files:** +- Modify: `src/main/java/com/jobtracker/service/assistant/**`, `config/AssistantToolCallingConfiguration.java`, `mcp/**`, and AI configuration in `src/main/resources/application.yml`. +- Modify: assistant/MCP tests under `src/test/java/com/jobtracker/unit/` and `integration/`. + +**Interfaces:** +- Consumes: Spring AI 2.0 chat/tool APIs, Google GenAI starter, and Spring AI-managed MCP WebMVC transport. +- Produces: existing SSE assistant behavior, tool registration/calls, MCP resources/prompts/tools, and provider-disabled test startup. + +- [ ] Follow Spring AI 2 upgrade notes for MCP artifact/package changes, WebMVC Streamable HTTP transport, Google GenAI model configuration, and chat/tool API changes. +- [ ] Adapt assistant streaming/error handling and tool registration with no externally visible API change. +- [ ] Preserve provider-disabled test profile behavior and use stubs/mocks for provider-specific tests. +- [ ] Run focused assistant service/controller/tool and MCP auth/resource tests. + +### Task 5: Audit direct dependencies, configuration, docs, and end-to-end verification + +**Files:** +- Modify: `pom.xml`, `src/main/resources/application.yml`, `src/test/resources/application-test.yml`, and deployment/documentation files only where version or configuration changes require it. +- Test: focused integration tests and the issue-required Maven verification commands. + +**Interfaces:** +- Consumes: compiling Boot 4 application and selected Boot/Spring AI BOMs. +- Produces: audited compatible dependency set and verified Boot 4 runtime configuration. + +- [ ] Audit all explicit direct dependency versions and Maven plugins in `pom.xml`; update stable compatible versions and remove BOM-managed overrides. Retain pinned versions only with a compatibility reason. +- [ ] Review Flyway, Jackson, mail/web, Actuator/Micrometer/OTLP, Resilience4j, and Spring AI properties across application/test/deployment configuration; remove renamed or obsolete keys. +- [ ] Update README/deployment guidance only where Java, dependency, or configuration requirements changed. +- [ ] Run the focused tests for serialization, security, assistant/MCP, OpenAPI, and configuration. +- [ ] Run `./mvnw clean verify` and `./mvnw dependency:tree`; confirm Java 21 build, AOT execution, no accidental duplicate Spring/Jackson generations, and successful normal-profile application startup if local services/configuration permit. + +## Self-Review + +- Spec coverage: dependency baseline, starters, Jackson, Security/Authorization Server, Spring AI/MCP, OpenAPI, Resilience4j, dependency audit, configuration, docs, and verification each have an owning task. +- Step scan: each checkbox identifies one bounded migration or verification action and its responsible files. +- Type/API consistency: Maven model outputs feed the Jackson, Security, and Spring AI source migration tasks; final audit runs only after those compile. +- Review focus: the five highest-risk behavior areas are paired with existing tests or an explicit targeted inspection. +- Proportion: the plan groups by migration boundary and avoids enumerating every Jackson-using file before compiler/search evidence identifies which ones actually change. diff --git a/docs/superpowers/specs/2026-09-27-spring-boot-4-migration-design.md b/docs/superpowers/specs/2026-09-27-spring-boot-4-migration-design.md new file mode 100644 index 00000000..c93cb659 --- /dev/null +++ b/docs/superpowers/specs/2026-09-27-spring-boot-4-migration-design.md @@ -0,0 +1,49 @@ +# Spring Boot 4.1 and Spring AI 2.0 Migration Design + +## Goal + +Migrate the backend from Spring Boot 3.5.0 to stable Spring Boot 4.1.x and Spring AI 2.0.x while retaining Java 21 and the behavior of existing application, security, assistant/MCP, API documentation, and observability features. + +## Scope + +- Upgrade Spring Boot to the stable 4.1.x release selected for implementation and Spring AI to the latest stable 2.0.x release. +- Use Boot 4-native starters and modules for MVC, OAuth2, AOP, Flyway, testing, and other dependencies where the project needs them. +- Move application Jackson integration to Jackson 3; keep Jackson 2 only where a third-party library requires it, without making its compatibility module the application default. +- Align Spring Security and authorization-server configuration with the Boot 4 / Security 7 generation, preserving OAuth2, OIDC, PKCE, registration, and token behavior. +- Adapt Spring AI assistant, Google GenAI configuration, tool calling, and MCP WebMVC server code to Spring AI 2 APIs and artifacts. +- Upgrade springdoc to a Boot 4-compatible 3.x release and Resilience4j to its Spring Boot 4 integration. +- Audit explicitly versioned direct dependencies and Maven plugins; remove versions already owned by the Boot or Spring AI BOMs and refresh other versions only when compatible. +- Audit application and test configuration, deployment configuration, and dependency documentation for changed properties or requirements. + +## Constraints + +- Keep Java 21. +- Do not use Spring Boot 4.2 milestones or release candidates. +- Do not retain `spring-boot-starter-classic` or Jackson 2 compatibility as the final application architecture. +- Preserve MariaDB, JPA, and Flyway; do not add AI provider credentials to CI requirements. +- Keep changes limited to compatibility and maintenance work required by this migration. + +## Approach + +Update dependency management and artifacts first, then migrate compile-time API changes in source, then audit configuration and deployment documentation. Keep the existing application architecture and public API. Resolve compatibility failures at the narrowest responsible boundary, and retain regression coverage around affected security, assistant/MCP, serialization, OpenAPI, and observability behavior. + +## Verification + +Verify Maven dependency resolution and compilation, then run focused tests for modified behavior and relevant existing security, assistant/MCP, serialization, and OpenAPI flows. Run the issue's full `./mvnw clean verify` and dependency-tree checks when the migration compiles. Review Java 21 compatibility, dependency convergence (especially Spring and Jackson generations), and normal application startup/configuration. + +## Current Code Areas Identified + +- `pom.xml` owns the Boot parent, Spring AI BOM, explicit library versions, starters, and Maven plugins. +- `src/main/resources/application.yml` and `src/test/resources/application-test.yml` carry AI, actuator, Resilience4j, and test-profile properties. +- Security configuration is centered in `config/SecurityConfig.java`, `config/AuthorizationServerConfig.java`, and adjacent `config/*OAuth*` classes. +- Assistant and MCP APIs are used in `service/assistant/*`, `config/AssistantToolCallingConfiguration.java`, and `mcp/*`. +- Jackson APIs appear in utility, DTO, service, configuration, and related test files; the exact migration set will be determined by compiler/dependency evidence. +- OpenAPI and observability are configured through `config/OpenApiConfig.java`, application properties, and existing integration tests. + +## Risks and Mitigations + +- Boot 4 modularization can break dependencies that relied on transitive modules. Declare only the Boot 4 modules required by the code and let the Boot BOM manage their versions. +- Jackson 3 package and exception changes may affect multiple serialized DTO and provider paths. Compile and exercise representative serialization and assistant/provider tests after migrating imports. +- Spring Security 7 and authorization-server API changes may affect protocol behavior. Preserve existing authorization-server configuration and use existing OAuth/OIDC/PKCE integration tests as regression checks. +- Spring AI 2 changes MCP transports and tool APIs. Validate both server startup/discovery and assistant tool calling without relying on paid external providers. +- Other explicitly pinned libraries may not yet support the target ecosystem. Keep compatible versions when required and document any justified override rather than forcing unrelated major upgrades. diff --git a/pom.xml b/pom.xml index 0fa7b7ec..c2d8dc6b 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.0 + 4.1.1 @@ -19,13 +19,11 @@ 21 - 0.12.5 - 1.19.8 - 5.4.0 - 0.10.2 + 0.13.0 + 1.21.4 + 6.0.1 2.9.0 - 1.5.8 - 1.1.7 + 2.0.1 @@ -44,7 +42,11 @@ org.springframework.boot - spring-boot-starter-web + spring-boot-starter-webmvc + + + org.springframework.boot + spring-boot-starter-restclient org.springframework.boot @@ -60,7 +62,7 @@ org.springframework.boot - spring-boot-starter-aop + spring-boot-starter-aspectj org.springframework.boot @@ -85,8 +87,8 @@ - org.flywaydb - flyway-core + org.springframework.boot + spring-boot-starter-flyway org.flywaydb @@ -116,7 +118,7 @@ org.springdoc springdoc-openapi-starter-webmvc-ui - 2.8.9 + 3.1.1 @@ -130,6 +132,10 @@ io.micrometer micrometer-tracing-bridge-otel + + org.springframework.boot + spring-boot-micrometer-tracing-opentelemetry + @@ -144,29 +150,29 @@ io.github.resilience4j - resilience4j-spring-boot3 - 2.2.0 + resilience4j-spring-boot4 + 2.4.0 net.logstash.logback logstash-logback-encoder - 7.4 + 9.0 net.datafaker datafaker - 2.3.1 + 2.7.0 org.jsoup jsoup - 1.23.1 + 1.23.2 @@ -207,51 +213,50 @@ org.springframework.boot - spring-boot-starter-oauth2-client + spring-boot-starter-security-oauth2-client org.springframework.boot - spring-boot-starter-oauth2-resource-server + spring-boot-starter-security-oauth2-resource-server - org.springframework.security - spring-security-oauth2-authorization-server - ${spring-authorization-server.version} + org.springframework.boot + spring-boot-starter-security-oauth2-authorization-server com.google.apis google-api-services-drive - v3-rev20240521-2.0.0 + v3-rev20260913-2.0.0 com.google.apis google-api-services-docs - v1-rev20240726-2.0.0 + v1-rev20260902-2.0.0 com.google.auth google-auth-library-oauth2-http - 1.25.0 + 1.53.0 org.apache.pdfbox pdfbox - 3.0.4 + 3.0.8 org.apache.poi poi-ooxml - 5.4.0 + 5.5.1 @@ -261,8 +266,18 @@ test - org.springframework.security - spring-security-test + org.springframework.boot + spring-boot-starter-security-test + test + + + org.springframework.boot + spring-boot-starter-security-oauth2-authorization-server-test + test + + + org.springframework.boot + spring-boot-starter-webmvc-test test diff --git a/src/main/java/com/jobtracker/JobTrackerApplication.java b/src/main/java/com/jobtracker/JobTrackerApplication.java index 9e565628..2f18e275 100644 --- a/src/main/java/com/jobtracker/JobTrackerApplication.java +++ b/src/main/java/com/jobtracker/JobTrackerApplication.java @@ -2,20 +2,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration; -import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; -import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration; -import org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration; @SpringBootApplication(exclude = { JmxAutoConfiguration.class, - JmxEndpointAutoConfiguration.class, - FreeMarkerAutoConfiguration.class, - GroovyTemplateAutoConfiguration.class, - MustacheAutoConfiguration.class, - WebSocketServletAutoConfiguration.class + JmxEndpointAutoConfiguration.class }) public class JobTrackerApplication { diff --git a/src/main/java/com/jobtracker/config/AssistantToolCallingConfiguration.java b/src/main/java/com/jobtracker/config/AssistantToolCallingConfiguration.java index b6f2691a..5df5504b 100644 --- a/src/main/java/com/jobtracker/config/AssistantToolCallingConfiguration.java +++ b/src/main/java/com/jobtracker/config/AssistantToolCallingConfiguration.java @@ -1,7 +1,7 @@ package com.jobtracker.config; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; import org.springframework.ai.tool.execution.DefaultToolExecutionExceptionProcessor; import org.springframework.ai.tool.execution.ToolExecutionExceptionProcessor; import org.springframework.beans.factory.annotation.Value; @@ -29,7 +29,7 @@ ToolExecutionExceptionProcessor jsonSafeToolExecutionExceptionProcessor( String message = delegate.process(exception); try { return objectMapper.writeValueAsString(Map.of("error", message)); - } catch (JsonProcessingException serializationFailure) { + } catch (JacksonException serializationFailure) { return "{\"error\":\"Tool execution failed\"}"; } }; diff --git a/src/main/java/com/jobtracker/config/AuthorizationServerConfig.java b/src/main/java/com/jobtracker/config/AuthorizationServerConfig.java index b469c09c..7dcbe97b 100644 --- a/src/main/java/com/jobtracker/config/AuthorizationServerConfig.java +++ b/src/main/java/com/jobtracker/config/AuthorizationServerConfig.java @@ -35,8 +35,8 @@ import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; -import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; -import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; +import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; +import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer; import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationContext; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; @@ -77,6 +77,14 @@ public class AuthorizationServerConfig { @Bean @Order(Ordered.HIGHEST_PRECEDENCE) + public SecurityFilterChain protectedResourceMetadataSecurityFilterChain(HttpSecurity http) throws Exception { + http.securityMatcher(request -> request.getRequestURI().startsWith("/.well-known/oauth-protected-resource")) + .authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll()); + return http.build(); + } + + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE + 1) public SecurityFilterChain authorizationServerSecurityFilterChain( HttpSecurity http, AuthorizationServerSettings authorizationServerSettings, @@ -84,7 +92,7 @@ public SecurityFilterChain authorizationServerSecurityFilterChain( McpOAuthProperties mcpOAuthProperties, FormLoginRateLimitFilter formLoginRateLimitFilter, RegisteredClientRepository registeredClientRepository) throws Exception { - OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer.authorizationServer(); + OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer(); RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher(); RequestMatcher authServerMatcher = new OrRequestMatcher( endpointsMatcher, diff --git a/src/main/java/com/jobtracker/config/UserDetailsConfig.java b/src/main/java/com/jobtracker/config/UserDetailsConfig.java index bc7a924c..dfc0e1bf 100644 --- a/src/main/java/com/jobtracker/config/UserDetailsConfig.java +++ b/src/main/java/com/jobtracker/config/UserDetailsConfig.java @@ -7,10 +7,13 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.authority.FactorGrantedAuthority; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.time.Instant; @Configuration public class UserDetailsConfig { @@ -27,8 +30,13 @@ public UserDetailsService userDetailsService() { .map(user -> new org.springframework.security.core.userdetails.User( user.getEmail(), user.getPasswordHash(), - user.getRoles().stream() - .map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName().name())) + Stream.concat( + user.getRoles().stream() + .map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName().name())), + Stream.of(FactorGrantedAuthority.withAuthority( + FactorGrantedAuthority.PASSWORD_AUTHORITY) + .issuedAt(Instant.now()) + .build())) .collect(Collectors.toSet()))) .orElseThrow(() -> new UsernameNotFoundException("User not found: " + username)); } @@ -36,8 +44,7 @@ public UserDetailsService userDetailsService() { @Bean public DaoAuthenticationProvider authenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setUserDetailsService(userDetailsService); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService); provider.setPasswordEncoder(passwordEncoder); return provider; } diff --git a/src/main/java/com/jobtracker/dto/auth/PasskeyOptionsResponse.java b/src/main/java/com/jobtracker/dto/auth/PasskeyOptionsResponse.java index 3517a037..dc03f44d 100644 --- a/src/main/java/com/jobtracker/dto/auth/PasskeyOptionsResponse.java +++ b/src/main/java/com/jobtracker/dto/auth/PasskeyOptionsResponse.java @@ -1,6 +1,6 @@ package com.jobtracker.dto.auth; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; import java.util.UUID; diff --git a/src/main/java/com/jobtracker/dto/auth/PasskeyVerifyRequest.java b/src/main/java/com/jobtracker/dto/auth/PasskeyVerifyRequest.java index 93caaa41..4fb6261d 100644 --- a/src/main/java/com/jobtracker/dto/auth/PasskeyVerifyRequest.java +++ b/src/main/java/com/jobtracker/dto/auth/PasskeyVerifyRequest.java @@ -1,6 +1,6 @@ package com.jobtracker.dto.auth; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; import jakarta.validation.constraints.NotNull; import java.util.UUID; diff --git a/src/main/java/com/jobtracker/dto/gdrive/GoogleDriveBaseResumeRequest.java b/src/main/java/com/jobtracker/dto/gdrive/GoogleDriveBaseResumeRequest.java index 37b8367c..ea248f8b 100644 --- a/src/main/java/com/jobtracker/dto/gdrive/GoogleDriveBaseResumeRequest.java +++ b/src/main/java/com/jobtracker/dto/gdrive/GoogleDriveBaseResumeRequest.java @@ -13,5 +13,9 @@ public record GoogleDriveBaseResumeRequest( String language, @Schema(description = "Whether this resume is a template", example = "true") - boolean template -) {} + Boolean template +) { + public GoogleDriveBaseResumeRequest { + template = Boolean.TRUE.equals(template); + } +} diff --git a/src/main/java/com/jobtracker/mcp/McpPromptsConfig.java b/src/main/java/com/jobtracker/mcp/McpPromptsConfig.java index 6f13fd57..94b283a5 100644 --- a/src/main/java/com/jobtracker/mcp/McpPromptsConfig.java +++ b/src/main/java/com/jobtracker/mcp/McpPromptsConfig.java @@ -5,9 +5,9 @@ import io.modelcontextprotocol.spec.McpSchema.PromptMessage; import io.modelcontextprotocol.spec.McpSchema.Role; import io.modelcontextprotocol.spec.McpSchema.TextContent; -import org.springaicommunity.mcp.annotation.McpComplete; -import org.springaicommunity.mcp.annotation.McpArg; -import org.springaicommunity.mcp.annotation.McpPrompt; +import org.springframework.ai.mcp.annotation.McpComplete; +import org.springframework.ai.mcp.annotation.McpArg; +import org.springframework.ai.mcp.annotation.McpPrompt; import org.springframework.stereotype.Service; import java.util.List; diff --git a/src/main/java/com/jobtracker/mcp/audit/McpAuditAspect.java b/src/main/java/com/jobtracker/mcp/audit/McpAuditAspect.java index 4d36f378..b3c33aa6 100644 --- a/src/main/java/com/jobtracker/mcp/audit/McpAuditAspect.java +++ b/src/main/java/com/jobtracker/mcp/audit/McpAuditAspect.java @@ -11,7 +11,7 @@ import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springaicommunity.mcp.context.McpSyncRequestContext; +import org.springframework.ai.mcp.annotation.context.McpSyncRequestContext; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/jobtracker/mcp/resources/McpApplicationCreationRulesResource.java b/src/main/java/com/jobtracker/mcp/resources/McpApplicationCreationRulesResource.java index 72936aa3..cecc2d59 100644 --- a/src/main/java/com/jobtracker/mcp/resources/McpApplicationCreationRulesResource.java +++ b/src/main/java/com/jobtracker/mcp/resources/McpApplicationCreationRulesResource.java @@ -4,8 +4,8 @@ import com.jobtracker.mcp.audit.AuditMcpOperation; import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema.Role; -import org.springaicommunity.mcp.annotation.McpResource; -import org.springaicommunity.mcp.annotation.McpResource.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpResource; +import org.springframework.ai.mcp.annotation.McpResource.McpAnnotations; import org.springframework.stereotype.Service; @Service diff --git a/src/main/java/com/jobtracker/mcp/resources/McpApplicationLifecycleRulesResource.java b/src/main/java/com/jobtracker/mcp/resources/McpApplicationLifecycleRulesResource.java index 33f47413..735ecbe5 100644 --- a/src/main/java/com/jobtracker/mcp/resources/McpApplicationLifecycleRulesResource.java +++ b/src/main/java/com/jobtracker/mcp/resources/McpApplicationLifecycleRulesResource.java @@ -4,8 +4,8 @@ import com.jobtracker.mcp.audit.AuditMcpOperation; import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema.Role; -import org.springaicommunity.mcp.annotation.McpResource; -import org.springaicommunity.mcp.annotation.McpResource.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpResource; +import org.springframework.ai.mcp.annotation.McpResource.McpAnnotations; import org.springframework.stereotype.Service; @Service diff --git a/src/main/java/com/jobtracker/mcp/resources/McpApplicationStatusesResource.java b/src/main/java/com/jobtracker/mcp/resources/McpApplicationStatusesResource.java index 3926ae9f..159429fb 100644 --- a/src/main/java/com/jobtracker/mcp/resources/McpApplicationStatusesResource.java +++ b/src/main/java/com/jobtracker/mcp/resources/McpApplicationStatusesResource.java @@ -6,8 +6,8 @@ import com.jobtracker.repository.ApplicationStatusRepository; import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema.Role; -import org.springaicommunity.mcp.annotation.McpResource; -import org.springaicommunity.mcp.annotation.McpResource.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpResource; +import org.springframework.ai.mcp.annotation.McpResource.McpAnnotations; import org.springframework.stereotype.Service; @Service diff --git a/src/main/java/com/jobtracker/mcp/resources/McpBaseInformationContentResource.java b/src/main/java/com/jobtracker/mcp/resources/McpBaseInformationContentResource.java index 0045e338..cf9563a4 100644 --- a/src/main/java/com/jobtracker/mcp/resources/McpBaseInformationContentResource.java +++ b/src/main/java/com/jobtracker/mcp/resources/McpBaseInformationContentResource.java @@ -6,8 +6,8 @@ import com.jobtracker.service.BaseInformationService; import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema.Role; -import org.springaicommunity.mcp.annotation.McpResource; -import org.springaicommunity.mcp.annotation.McpResource.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpResource; +import org.springframework.ai.mcp.annotation.McpResource.McpAnnotations; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/jobtracker/mcp/resources/McpBaseResumeContentResource.java b/src/main/java/com/jobtracker/mcp/resources/McpBaseResumeContentResource.java index 86c8428c..61830e77 100644 --- a/src/main/java/com/jobtracker/mcp/resources/McpBaseResumeContentResource.java +++ b/src/main/java/com/jobtracker/mcp/resources/McpBaseResumeContentResource.java @@ -6,8 +6,8 @@ import com.jobtracker.service.ResumeGenerationService; import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema.Role; -import org.springaicommunity.mcp.annotation.McpResource; -import org.springaicommunity.mcp.annotation.McpResource.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpResource; +import org.springframework.ai.mcp.annotation.McpResource.McpAnnotations; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/jobtracker/mcp/resources/McpGeneratedResumeContentResource.java b/src/main/java/com/jobtracker/mcp/resources/McpGeneratedResumeContentResource.java index 01fd4613..e3487ecb 100644 --- a/src/main/java/com/jobtracker/mcp/resources/McpGeneratedResumeContentResource.java +++ b/src/main/java/com/jobtracker/mcp/resources/McpGeneratedResumeContentResource.java @@ -6,8 +6,8 @@ import com.jobtracker.service.ResumeGenerationService.GeneratedResumeContentResponse; import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema.Role; -import org.springaicommunity.mcp.annotation.McpResource; -import org.springaicommunity.mcp.annotation.McpResource.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpResource; +import org.springframework.ai.mcp.annotation.McpResource.McpAnnotations; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/jobtracker/mcp/resources/McpReadOnlySnapshotResources.java b/src/main/java/com/jobtracker/mcp/resources/McpReadOnlySnapshotResources.java index a757dcf1..17f2b575 100644 --- a/src/main/java/com/jobtracker/mcp/resources/McpReadOnlySnapshotResources.java +++ b/src/main/java/com/jobtracker/mcp/resources/McpReadOnlySnapshotResources.java @@ -1,7 +1,7 @@ package com.jobtracker.mcp.resources; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.UserResponse; import com.jobtracker.mapper.AuthMapper; import com.jobtracker.mcp.McpResourcesConfig; @@ -13,8 +13,8 @@ import com.jobtracker.util.SecurityUtils; import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema.Role; -import org.springaicommunity.mcp.annotation.McpResource; -import org.springaicommunity.mcp.annotation.McpResource.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpResource; +import org.springframework.ai.mcp.annotation.McpResource.McpAnnotations; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; @@ -162,7 +162,7 @@ public String currentUser(McpSyncServerExchange exchange) { private String toJson(Object value) { try { return objectMapper.writeValueAsString(value); - } catch (JsonProcessingException ex) { + } catch (JacksonException ex) { throw new IllegalStateException("Failed to serialize MCP resource", ex); } } diff --git a/src/main/java/com/jobtracker/mcp/resources/McpResumeWorkflowRulesResource.java b/src/main/java/com/jobtracker/mcp/resources/McpResumeWorkflowRulesResource.java index a2b50fd1..671fc111 100644 --- a/src/main/java/com/jobtracker/mcp/resources/McpResumeWorkflowRulesResource.java +++ b/src/main/java/com/jobtracker/mcp/resources/McpResumeWorkflowRulesResource.java @@ -4,8 +4,8 @@ import com.jobtracker.mcp.audit.AuditMcpOperation; import io.modelcontextprotocol.server.McpSyncServerExchange; import io.modelcontextprotocol.spec.McpSchema.Role; -import org.springaicommunity.mcp.annotation.McpResource; -import org.springaicommunity.mcp.annotation.McpResource.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpResource; +import org.springframework.ai.mcp.annotation.McpResource.McpAnnotations; import org.springframework.stereotype.Service; @Service diff --git a/src/main/java/com/jobtracker/mcp/tools/McpAnalyticsTools.java b/src/main/java/com/jobtracker/mcp/tools/McpAnalyticsTools.java index 015d1532..4ccb38d1 100644 --- a/src/main/java/com/jobtracker/mcp/tools/McpAnalyticsTools.java +++ b/src/main/java/com/jobtracker/mcp/tools/McpAnalyticsTools.java @@ -10,10 +10,10 @@ import com.jobtracker.repository.ApplicationRepository; import com.jobtracker.service.ApplicationService; import com.jobtracker.util.SecurityUtils; -import org.springaicommunity.mcp.annotation.McpTool; -import org.springaicommunity.mcp.annotation.McpTool.McpAnnotations; -import org.springaicommunity.mcp.annotation.McpToolParam; -import org.springaicommunity.mcp.context.McpSyncRequestContext; +import org.springframework.ai.mcp.annotation.McpTool; +import org.springframework.ai.mcp.annotation.McpTool.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpToolParam; +import org.springframework.ai.mcp.annotation.context.McpSyncRequestContext; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/com/jobtracker/mcp/tools/McpApplicationTools.java b/src/main/java/com/jobtracker/mcp/tools/McpApplicationTools.java index aecf2a23..f4dea756 100644 --- a/src/main/java/com/jobtracker/mcp/tools/McpApplicationTools.java +++ b/src/main/java/com/jobtracker/mcp/tools/McpApplicationTools.java @@ -11,10 +11,10 @@ import com.jobtracker.mcp.audit.AuditMcpOperation; import com.jobtracker.service.ApplicationService; import java.util.List; -import org.springaicommunity.mcp.annotation.McpTool; -import org.springaicommunity.mcp.annotation.McpTool.McpAnnotations; -import org.springaicommunity.mcp.annotation.McpToolParam; -import org.springaicommunity.mcp.context.McpSyncRequestContext; +import org.springframework.ai.mcp.annotation.McpTool; +import org.springframework.ai.mcp.annotation.McpTool.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpToolParam; +import org.springframework.ai.mcp.annotation.context.McpSyncRequestContext; import org.springframework.stereotype.Component; import java.time.LocalDate; diff --git a/src/main/java/com/jobtracker/mcp/tools/McpBaseInformationTools.java b/src/main/java/com/jobtracker/mcp/tools/McpBaseInformationTools.java index 8abbd610..3972a634 100644 --- a/src/main/java/com/jobtracker/mcp/tools/McpBaseInformationTools.java +++ b/src/main/java/com/jobtracker/mcp/tools/McpBaseInformationTools.java @@ -4,10 +4,10 @@ import com.jobtracker.dto.gdrive.BaseInformationResponse; import com.jobtracker.mcp.audit.AuditMcpOperation; import com.jobtracker.service.BaseInformationService; -import org.springaicommunity.mcp.annotation.McpTool; -import org.springaicommunity.mcp.annotation.McpTool.McpAnnotations; -import org.springaicommunity.mcp.annotation.McpToolParam; -import org.springaicommunity.mcp.context.McpSyncRequestContext; +import org.springframework.ai.mcp.annotation.McpTool; +import org.springframework.ai.mcp.annotation.McpTool.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpToolParam; +import org.springframework.ai.mcp.annotation.context.McpSyncRequestContext; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/jobtracker/mcp/tools/McpGamificationTools.java b/src/main/java/com/jobtracker/mcp/tools/McpGamificationTools.java index f8bd9008..02e76f40 100644 --- a/src/main/java/com/jobtracker/mcp/tools/McpGamificationTools.java +++ b/src/main/java/com/jobtracker/mcp/tools/McpGamificationTools.java @@ -6,10 +6,10 @@ import com.jobtracker.gamification.GamificationProgressCallback; import com.jobtracker.mcp.audit.AuditMcpOperation; import com.jobtracker.service.GamificationService; -import org.springaicommunity.mcp.annotation.McpTool; -import org.springaicommunity.mcp.annotation.McpTool.McpAnnotations; -import org.springaicommunity.mcp.annotation.McpToolParam; -import org.springaicommunity.mcp.context.McpSyncRequestContext; +import org.springframework.ai.mcp.annotation.McpTool; +import org.springframework.ai.mcp.annotation.McpTool.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpToolParam; +import org.springframework.ai.mcp.annotation.context.McpSyncRequestContext; import org.springframework.stereotype.Component; import java.time.LocalDateTime; diff --git a/src/main/java/com/jobtracker/mcp/tools/McpGoogleDriveTools.java b/src/main/java/com/jobtracker/mcp/tools/McpGoogleDriveTools.java index 76404419..9f66fe01 100644 --- a/src/main/java/com/jobtracker/mcp/tools/McpGoogleDriveTools.java +++ b/src/main/java/com/jobtracker/mcp/tools/McpGoogleDriveTools.java @@ -11,10 +11,10 @@ import com.jobtracker.service.GoogleDriveGeneratedResumeDownloadService.DownloadedFile; import com.jobtracker.service.GoogleDriveService; import com.jobtracker.service.ResumeGenerationService; -import org.springaicommunity.mcp.annotation.McpTool; -import org.springaicommunity.mcp.annotation.McpTool.McpAnnotations; -import org.springaicommunity.mcp.annotation.McpToolParam; -import org.springaicommunity.mcp.context.McpSyncRequestContext; +import org.springframework.ai.mcp.annotation.McpTool; +import org.springframework.ai.mcp.annotation.McpTool.McpAnnotations; +import org.springframework.ai.mcp.annotation.McpToolParam; +import org.springframework.ai.mcp.annotation.context.McpSyncRequestContext; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/jobtracker/service/PasskeyAuthService.java b/src/main/java/com/jobtracker/service/PasskeyAuthService.java index 0a2fe824..98ddebad 100644 --- a/src/main/java/com/jobtracker/service/PasskeyAuthService.java +++ b/src/main/java/com/jobtracker/service/PasskeyAuthService.java @@ -1,8 +1,8 @@ package com.jobtracker.service; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.config.WebAuthnProperties; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.MessageResponse; @@ -259,7 +259,7 @@ private WebAuthnChallenge resolveUsableChallenge(UUID challengeId, WebAuthnChall private JsonNode readJson(String json) { try { return objectMapper.readTree(json); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new IllegalStateException("Failed to serialize WebAuthn options", e); } } @@ -275,7 +275,7 @@ private JsonNode readCredentialPublicKey(String credentialsJson) { private String toJsonSafely(PublicKeyCredentialCreationOptions options) { try { return options.toJson(); - } catch (JsonProcessingException e) { + } catch (com.fasterxml.jackson.core.JsonProcessingException e) { throw new IllegalStateException("Failed to serialize WebAuthn registration request", e); } } @@ -283,7 +283,7 @@ private String toJsonSafely(PublicKeyCredentialCreationOptions options) { private String toJsonSafely(AssertionRequest assertionRequest) { try { return assertionRequest.toJson(); - } catch (JsonProcessingException e) { + } catch (com.fasterxml.jackson.core.JsonProcessingException e) { throw new IllegalStateException("Failed to serialize WebAuthn assertion request", e); } } @@ -291,7 +291,7 @@ private String toJsonSafely(AssertionRequest assertionRequest) { private String toCredentialsCreateJsonSafely(PublicKeyCredentialCreationOptions options) { try { return options.toCredentialsCreateJson(); - } catch (JsonProcessingException e) { + } catch (com.fasterxml.jackson.core.JsonProcessingException e) { throw new IllegalStateException("Failed to serialize WebAuthn registration options", e); } } @@ -299,7 +299,7 @@ private String toCredentialsCreateJsonSafely(PublicKeyCredentialCreationOptions private String toCredentialsGetJsonSafely(AssertionRequest assertionRequest) { try { return assertionRequest.toCredentialsGetJson(); - } catch (JsonProcessingException e) { + } catch (com.fasterxml.jackson.core.JsonProcessingException e) { throw new IllegalStateException("Failed to serialize WebAuthn authentication options", e); } } @@ -307,7 +307,7 @@ private String toCredentialsGetJsonSafely(AssertionRequest assertionRequest) { private PublicKeyCredentialCreationOptions parseRegistrationOptions(String json) { try { return PublicKeyCredentialCreationOptions.fromJson(json); - } catch (JsonProcessingException e) { + } catch (com.fasterxml.jackson.core.JsonProcessingException e) { throw new BadRequestException("Invalid registration request payload"); } } @@ -315,7 +315,7 @@ private PublicKeyCredentialCreationOptions parseRegistrationOptions(String json) private AssertionRequest parseAssertionRequest(String json) { try { return AssertionRequest.fromJson(json); - } catch (JsonProcessingException e) { + } catch (com.fasterxml.jackson.core.JsonProcessingException e) { throw new BadRequestException("Invalid authentication request payload"); } } diff --git a/src/main/java/com/jobtracker/service/TokenEstimatorService.java b/src/main/java/com/jobtracker/service/TokenEstimatorService.java index 488f6434..f72076cf 100644 --- a/src/main/java/com/jobtracker/service/TokenEstimatorService.java +++ b/src/main/java/com/jobtracker/service/TokenEstimatorService.java @@ -1,6 +1,6 @@ package com.jobtracker.service; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.knuddels.jtokkit.Encodings; import com.knuddels.jtokkit.api.Encoding; import com.knuddels.jtokkit.api.EncodingRegistry; diff --git a/src/main/java/com/jobtracker/service/export/ExportConfigCodec.java b/src/main/java/com/jobtracker/service/export/ExportConfigCodec.java index fa0903e2..f581e7e8 100644 --- a/src/main/java/com/jobtracker/service/export/ExportConfigCodec.java +++ b/src/main/java/com/jobtracker/service/export/ExportConfigCodec.java @@ -1,8 +1,8 @@ package com.jobtracker.service.export; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.export.ExportFilters; import com.jobtracker.exception.BadRequestException; import org.springframework.stereotype.Component; @@ -31,7 +31,7 @@ public String write(Object value) { } try { return objectMapper.writeValueAsString(value); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new BadRequestException("Could not store the export configuration"); } } @@ -43,7 +43,7 @@ public ExportFilters readFilters(String json) { } try { return objectMapper.readValue(json, ExportFilters.class); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { return ExportFilters.empty(); } } @@ -54,7 +54,7 @@ public List readColumns(String json) { } try { return objectMapper.readValue(json, new TypeReference>() {}); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { return List.of(); } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 26d0e9b6..aa3580a9 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -36,7 +36,7 @@ spring: resource://job-apply-tracker/application-lifecycle-rules for the full lifecycle policy. # Claude.ai (and other modern MCP connectors) speak the Streamable HTTP # transport: a single endpoint that handles both POST (JSON-RPC) and GET - # (SSE stream). Requires Spring AI 1.1+. The endpoint defaults to /mcp, + # (SSE stream). Requires Spring AI 2.0+. The endpoint defaults to /mcp, # which is already covered by SecurityConfig's /mcp/** rule and the # OAuth protected-resource metadata controller. protocol: STREAMABLE diff --git a/src/test/java/com/jobtracker/JobTrackerApplicationTests.java b/src/test/java/com/jobtracker/JobTrackerApplicationTests.java index c5a51afc..cf35d678 100644 --- a/src/test/java/com/jobtracker/JobTrackerApplicationTests.java +++ b/src/test/java/com/jobtracker/JobTrackerApplicationTests.java @@ -1,7 +1,7 @@ package com.jobtracker; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.ai.tool.definition.ToolDefinition; import org.springframework.ai.tool.execution.ToolExecutionException; diff --git a/src/test/java/com/jobtracker/e2e/ChatGptConnectorOAuthE2ETest.java b/src/test/java/com/jobtracker/e2e/ChatGptConnectorOAuthE2ETest.java index 87c15520..24001d7a 100644 --- a/src/test/java/com/jobtracker/e2e/ChatGptConnectorOAuthE2ETest.java +++ b/src/test/java/com/jobtracker/e2e/ChatGptConnectorOAuthE2ETest.java @@ -367,8 +367,8 @@ void fullChatGptConnectorFlow_dcrToAuthenticatedMcpCall() throws Exception { private static Map decodeJwtPayload(String jwt) throws Exception { String payload = jwt.split("\\.")[1]; byte[] json = Base64.getUrlDecoder().decode(payload); - return new com.fasterxml.jackson.databind.ObjectMapper() - .readValue(json, new com.fasterxml.jackson.core.type.TypeReference>() {}); + return new tools.jackson.databind.ObjectMapper() + .readValue(json, new tools.jackson.core.type.TypeReference>() {}); } /** diff --git a/src/test/java/com/jobtracker/integration/AbstractIntegrationTest.java b/src/test/java/com/jobtracker/integration/AbstractIntegrationTest.java index 17ac475d..d7f9b1cf 100644 --- a/src/test/java/com/jobtracker/integration/AbstractIntegrationTest.java +++ b/src/test/java/com/jobtracker/integration/AbstractIntegrationTest.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; diff --git a/src/test/java/com/jobtracker/integration/ApplicationControllerIT.java b/src/test/java/com/jobtracker/integration/ApplicationControllerIT.java index 64509570..ad951fc3 100644 --- a/src/test/java/com/jobtracker/integration/ApplicationControllerIT.java +++ b/src/test/java/com/jobtracker/integration/ApplicationControllerIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.application.ApplicationRequest; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; diff --git a/src/test/java/com/jobtracker/integration/AuthControllerIT.java b/src/test/java/com/jobtracker/integration/AuthControllerIT.java index 59a2f6fa..0b8d7069 100644 --- a/src/test/java/com/jobtracker/integration/AuthControllerIT.java +++ b/src/test/java/com/jobtracker/integration/AuthControllerIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.config.JwtService; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.LoginRequest; diff --git a/src/test/java/com/jobtracker/integration/AuthRateLimiterIT.java b/src/test/java/com/jobtracker/integration/AuthRateLimiterIT.java index bfdbe3c0..4e0b3c6f 100644 --- a/src/test/java/com/jobtracker/integration/AuthRateLimiterIT.java +++ b/src/test/java/com/jobtracker/integration/AuthRateLimiterIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.LoginRequest; import com.jobtracker.dto.auth.RegisterRequest; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/jobtracker/integration/DcrDisabledIT.java b/src/test/java/com/jobtracker/integration/DcrDisabledIT.java index 37baa53b..c90d1e71 100644 --- a/src/test/java/com/jobtracker/integration/DcrDisabledIT.java +++ b/src/test/java/com/jobtracker/integration/DcrDisabledIT.java @@ -2,7 +2,7 @@ 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.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; diff --git a/src/test/java/com/jobtracker/integration/DynamicClientRegistrationIT.java b/src/test/java/com/jobtracker/integration/DynamicClientRegistrationIT.java index 5c0c27db..105e7370 100644 --- a/src/test/java/com/jobtracker/integration/DynamicClientRegistrationIT.java +++ b/src/test/java/com/jobtracker/integration/DynamicClientRegistrationIT.java @@ -1,7 +1,7 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.config.DynamicClientRegistrationController; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/jobtracker/integration/ExportControllerIT.java b/src/test/java/com/jobtracker/integration/ExportControllerIT.java index 64bad776..fda5f62b 100644 --- a/src/test/java/com/jobtracker/integration/ExportControllerIT.java +++ b/src/test/java/com/jobtracker/integration/ExportControllerIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.application.ApplicationRequest; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; diff --git a/src/test/java/com/jobtracker/integration/ExportRateLimitIT.java b/src/test/java/com/jobtracker/integration/ExportRateLimitIT.java index 3e760548..0630da26 100644 --- a/src/test/java/com/jobtracker/integration/ExportRateLimitIT.java +++ b/src/test/java/com/jobtracker/integration/ExportRateLimitIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/jobtracker/integration/ExportScheduleControllerIT.java b/src/test/java/com/jobtracker/integration/ExportScheduleControllerIT.java index 4c1d4d85..04b3d043 100644 --- a/src/test/java/com/jobtracker/integration/ExportScheduleControllerIT.java +++ b/src/test/java/com/jobtracker/integration/ExportScheduleControllerIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.application.ApplicationRequest; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; diff --git a/src/test/java/com/jobtracker/integration/ExportSchedulerIT.java b/src/test/java/com/jobtracker/integration/ExportSchedulerIT.java index d7b34c79..ab3d19ff 100644 --- a/src/test/java/com/jobtracker/integration/ExportSchedulerIT.java +++ b/src/test/java/com/jobtracker/integration/ExportSchedulerIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.application.ApplicationRequest; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; diff --git a/src/test/java/com/jobtracker/integration/GamificationControllerIT.java b/src/test/java/com/jobtracker/integration/GamificationControllerIT.java index a8fafe8d..6fed1b4b 100644 --- a/src/test/java/com/jobtracker/integration/GamificationControllerIT.java +++ b/src/test/java/com/jobtracker/integration/GamificationControllerIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; import com.jobtracker.dto.gamification.GamificationEventRequest; diff --git a/src/test/java/com/jobtracker/integration/GitHubControllerIT.java b/src/test/java/com/jobtracker/integration/GitHubControllerIT.java index e9c39169..d87ccca3 100644 --- a/src/test/java/com/jobtracker/integration/GitHubControllerIT.java +++ b/src/test/java/com/jobtracker/integration/GitHubControllerIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; import com.jobtracker.repository.RefreshTokenRepository; diff --git a/src/test/java/com/jobtracker/integration/GoogleDriveControllerIT.java b/src/test/java/com/jobtracker/integration/GoogleDriveControllerIT.java index 13f78618..dfe30e93 100644 --- a/src/test/java/com/jobtracker/integration/GoogleDriveControllerIT.java +++ b/src/test/java/com/jobtracker/integration/GoogleDriveControllerIT.java @@ -1,7 +1,7 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; import com.jobtracker.entity.GoogleDriveBaseResume; diff --git a/src/test/java/com/jobtracker/integration/GptOAuthFlowIT.java b/src/test/java/com/jobtracker/integration/GptOAuthFlowIT.java index caa69161..619ee59a 100644 --- a/src/test/java/com/jobtracker/integration/GptOAuthFlowIT.java +++ b/src/test/java/com/jobtracker/integration/GptOAuthFlowIT.java @@ -1,7 +1,7 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; import com.jobtracker.repository.ApplicationRepository; @@ -19,6 +19,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.authority.FactorGrantedAuthority; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.security.oauth2.jwt.Jwt; @@ -234,7 +235,10 @@ private AuthResponse registerUser(String email, String password) throws Exceptio private String authorizeWithPkce(String email, String scope, PkcePair pkcePair) throws Exception { MvcResult result = mockMvc.perform(get("/oauth2/authorize") - .with(user(email).roles("USER")) + .with(user(email).roles("USER").authorities( + FactorGrantedAuthority.withAuthority(FactorGrantedAuthority.PASSWORD_AUTHORITY) + .issuedAt(java.time.Instant.now()) + .build())) .queryParam("response_type", "code") .queryParam("client_id", CLIENT_ID) .queryParam("redirect_uri", REDIRECT_URI) diff --git a/src/test/java/com/jobtracker/integration/OpenApiDocumentationIT.java b/src/test/java/com/jobtracker/integration/OpenApiDocumentationIT.java index 9fc95791..ff08aeac 100644 --- a/src/test/java/com/jobtracker/integration/OpenApiDocumentationIT.java +++ b/src/test/java/com/jobtracker/integration/OpenApiDocumentationIT.java @@ -1,7 +1,7 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.web.servlet.MockMvc; diff --git a/src/test/java/com/jobtracker/integration/PasskeyRegistrationOptionsIT.java b/src/test/java/com/jobtracker/integration/PasskeyRegistrationOptionsIT.java index 39ca0a44..e1fc0211 100644 --- a/src/test/java/com/jobtracker/integration/PasskeyRegistrationOptionsIT.java +++ b/src/test/java/com/jobtracker/integration/PasskeyRegistrationOptionsIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/jobtracker/integration/UserDeletionCascadeIT.java b/src/test/java/com/jobtracker/integration/UserDeletionCascadeIT.java index a6769e4d..3976ffb6 100644 --- a/src/test/java/com/jobtracker/integration/UserDeletionCascadeIT.java +++ b/src/test/java/com/jobtracker/integration/UserDeletionCascadeIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.RegisterRequest; import com.jobtracker.entity.ExportExecution; import com.jobtracker.entity.ExportSchedule; diff --git a/src/test/java/com/jobtracker/integration/mcp/McpAuthIT.java b/src/test/java/com/jobtracker/integration/mcp/McpAuthIT.java index 122b865d..c655a651 100644 --- a/src/test/java/com/jobtracker/integration/mcp/McpAuthIT.java +++ b/src/test/java/com/jobtracker/integration/mcp/McpAuthIT.java @@ -1,6 +1,6 @@ package com.jobtracker.integration.mcp; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.AuthResponse; import com.jobtracker.dto.auth.RegisterRequest; import com.jobtracker.integration.AbstractIntegrationTest; diff --git a/src/test/java/com/jobtracker/unit/ApplicationConfigTest.java b/src/test/java/com/jobtracker/unit/ApplicationConfigTest.java index e86230ae..6eee1bd3 100644 --- a/src/test/java/com/jobtracker/unit/ApplicationConfigTest.java +++ b/src/test/java/com/jobtracker/unit/ApplicationConfigTest.java @@ -39,6 +39,6 @@ void userDetailsService_shouldMapPersistedRolesToGrantedAuthorities() { assertThat(userDetails.getAuthorities()) .extracting("authority") - .containsExactlyInAnyOrder("ROLE_USER", "ROLE_BETA"); + .containsExactlyInAnyOrder("ROLE_USER", "ROLE_BETA", "FACTOR_PASSWORD"); } } diff --git a/src/test/java/com/jobtracker/unit/ApplicationPatchRequestTest.java b/src/test/java/com/jobtracker/unit/ApplicationPatchRequestTest.java index 673aee66..cc9b0803 100644 --- a/src/test/java/com/jobtracker/unit/ApplicationPatchRequestTest.java +++ b/src/test/java/com/jobtracker/unit/ApplicationPatchRequestTest.java @@ -1,7 +1,6 @@ package com.jobtracker.unit; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.application.ApplicationPatchRequest; import org.junit.jupiter.api.Test; @@ -15,7 +14,7 @@ */ class ApplicationPatchRequestTest { - private final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); + private final ObjectMapper objectMapper = new ObjectMapper(); @Test void omittedProperties_areNotMarkedAsProvided() throws Exception { diff --git a/src/test/java/com/jobtracker/unit/AssistantConversationMemoryTest.java b/src/test/java/com/jobtracker/unit/AssistantConversationMemoryTest.java index be50c7e9..21e4573c 100644 --- a/src/test/java/com/jobtracker/unit/AssistantConversationMemoryTest.java +++ b/src/test/java/com/jobtracker/unit/AssistantConversationMemoryTest.java @@ -13,6 +13,7 @@ import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.model.ChatModel; +import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.Generation; import org.springframework.ai.chat.prompt.Prompt; @@ -138,6 +139,7 @@ void systemPromptPreservesRelevantFiltersForFollowUps() throws Exception { private ChatModel recordingModel(List prompts) { ChatModel model = mock(ChatModel.class); + when(model.getOptions()).thenReturn(ChatOptions.builder().build()); when(model.stream(any(Prompt.class))).thenAnswer(invocation -> { Prompt prompt = invocation.getArgument(0); prompts.add(prompt); diff --git a/src/test/java/com/jobtracker/unit/mcp/McpApplicationToolsTest.java b/src/test/java/com/jobtracker/unit/mcp/McpApplicationToolsTest.java index 1ad98c82..65d31c48 100644 --- a/src/test/java/com/jobtracker/unit/mcp/McpApplicationToolsTest.java +++ b/src/test/java/com/jobtracker/unit/mcp/McpApplicationToolsTest.java @@ -16,8 +16,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springaicommunity.mcp.annotation.McpTool; -import org.springaicommunity.mcp.annotation.McpToolParam; +import org.springframework.ai.mcp.annotation.McpTool; +import org.springframework.ai.mcp.annotation.McpToolParam; import java.lang.reflect.Method; import java.lang.reflect.Parameter; diff --git a/src/test/java/com/jobtracker/unit/mcp/McpAuditAspectProxyTest.java b/src/test/java/com/jobtracker/unit/mcp/McpAuditAspectProxyTest.java index c3781f41..ffdb9455 100644 --- a/src/test/java/com/jobtracker/unit/mcp/McpAuditAspectProxyTest.java +++ b/src/test/java/com/jobtracker/unit/mcp/McpAuditAspectProxyTest.java @@ -1,6 +1,6 @@ package com.jobtracker.unit.mcp; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.mcp.audit.AuditMcpOperation; import com.jobtracker.mcp.audit.McpAuditAspect; import com.jobtracker.service.McpAuditService; diff --git a/src/test/java/com/jobtracker/unit/mcp/McpAuditAspectTest.java b/src/test/java/com/jobtracker/unit/mcp/McpAuditAspectTest.java index acf1fa6c..a542a947 100644 --- a/src/test/java/com/jobtracker/unit/mcp/McpAuditAspectTest.java +++ b/src/test/java/com/jobtracker/unit/mcp/McpAuditAspectTest.java @@ -1,6 +1,6 @@ package com.jobtracker.unit.mcp; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.mcp.audit.AuditMcpOperation; import com.jobtracker.mcp.audit.McpAuditAspect; import com.jobtracker.service.McpAuditService; @@ -16,7 +16,7 @@ import org.aspectj.lang.reflect.MethodSignature; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springaicommunity.mcp.context.McpSyncRequestContext; +import org.springframework.ai.mcp.annotation.context.McpSyncRequestContext; import java.lang.reflect.Method; diff --git a/src/test/java/com/jobtracker/unit/mcp/McpDashboardToolsTest.java b/src/test/java/com/jobtracker/unit/mcp/McpDashboardToolsTest.java index d1fbd9a2..28338ef7 100644 --- a/src/test/java/com/jobtracker/unit/mcp/McpDashboardToolsTest.java +++ b/src/test/java/com/jobtracker/unit/mcp/McpDashboardToolsTest.java @@ -1,6 +1,6 @@ package com.jobtracker.unit.mcp; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.dashboard.DashboardSummaryResponse; import com.jobtracker.dto.gamification.AchievementResponse; import com.jobtracker.dto.gamification.GamificationProfileResponse; @@ -50,7 +50,7 @@ class McpDashboardToolsTest { @BeforeEach void setUp() { - objectMapper = new ObjectMapper().findAndRegisterModules(); + objectMapper = new ObjectMapper(); resources = new McpReadOnlySnapshotResources( dashboardService, gamificationService, diff --git a/src/test/java/com/jobtracker/unit/mcp/McpGamificationToolsTest.java b/src/test/java/com/jobtracker/unit/mcp/McpGamificationToolsTest.java index 8352ae8c..8ee84f79 100644 --- a/src/test/java/com/jobtracker/unit/mcp/McpGamificationToolsTest.java +++ b/src/test/java/com/jobtracker/unit/mcp/McpGamificationToolsTest.java @@ -13,7 +13,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springaicommunity.mcp.context.McpSyncRequestContext; +import org.springframework.ai.mcp.annotation.context.McpSyncRequestContext; import java.util.ArrayList; import java.util.List; @@ -110,7 +110,7 @@ void applyGamificationEvent_emitsProgressNotificationsViaContext() { }).when(gamificationService).applyEventWithProgress(any(), any()); doAnswer(inv -> { - Consumer specConsumer = inv.getArgument(0); + Consumer specConsumer = inv.getArgument(0); // record the message by using a recording spec capturedMessages.add("step"); return null; diff --git a/src/test/java/com/jobtracker/unit/mcp/McpProfileToolsTest.java b/src/test/java/com/jobtracker/unit/mcp/McpProfileToolsTest.java index 6d8dfd89..7389be7a 100644 --- a/src/test/java/com/jobtracker/unit/mcp/McpProfileToolsTest.java +++ b/src/test/java/com/jobtracker/unit/mcp/McpProfileToolsTest.java @@ -1,6 +1,6 @@ package com.jobtracker.unit.mcp; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import com.jobtracker.dto.auth.UserResponse; import com.jobtracker.entity.User; import com.jobtracker.mapper.AuthMapper; @@ -47,7 +47,7 @@ class McpProfileToolsTest { @BeforeEach void setUp() { - objectMapper = new ObjectMapper().findAndRegisterModules(); + objectMapper = new ObjectMapper(); resources = new McpReadOnlySnapshotResources( dashboardService, gamificationService, diff --git a/src/test/java/com/jobtracker/unit/mcp/McpPromptsConfigTest.java b/src/test/java/com/jobtracker/unit/mcp/McpPromptsConfigTest.java index 68195c59..34746a45 100644 --- a/src/test/java/com/jobtracker/unit/mcp/McpPromptsConfigTest.java +++ b/src/test/java/com/jobtracker/unit/mcp/McpPromptsConfigTest.java @@ -4,8 +4,8 @@ import io.modelcontextprotocol.spec.McpSchema.GetPromptResult; import io.modelcontextprotocol.spec.McpSchema.TextContent; import org.junit.jupiter.api.Test; -import org.springaicommunity.mcp.annotation.McpComplete; -import org.springaicommunity.mcp.annotation.McpPrompt; +import org.springframework.ai.mcp.annotation.McpComplete; +import org.springframework.ai.mcp.annotation.McpPrompt; import java.lang.reflect.Method; import java.util.Set;