Skip to content

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Nov 20, 2025

This PR contains the following updates:

Package Change Age Confidence
org.springframework.boot:spring-boot-starter-parent (source) 3.5.8 -> 4.0.0 age confidence

Release Notes

spring-projects/spring-boot (org.springframework.boot:spring-boot-starter-parent)

v4.0.0

Compare Source


Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 20, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request modernizes the HTTP client configuration and test infrastructure. It replaces individual RestClient beans with a centralized RestClientHttpServiceGroupConfigurer, adds @HttpExchange annotations to service clients, updates PagedResult to use nullable wrapper types, refactors ProductController to manually parse JSON responses, and updates framework import paths and test dependencies.

Changes

Cohort / File(s) Summary
HTTP Service Client Configuration
retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/ClientsConfig.java, retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/catalog/CatalogServiceClient.java, retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/customer/CustomerServiceClient.java, retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/inventory/InventoryServiceClient.java, retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderServiceClient.java
Replaced per-service RestClient bean creation with centralized RestClientHttpServiceGroupConfigurer in ClientsConfig, added @ImportHttpServices annotation to register all service clients. Added @HttpExchange base path annotations to each service client interface (/catalog-service, /payment-service, /inventory-service, /order-service).
Data Model Updates
retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/PagedResult.java
Changed field types from primitives to nullable wrapper equivalents: totalElements (long → Long), pageNumber and totalPages (int → Integer), and boolean pagination flags (boolean → Boolean).
Controller & Service Integration
retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/ProductController.java
Updated constructor to accept ObjectMapper alongside CatalogServiceClient. Modified getProducts to parse JSON string responses from catalog service client and reconstruct PagedResult objects.
Framework Imports & Annotations
retail-store-webapp/src/main/java/com/example/retailstore/webapp/config/WebConfig.java, retail-store-webapp/src/main/java/com/example/retailstore/webapp/exception/ResourceNotFoundException.java
Replaced Spring @NonNull import with Jspecify @NonNull in WebConfig. Replaced String.format with String.formatted() in ResourceNotFoundException.
Application Configuration
retail-store-webapp/src/main/resources/application.properties
Updated configuration keys: management.tracing.enabled → management.tracing.export.enabled; spring.http.client.* → spring.http.clients.*.
Test Infrastructure
retail-store-webapp/src/test/java/com/example/retailstore/webapp/common/AbstractIntegrationTest.java, retail-store-webapp/src/test/java/com/example/retailstore/webapp/common/ContainerConfig.java
Replaced ObjectMapper with JsonMapper in AbstractIntegrationTest. Updated Keycloak container image from 26.4.2 to 26.4.7 in ContainerConfig.
Test Annotation & Import Updates
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java, LoginControllerTest.java, OrderControllerTest.java, ProductControllerTest.java, RegistrationControllerTest.java
Updated WebMvcTest import path from org.springframework.boot.test.autoconfigure.web.servlet to org.springframework.boot.webmvc.test.autoconfigure. Replaced Jackson ObjectMapper import from com.fasterxml.jackson.databind to tools.jackson.databind.
Test Logic & Serialization Updates
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerIT.java, ProductControllerIT.java, RegistrationControllerIT.java
Replaced objectMapper with jsonMapper for JSON serialization across test mocks and assertions. Updated PagedResult constructor calls to reflect Long type for totalElements. Removed throws Exception declarations and updated exception types (JsonProcessingException → JacksonException).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • ProductController refactoring: Verify that manual JSON parsing via ObjectMapper correctly reconstructs PagedResult objects and that the service integration works as expected.
  • PagedResult type changes: Confirm that the shift from primitives to nullable wrapper types does not break existing serialization/deserialization or introduce unexpected null-handling issues.
  • HTTP client configuration migration: Ensure that the centralized RestClientHttpServiceGroupConfigurer correctly applies base URLs and headers to all service clients via @ImportHttpServices.
  • Test file import consolidation: While mostly repetitive, verify that the switch from com.fasterxml.jackson to tools.jackson and the WebMvcTest import path change work correctly across all test classes.

