feat: migrate eShopLegacyMVC from .NET Framework 4.7.2 to Java 21 / Spring Boot 3.5#2
Open
devin-ai-integration[bot] wants to merge 7 commits into
Open
feat: migrate eShopLegacyMVC from .NET Framework 4.7.2 to Java 21 / Spring Boot 3.5#2devin-ai-integration[bot] wants to merge 7 commits into
devin-ai-integration[bot] wants to merge 7 commits into
Conversation
…pring Boot 3.5 Complete 8-phase migration of the eShopLegacyMVC ASP.NET MVC 5 application to Java 21 with Spring Boot 3.5.x. All new Java code is in eShopModernizedJava/. Phase 1 - Project Scaffolding: - Maven project with spring-boot-starter-parent 3.5.0, Java 21 - Spring Boot application entry point (CatalogApplication) - application.yml with SQL Server, Flyway, and app config - Logback logging config ported from log4net.xml - Static assets (CSS, product images, setup CSVs) copied Phase 2 - Domain Model: - JPA entities: CatalogItem, CatalogBrand, CatalogType - HiLo sequence generators matching legacy SQL Server sequences - Flyway migrations for schema and sequences - PaginatedItemsDto replacing PaginatedItemsViewModel Phase 3 - Repository & Seeding: - Spring Data JPA repositories with EntityGraph for eager loading - PreconfiguredData with 12 items, 5 brands, 4 types - CatalogDbInitializer (ApplicationRunner) with CSV import support Phase 4 - Service Layer: - CatalogService interface matching ICatalogService.cs - CatalogServiceImpl with JPA (ConditionalOnProperty) - CatalogServiceMock in-memory implementation - AppConfig for custom configuration properties Phase 5 - MVC Controllers & Views: - CatalogController with full CRUD (/, details, create, edit, delete) - PicController for product image serving with MIME type detection - Thymeleaf templates with layout dialect replacing Razor views - GlobalExceptionHandler replacing HandleErrorAttribute Phase 6 - REST API: - BrandsRestController (/api/brands) - GET all, GET by id, DELETE (no-op) - FilesRestController (/api/files) - returns JSON instead of BinaryFormatter - CatalogRestController (/api) - Hello World endpoint - BrandDto record replacing BinaryFormatter-serialized BrandDTO Phase 7 - Observability: - Spring Boot Actuator (health, metrics, prometheus) - Micrometer Prometheus registry - OpenTelemetry tracing via micrometer-tracing-bridge-otel - RequestLoggingInterceptor with MDC (replaces ActivityIdHelper) Phase 8 - Deployment: - Spring Security (permit all, CSRF for forms) - HttpSessionListener (replaces Global.asax Session_Start) - Multi-stage Dockerfile with eclipse-temurin:21 - Docker Compose with SQL Server 2022 - Migration documentation in README.md
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
… protection - CatalogServiceImpl: resolve CatalogBrand/CatalogType entity references via repository lookups before calling save() in create/update operations. Fixes PropertyValueException from null @manytoone(optional=false) refs. - CatalogDbInitializer: resolve entity references on seed items after brands and types are persisted, before saving catalog items. - PicController: reject pictureFileName containing '..', '/', or '\' to prevent path traversal attacks via crafted filenames.
…, validate CSV headers - V2__create_sequences.sql: START WITH 100 for all three sequences so generated IDs don't collide with preconfigured seed data (items 1-12, brands 1-5, types 1-4). - CatalogDbInitializer: validate CSV header indices before use to prevent ArrayIndexOutOfBoundsException with unexpected CSV formats.
- CatalogController: clamp pageSize to minimum 1 and pageIndex to minimum 0 - PaginatedItemsDto: defend against division by zero when pageSize <= 0
- CatalogItem, CatalogBrand, CatalogType: change @id from primitive int to Integer so Spring Data's isNew() returns true for new entities (null id) triggering persist(), and false for seed data with explicit IDs triggering merge() which preserves the pre-set IDs. - CatalogServiceMock: change == to .equals() for Integer comparisons in updateCatalogItem() and removeCatalogItem() to avoid reference equality issues with Integer wrapper objects.
…error - edit.html: add hidden field for onReorder to prevent silent reset to false - CatalogController: call addUriPlaceholder() before re-rendering edit form on validation errors so product image displays correctly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Complete 8-phase migration of the eShopLegacyMVC ASP.NET MVC 5 application (.NET Framework 4.7.2) to Java 21 with Spring Boot 3.5.x. All new Java code lives in
eShopModernizedJava/— the legacy .NET code is untouched.What's included:
@ConditionalOnProperty)Breaking change:
/api/filesnow returns JSON instead of binary-serialized data. The legacyBinaryFormatterineShopLegacy.Utilities/Serializing.cswas a known security vulnerability (CVE-2021-24112) and has been eliminated entirely.Build verified:
./mvnw clean testpasses (compilation + Spring Boot context loads with H2 in mock data mode).Review feedback addressed:
CatalogServiceImplandCatalogDbInitializernow resolve@ManyToOneentity references before savingPicController: rejects filenames containing..,/, or\\Review & Testing Checklist for Human
./mvnw clean packageineShopModernizedJava/to verify the build compiles and tests pass with Java 21./mvnw spring-boot:run -Dspring-boot.run.arguments="--app.use-mock-data=true") and verify:/items/{id}/picGET /api/brandsreturns JSON array of 5 brandsGET /api/brands/1returns single brandGET /api/filesreturns JSON list of BrandDto (NOT binary)DELETE /api/brands/1returns 200 (no-op)GET /actuator/healthandGET /actuator/prometheusrespond correctlydocker-compose upineShopModernizedJava/— verify full CRUD against SQL Server with Flyway migrationsRecommended test plan: Start with mock data mode (no database required) to verify UI and API. Then test with Docker Compose for full SQL Server integration including Flyway migrations and data seeding.
Notes
@Patternannotation was removed from theBigDecimal pricefield in CatalogItem since Jakarta Validation's@Patternonly applies toCharSequencetypes. The@DecimalMin/@DecimalMaxconstraints provide equivalent validation.@EntityGraphfor eager loading of CatalogBrand and CatalogType relationships, replacing EF's.Include().Link to Devin session: https://partner-workshops.devinenterprise.com/sessions/fdea619c44c04acfbe300b74485c468d
Requested by: @mbatchelor81