Possibly related PRs

Poem

🐰 ✨ Hops through configs, neat and tight,
Service clients dance in grouped delight!
JSON strings now parsed with care,
Tests leap forward, imports spare—
A springtime refresh, oh what a sight!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: upgrading Spring Boot from v3 to v4, which is reflected across all modified files.
Description check ✅ Passed The description clearly explains the dependency upgrade from Spring Boot 3.5.8 to 4.0.0, including release information and Renovate configuration details.

Comment @coderabbitai help to get the list of available commands and usage tips.

@renovate
Copy link
Contributor Author

renovate bot commented Dec 7, 2025

Edited/Blocked Notification

Renovate will not automatically rebase this PR, because it does not recognize the last commit author and assumes somebody else may have edited the PR.

You can manually request rebase by checking the rebase/retry box above.

⚠️ Warning: custom changes will be lost.

@rajadilipkolli
Copy link
Owner

@coderabbitai, full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 7, 2025

@rajadilipkolli, I'll conduct a full review of this Spring Boot 4.0.0 upgrade. This is a major version update that likely includes breaking changes, API updates, and new requirements. I'll analyze all the changes comprehensively.

✅ Actions performed

Full review triggered.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/ProductController.java (1)

60-112: Manual JSON parsing defeats type-safe client design and creates maintainability burden.

This method performs 45+ lines of manual JSON tree parsing to reconstruct PagedResult<ProductResponse>, which:

  • Reimplements what Jackson would do automatically with proper deserialization
  • Is error-prone and harder to maintain (any DTO changes require updating this logic)
  • Loses compile-time type safety that typed responses provide
  • Has slower performance (tree model traversal vs. streaming deserialization)
  • Is inconsistent with other controllers: InventoryController (line 28) and OrderController (line 60) return typed PagedResult directly from their service clients without manual parsing

Recommendation: Revert CatalogServiceClient.getProducts() to return PagedResult<ProductResponse> instead of String, then simplify this method:

 PagedResult<ProductResponse> products(@RequestParam(defaultValue = "0") int page, Model model) {
     log.info("Fetching products for page: {}", page);
     try {
-        String json = catalogServiceClient.getProducts(page);
-        var root = objectMapper.readTree(json);
-        var dataNode = root.path("data");
-        var list = new ArrayList<ProductResponse>();
-        if (dataNode.isArray()) {
-            for (var elem : dataNode) {
-                Long id = elem.path("id").isNumber() ? elem.path("id").asLong() : null;
-                String productCode = elem.path("productCode").isMissingNode()
-                        ? null
-                        : elem.path("productCode").asText(null);
-                String productName = elem.path("productName").isMissingNode()
-                        ? null
-                        : elem.path("productName").asText(null);
-                String description = elem.path("description").isMissingNode()
-                        ? null
-                        : elem.path("description").asText(null);
-                String imageUrl = elem.path("imageUrl").isMissingNode()
-                                || elem.path("imageUrl").isNull()
-                        ? null
-                        : elem.path("imageUrl").asText(null);
-                double price = elem.has("price") && elem.path("price").isNumber()
-                        ? elem.path("price").asDouble(0.0)
-                        : 0.0;
-                boolean inStock =
-                        elem.has("inStock") && elem.path("inStock").isBoolean()
-                                ? elem.path("inStock").asBoolean(false)
-                                : false;
-                list.add(new ProductResponse(id, productCode, productName, description, imageUrl, price, inStock));
-            }
-        }
-
-        long totalElements = root.path("totalElements").isNumber()
-                ? root.path("totalElements").asLong()
-                : 0L;
-        int pageNumber =
-                root.path("pageNumber").isNumber() ? root.path("pageNumber").asInt() : 0;
-        int totalPages =
-                root.path("totalPages").isNumber() ? root.path("totalPages").asInt() : 0;
-        boolean isFirst = root.path("isFirst").asBoolean(false);
-        boolean isLast = root.path("isLast").asBoolean(false);
-        boolean hasNext = root.path("hasNext").asBoolean(false);
-        boolean hasPrevious = root.path("hasPrevious").asBoolean(false);
-
-        return new PagedResult<>(
-                list, totalElements, pageNumber, totalPages, isFirst, isLast, hasNext, hasPrevious);
+        return catalogServiceClient.getProducts(page);
     } catch (Exception e) {

This would also allow removing the ObjectMapper dependency from the constructor and the ArrayList import.

♻️ Duplicate comments (2)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/LoginControllerTest.java (1)

13-13: Verify the WebMvcTest import path.

This file has the same non-standard import path as OrderControllerTest.java. Please ensure all test files use the correct Spring Boot 4.0 import path once verified.

retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java (1)

21-21: Verify import paths for Spring Boot 4.0.

This file contains the same non-standard import paths as other test files. Verification requested in OrderControllerTest.java applies here as well.

Also applies to: 27-27

🧹 Nitpick comments (2)
retail-store-webapp/src/main/resources/application.properties (1)

1-41: Add Swagger UI endpoint configuration per coding guidelines.

The coding guidelines require exposing Swagger UI endpoints at /swagger-ui.html for API documentation. While Line 11 correctly exposes all actuator endpoints, there is no explicit Swagger UI path configuration in this file.

If the application uses SpringDoc OpenAPI or similar Swagger UI libraries, add an explicit configuration entry to ensure the endpoint is properly exposed:

# Swagger UI endpoint configuration
springdoc.swagger-ui.path=/swagger-ui.html

If Swagger UI is auto-configured or configured elsewhere, ensure it remains accessible at /swagger-ui.html after the Spring Boot 4.0.0 upgrade.

retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerTest.java (1)

57-60: Optionally replace fully qualified customer DTO types with imports for readability

Lines 57–60 and 77–80 use fully qualified names (com.example.retailstore.webapp.clients.customer.CustomerRequest / CustomerResponse) instead of imports. To align with the project guideline of using imports rather than FQCNs, you could simplify these references:

@@
-import com.example.retailstore.webapp.clients.customer.CustomerServiceClient;
+import com.example.retailstore.webapp.clients.customer.CustomerServiceClient;
+import com.example.retailstore.webapp.clients.customer.CustomerRequest;
+import com.example.retailstore.webapp.clients.customer.CustomerResponse;
@@
-        when(customerServiceClient.getOrCreateCustomer(
-                        any(com.example.retailstore.webapp.clients.customer.CustomerRequest.class)))
-                .thenReturn(new com.example.retailstore.webapp.clients.customer.CustomerResponse(
+        when(customerServiceClient.getOrCreateCustomer(any(CustomerRequest.class)))
+                .thenReturn(new CustomerResponse(
                         1L, TEST_USERNAME, TEST_EMAIL, "9848022334", "junitAddress", 10_000));
@@
-        when(customerServiceClient.getOrCreateCustomer(
-                        any(com.example.retailstore.webapp.clients.customer.CustomerRequest.class)))
-                .thenReturn(new com.example.retailstore.webapp.clients.customer.CustomerResponse(
+        when(customerServiceClient.getOrCreateCustomer(any(CustomerRequest.class)))
+                .thenReturn(new CustomerResponse(
                         1L, TEST_USERNAME, TEST_EMAIL, "9848022334", "junitAddress", 0));

Also applies to: 77-80

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8482b28 and c4acc54.

⛔ Files ignored due to path filters (1)
  • retail-store-webapp/pom.xml is excluded by !**/*.xml
📒 Files selected for processing (20)
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/ClientsConfig.java (1 hunks)
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/PagedResult.java (1 hunks)
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/catalog/CatalogServiceClient.java (1 hunks)
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/customer/CustomerServiceClient.java (1 hunks)
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/inventory/InventoryServiceClient.java (1 hunks)
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderServiceClient.java (1 hunks)
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/config/WebConfig.java (1 hunks)
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/exception/ResourceNotFoundException.java (1 hunks)
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/ProductController.java (4 hunks)
  • retail-store-webapp/src/main/resources/application.properties (2 hunks)
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/common/AbstractIntegrationTest.java (2 hunks)
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/common/ContainerConfig.java (1 hunks)
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java (2 hunks)
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/LoginControllerTest.java (1 hunks)
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerIT.java (3 hunks)
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerTest.java (1 hunks)
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerIT.java (2 hunks)
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerTest.java (3 hunks)
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerIT.java (7 hunks)
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerTest.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: Use imports rather than fully qualified class names in code
Run spotless:apply after any formatting rule changes to maintain consistent code style

Files:

  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderServiceClient.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/common/ContainerConfig.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/inventory/InventoryServiceClient.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerIT.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/config/WebConfig.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/PagedResult.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/LoginControllerTest.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/customer/CustomerServiceClient.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/ClientsConfig.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/catalog/CatalogServiceClient.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerIT.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/common/AbstractIntegrationTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerIT.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/exception/ResourceNotFoundException.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerTest.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/ProductController.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java
**/src/main/java/**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Search for @KafkaListener, @KafkaTemplate, and topic constants in service source code to verify event contracts and Kafka message producers/consumers

Files:

  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderServiceClient.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/inventory/InventoryServiceClient.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/config/WebConfig.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/PagedResult.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/customer/CustomerServiceClient.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/ClientsConfig.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/catalog/CatalogServiceClient.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/exception/ResourceNotFoundException.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/ProductController.java
**/*.{properties,yml,yaml}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use the local Spring profile when running services against Dockerized infrastructure (e.g., -Dspring-boot.run.profiles=local)

Files:

  • retail-store-webapp/src/main/resources/application.properties
**/src/main/resources/application*.{properties,yml,yaml}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Expose actuator endpoints under /actuator and Swagger UI endpoints at /swagger-ui.html for observability and API documentation

Files:

  • retail-store-webapp/src/main/resources/application.properties
**/*Test.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*Test.java: Use AssertJ for assertions in all test files
Run unit tests for a specific module before merging changes using ./mvnw -pl <module> test (Unix) or .mvnw.cmd -pl <module> test (Windows)

Files:

  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/LoginControllerTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/common/AbstractIntegrationTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java
**/src/main/java/**/controller/**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Update API controllers and DTOs in the same module when changing a service API

Files:

  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/ProductController.java
🧠 Learnings (4)
📚 Learning: 2025-12-01T03:54:08.848Z
Learnt from: CR
Repo: rajadilipkolli/spring-boot-microservices-series-v2 PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-01T03:54:08.848Z
Learning: Applies to **/src/main/java/**/controller/**/*.java : Update API controllers and DTOs in the same module when changing a service API

Applied to files:

  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderServiceClient.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerIT.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/LoginControllerTest.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/customer/CustomerServiceClient.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerIT.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/common/AbstractIntegrationTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerIT.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerTest.java
  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/ProductController.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java
📚 Learning: 2025-12-01T03:54:08.848Z
Learnt from: CR
Repo: rajadilipkolli/spring-boot-microservices-series-v2 PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-01T03:54:08.848Z
Learning: Applies to **/src/main/resources/application*.{properties,yml,yaml} : Expose actuator endpoints under `/actuator` and Swagger UI endpoints at `/swagger-ui.html` for observability and API documentation

Applied to files:

  • retail-store-webapp/src/main/resources/application.properties
📚 Learning: 2025-12-01T03:54:08.848Z
Learnt from: CR
Repo: rajadilipkolli/spring-boot-microservices-series-v2 PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-01T03:54:08.848Z
Learning: Applies to **/*Test.java : Use AssertJ for assertions in all test files

Applied to files:

  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/LoginControllerTest.java
  • retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java
📚 Learning: 2025-12-01T03:54:08.848Z
Learnt from: CR
Repo: rajadilipkolli/spring-boot-microservices-series-v2 PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-01T03:54:08.848Z
Learning: Spring Boot microservices architecture comprises: API Gateway (single entry point), Service Registry (Eureka), Config Server, domain services (catalog, inventory, order, payment), UI (Thymeleaf), and asynchronous Kafka messaging

Applied to files:

  • retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/ClientsConfig.java
🧬 Code graph analysis (5)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/LoginControllerTest.java (2)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerTest.java (1)
  • WebMvcTest (36-175)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java (1)
  • WebMvcTest (29-149)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerTest.java (3)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerTest.java (1)
  • WebMvcTest (36-175)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java (1)
  • WebMvcTest (29-149)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerTest.java (1)
  • WebMvcTest (47-261)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerTest.java (2)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java (1)
  • WebMvcTest (29-149)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerTest.java (1)
  • WebMvcTest (47-261)
retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/ProductController.java (2)
retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/InventoryController.java (1)
  • Controller (20-75)
retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/OrderController.java (1)
  • Controller (26-107)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/InventoryControllerTest.java (1)
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/LoginControllerTest.java (1)
  • WebMvcTest (19-45)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (26)
retail-store-webapp/src/main/java/com/example/retailstore/webapp/exception/ResourceNotFoundException.java (1)

12-14: LGTM! Modern Java idiom.

The use of String.formatted(...) is a more concise and idiomatic approach in modern Java (15+). This change is functionally equivalent to the previous implementation and aligns well with the Spring Boot 4.x upgrade.

retail-store-webapp/src/test/java/com/example/retailstore/webapp/common/ContainerConfig.java (1)

11-11: Keycloak test image bump looks fine; verify container startup with 26.4.7

This is a clean, localized change: only the KEYCLOAK_IMAGE constant is updated, and all usage goes through new KeycloakContainer(KEYCLOAK_IMAGE), so there’s no code‑side regression visible here. The only remaining concern is runtime compatibility (admin credentials, realm import behavior) of the 26.4.7 image versus the previous one, which CI or a quick local test should confirm.

Please confirm that the Keycloak testcontainer still starts successfully and imports retailstore-realm.json without errors under the new 26.4.7 image (e.g., via your existing test suite run).

retail-store-webapp/src/main/resources/application.properties (2)

35-36: The HTTP client configuration property names are correct for Spring Boot 4.0.0.

The properties spring.http.clients.read-timeout and spring.http.clients.connect-timeout (plural "clients") are the correct property names in Spring Boot 4.0.0, and the Duration values (PT10S and PT5S) use the valid ISO-8601 format. No changes are needed for these lines.

However, per the coding guidelines for **/src/main/resources/application*.{properties,yml,yaml}, this file should also expose Swagger UI endpoints at /swagger-ui.html. The Swagger UI configuration is missing and should be added to comply with observability and API documentation requirements.


13-13: The tracing configuration property is correct for Spring Boot 4.0.0.

The management.tracing.export.enabled=false property on line 13 is the correct replacement for the deprecated management.tracing.enabled property in Spring Boot 4.0.0. The property name and syntax are valid. The actuator endpoints are properly exposed under /actuator via the existing management.endpoints.web.exposure.include=* configuration.

retail-store-webapp/src/main/java/com/example/retailstore/webapp/config/WebConfig.java (1)

3-16: JSpecify @NonNull annotation is correctly applied and consistent with codebase migration

The import and usage of org.jspecify.annotations.NonNull on the CorsRegistry parameter is correct. The codebase has already been fully migrated to JSpecify annotations across all 11 Java configuration and service files; no legacy javax.annotation, jakarta.annotation, or org.springframework.lang nullability annotations remain.

retail-store-webapp/src/test/java/com/example/retailstore/webapp/common/AbstractIntegrationTest.java (2)

9-9: Verify the AutoConfigureMockMvc import path for Spring Boot 4.0.

Similar to the WebMvcTest import issue, the import path org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc appears non-standard. Please verify this is the correct package for Spring Boot 4.0.


14-24: Good migration to JsonMapper.

The change from ObjectMapper to JsonMapper is appropriate for Jackson 3.x. JsonMapper is the JSON-specific implementation and is the recommended type when working exclusively with JSON data.

retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerIT.java (2)

17-17: Jackson 3.x exception hierarchy update.

The change from JsonProcessingException to JacksonException is appropriate for Jackson 3.x, where JacksonException is the base exception type. This provides broader exception coverage.

Also applies to: 32-32


51-51: Consistent JsonMapper usage.

The migration from objectMapper to jsonMapper is consistent with the field type change in AbstractIntegrationTest and aligns with Jackson 3.x best practices.

Also applies to: 54-54, 60-60, 85-85, 117-117, 142-142, 167-167

retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/order/OrderServiceClient.java (1)

10-10: Good use of @HttpExchange for declarative HTTP clients.

The addition of @HttpExchange("/order-service") is appropriate for Spring Boot 4.0's declarative HTTP interface support (Spring Framework 6.1+). This centralizes the base URL configuration and simplifies client setup.

Also applies to: 13-13

retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/inventory/InventoryServiceClient.java (1)

8-8: Consistent HTTP interface client pattern.

The @HttpExchange annotation follows the same pattern as OrderServiceClient, providing a clean, declarative approach to HTTP client configuration in Spring Boot 4.0.

Also applies to: 11-11

retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerIT.java (2)

47-47: Consistent JsonMapper migration.

All objectMapper references correctly updated to jsonMapper, consistent with the parent class AbstractIntegrationTest changes.

Also applies to: 54-54, 59-59, 84-84, 90-90, 114-114


108-108: No action required—0L correctly matches the Long totalElements parameter.

The PagedResult class uses Long (wrapper type) for the totalElements parameter. The code at line 108 correctly uses 0L as a Long literal, which is consistent with all other explicit PagedResult instantiations across the codebase (e.g., 2L, 3L, 1L in test files). Using 0 (primitive int) would cause a type mismatch.

retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/OrderControllerTest.java (1)

37-37: The import path is correct for Spring Boot 4.0.

The import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest is the correct path for Spring Boot 4.0. In this version, Spring Boot restructured its test dependencies and modularized the testing infrastructure. The package path you suggested (org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest) was used in Spring Boot 2/3 but is no longer valid for Spring Boot 4.0. The current import is consistent across the test suite and requires the spring-boot-starter-webmvc-test dependency.

Likely an incorrect or invalid review comment.

retail-store-webapp/src/main/java/com/example/retailstore/webapp/web/controller/ProductController.java (2)

9-9: LGTM! Framework upgrade changes applied correctly.

The import path change from com.fasterxml.jackson to tools.jackson aligns with the Jackson 3.x upgrade in Spring Boot 4.0.0, and the constructor injection pattern for both dependencies is appropriate.

Also applies to: 20-20, 26-27, 29-31


48-56: LGTM!

The delegation to catalogServiceClient.createProduct() is straightforward and maintains proper error handling.

retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerIT.java (3)

86-87: LGTM!

The explicit null assertion for imageUrl is appropriate given the test data doesn't provide this field.


93-93: LGTM! Method signature simplified.

Removing the throws Exception clause is appropriate since the test framework handles exceptions thrown from test methods.


121-121: jsonMapper is available in the test context.

The field is properly defined as protected JsonMapper jsonMapper in AbstractIntegrationTest and autowired at line 24. ProductControllerIT inherits this field and can use it directly. No issues found.

retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/ProductControllerTest.java (2)

26-26: LGTM! Framework upgrade imports applied correctly.

The import path changes reflect Spring Boot 4.0.0 and Jackson 3.x upgrades:

  • WebMvcTest moved to org.springframework.boot.webmvc.test.autoconfigure
  • ObjectMapper moved to tools.jackson.databind

Also applies to: 34-34


47-47: Test correctly updated for new API contract.

The test properly mocks CatalogServiceClient.getProducts() to return a JSON string (using objectMapper.writeValueAsString(pagedResult)), which is consistent with the updated service client signature.

However, this test is coupled to the manual JSON parsing approach in ProductController.products() (lines 63-107). If the recommendation to revert to typed responses is adopted, these mocks should also be updated to return PagedResult<ProductResponse> directly.

Also applies to: 103-103, 126-126

retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/catalog/CatalogServiceClient.java (1)

6-6: LGTM! Base path annotation aligns with centralized HTTP client configuration.

The @HttpExchange("/catalog-service") annotation correctly establishes the base path for catalog service endpoints, consistent with the new @ImportHttpServices configuration in ClientsConfig.

Also applies to: 9-9

retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/ClientsConfig.java (2)

13-14: LGTM! Centralized HTTP service registration improves maintainability.

The @ImportHttpServices annotation with explicit service client listing provides clear visibility of all HTTP clients in one place, and the new imports support the group-based configuration approach.

Also applies to: 17-22


26-35: LGTM! Group-based configuration centralizes client setup.

The RestClientHttpServiceGroupConfigurer approach cleanly applies common settings (base URL, headers, observation registry) to all HTTP service clients, eliminating the need for individual bean definitions. This is a best practice for Spring Boot 4.0.0.

retail-store-webapp/src/main/java/com/example/retailstore/webapp/clients/PagedResult.java (1)

8-14: Document the rationale for wrapper types and consider null safety.

The change from primitive types to wrapper types (e.g., longLong, booleanBoolean) introduces nullability where it wasn't possible before. This changes the contract of PagedResult and requires callers to handle potential null values.

Please clarify:

  1. Is this change required for Jackson 3.x / Spring Boot 4.0.0 compatibility?
  2. Are there specific serialization scenarios where nulls are expected?

If wrapper types aren't strictly necessary, consider:

  • Reverting to primitives for better null safety
  • Or adding @NonNull annotations to document that nulls shouldn't occur
  • Or providing default values in a secondary constructor

Search for documentation on Jackson 3.x record serialization requirements:

Does Jackson 3.x require wrapper types for record fields in Java?
retail-store-webapp/src/test/java/com/example/retailstore/webapp/web/controller/RegistrationControllerTest.java (1)

19-30: Import updates to Spring Boot 4 and Jackson 3 are correct, but test lacks AssertJ assertions per guidelines

The new imports on lines 21 and 27 correctly target Spring Boot 4's test module and Jackson 3:

  • org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest
  • tools.jackson.databind.ObjectMapper

However, the test violates two coding guidelines:

  1. Use AssertJ for assertions: This test file uses hamcrest matchers (is(), jsonPath()) instead of AssertJ. All test files must use AssertJ per coding guidelines.

  2. Avoid fully qualified class names: Lines 58–60 and 78–80 use FQCNs for com.example.retailstore.webapp.clients.customer.CustomerRequest and com.example.retailstore.webapp.clients.customer.CustomerResponse instead of importing them.

Add AssertJ imports and assertions, replace hamcrest matchers with AssertJ equivalents, and import the customer DTOs.

Note: An old Jackson 2 import (com.fasterxml.jackson.databind.ObjectMapper) still exists in gatling-tests/src/test/java/simulation/BaseSimulation.java and should be updated to the Jackson 3 style.

⛔ Skipped due to learnings
Learnt from: CR
Repo: rajadilipkolli/spring-boot-microservices-series-v2 PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-01T03:54:08.848Z
Learning: Applies to **/*Test.java : Use AssertJ for assertions in all test files

@rajadilipkolli rajadilipkolli merged commit 88b58f0 into main Dec 7, 2025
8 of 9 checks passed
@rajadilipkolli rajadilipkolli deleted the renovate/major-spring-boot branch December 7, 2025 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants