diff --git a/.github/modernize/assessment/reports/report-20260521063406/facts/api-service-contracts.md b/.github/modernize/assessment/reports/report-20260521063406/facts/api-service-contracts.md new file mode 100644 index 000000000..6c6196b1e --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260521063406/facts/api-service-contracts.md @@ -0,0 +1,70 @@ +# API & Service Communication Contracts + +The application exposes a compact HTTP surface with browser-facing endpoints for gallery browsing, upload, detail navigation, image retrieval, and deletion. Communication is synchronous within a single deployable service. + +## Service Catalog + +| Service | Port | Category | Purpose | +|---|---:|---|---| +| photo-album (single Spring Boot module) | 8080 | Business | Serves UI pages, upload API, and image delivery endpoints | + +## API Endpoints Inventory + +| Service | Method | Path | Request Type | Response Type | +|---|---|---|---|---| +| photo-album (`HomeController`) | GET | `/` | No body | HTML view (`index`) | +| photo-album (`HomeController`) | POST | `/upload` | Multipart `files[]` | JSON map with `success`, `uploadedPhotos`, `failedUploads` | +| photo-album (`DetailController`) | GET | `/detail/{id}` | Path param `id` | HTML view (`detail`) or redirect | +| photo-album (`DetailController`) | POST | `/detail/{id}/delete` | Path param `id` | Redirect to `/` with flash message | +| photo-album (`PhotoFileController`) | GET | `/photo/{id}` | Path param `id` | Binary resource with media type headers or 404/500 | + +## Management & Observability Endpoints + +| Service | Endpoint | Custom Metrics (if any) | +|---|---|---| +| photo-album | None explicitly declared in code/config | None detected | + +## DTOs & Contracts + +API contract objects include: +- `UploadResult` (mutable POJO): service-level upload outcome object used to represent success/failure and associated photo id. +- `Photo` (domain entity reused in API/view model): used for response data in controllers and template rendering. +- Upload response payload is composed as a dynamic `Map` with uploaded/failed item lists. + +No OpenAPI/Swagger, GraphQL schema, or protobuf contract files were detected. Serialization relies on Spring Boot JSON/Jackson defaults. + +## Communication Patterns + +All service communication is synchronous request/response over HTTP between browser clients and the single backend service. Controllers delegate to `PhotoServiceImpl`, which performs transactional database work through `PhotoRepository`. No async messaging, circuit breaker, retry policy, or service discovery framework is present. API availability depends on datasource readiness; if Oracle is unavailable, persistence-backed operations fail. Security posture: no explicit authentication, authorization, or TLS enforcement is configured in application code. + +## Service Technology Matrix + +| Service | Web | Data Access | Discovery | Gateway | Actuator | Cache | Metrics | +|---|---|---|---|---|---|---|---| +| photo-album | Spring MVC + Thymeleaf | Spring Data JPA / Hibernate / Oracle JDBC | None | None | None detected | None detected | None detected | + +## Service Communication Sequence + +```mermaid +sequenceDiagram + participant User as "Browser Client" + participant Home as "HomeController" + participant Service as "PhotoServiceImpl" + participant Repo as "PhotoRepository" + participant DB as "Oracle Database" + + User->>Home: POST /upload (multipart files) + Home->>Service: uploadPhoto(file) + Service->>Service: validate mime type and size + alt Validation passes + Service->>Repo: save(Photo) + Repo->>DB: INSERT photo metadata and BLOB + DB-->>Repo: persisted row + Repo-->>Service: saved Photo(id) + Service-->>Home: UploadResult success + Home-->>User: 200 JSON upload summary + else Validation fails + Service-->>Home: UploadResult failure + Home-->>User: 200 JSON with failedUploads + end +``` diff --git a/.github/modernize/assessment/reports/report-20260521063406/facts/architecture-diagram.md b/.github/modernize/assessment/reports/report-20260521063406/facts/architecture-diagram.md new file mode 100644 index 000000000..fcebd1094 --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260521063406/facts/architecture-diagram.md @@ -0,0 +1,103 @@ +# Architecture Diagram + +This application is a single Spring Boot web service that serves Thymeleaf pages and REST-style upload/file endpoints for photo management backed by an Oracle database. + +## Application Architecture + +```mermaid +flowchart TD + subgraph Client["Client Layer"] + Browser["Web Browser"] + end + + subgraph App["Application Layer - Spring Boot 2.7"] + MVC["Spring MVC Controllers"] + Views["Thymeleaf Templates"] + Service["PhotoService"] + end + + subgraph Data["Data Layer"] + Repo["Spring Data JPA Repository"] + Oracle[("Oracle Database PHOTOS table")] + Blob[("BLOB photo data")] + end + + Browser -->|"GET/POST requests"| MVC + MVC -->|"render views"| Views + MVC -->|"invoke business logic"| Service + Service -->|"CRUD and queries"| Repo + Repo -->|"SQL operations"| Oracle + Oracle -->|"stores image bytes"| Blob +``` + +### Technology Stack Summary + +| Layer | Technology | Version | Purpose | +|---|---|---|---| +| Presentation | Spring MVC + Thymeleaf | Spring Boot 2.7.18 | Handles gallery UI and request routing | +| Business | Spring Service + Validation | Spring Boot 2.7.18 | Enforces upload rules and photo lifecycle operations | +| Data Access | Spring Data JPA + Hibernate | Spring Boot 2.7.18 | Repository abstraction and ORM integration | +| Data Store | Oracle JDBC (`ojdbc8`) | Runtime dependency | Persistent storage for metadata and BLOB image data | + +### Data Storage & External Services + +The primary runtime datastore is Oracle, with the `PHOTOS` table storing both metadata and raw image data in a BLOB column. Test executions use H2 in-memory storage via the test profile, and there are no outbound third-party API integrations in core request flows. + +### Key Architectural Decisions + +- Stores photo binary content directly in the database (`@Lob`) instead of serving from external object storage. +- Uses constructor injection and a thin-controller/service/repository layering to keep controller logic focused on HTTP concerns. +- Uses environment/profile-based datasource switching (`default`/`docker` runtime vs `test` profile with H2). + +## Component Relationships + +```mermaid +flowchart LR + subgraph Presentation["Presentation"] + HomeCtrl["HomeController"] + DetailCtrl["DetailController"] + FileCtrl["PhotoFileController"] + end + + subgraph Business["Business Logic"] + PhotoSvc["PhotoServiceImpl"] + UploadRes["UploadResult"] + end + + subgraph DataAccess["Data Access"] + PhotoRepo["PhotoRepository"] + PhotoEntity["Photo Entity"] + end + + subgraph Infra["Infrastructure"] + Tx["Spring Transactions"] + Log["SLF4J Logging"] + OracleDB["Oracle DB"] + end + + HomeCtrl -->|"list/upload"| PhotoSvc + DetailCtrl -->|"detail/delete/navigation"| PhotoSvc + FileCtrl -->|"fetch bytes"| PhotoSvc + PhotoSvc -->|"save/query/delete"| PhotoRepo + PhotoRepo -->|"maps rows"| PhotoEntity + PhotoRepo -->|"native SQL"| OracleDB + Tx -.->|"transaction boundary"| PhotoSvc + Log -.->|"cross-cutting logs"| HomeCtrl + Log -.->|"cross-cutting logs"| DetailCtrl + Log -.->|"cross-cutting logs"| FileCtrl +``` + +### Component Inventory + +| Component | Layer | Type | Responsibility | +|---|---|---|---| +| HomeController | Presentation | MVC Controller | Renders gallery and handles batch upload requests | +| DetailController | Presentation | MVC Controller | Renders single photo detail and delete actions | +| PhotoFileController | Presentation | MVC Controller | Streams image binary content for `/photo/{id}` | +| PhotoServiceImpl | Business Logic | Service | Validates files, handles photo persistence and navigation operations | +| UploadResult | Business Logic | DTO | Captures per-file upload outcome for API responses | +| PhotoRepository | Data Access | Spring Data Repository | Executes CRUD and custom Oracle-native queries | +| Photo | Data Access | JPA Entity | Represents persisted photo metadata and image BLOB | +| Spring Transactions | Infrastructure | Framework Concern | Ensures atomic writes and consistent data operations | +| SLF4J Logging | Infrastructure | Cross-cutting Concern | Provides operational/error tracing across controllers and service | +``` diff --git a/.github/modernize/assessment/reports/report-20260521063406/facts/assessment-overview.md b/.github/modernize/assessment/reports/report-20260521063406/facts/assessment-overview.md new file mode 100644 index 000000000..52367ce28 --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260521063406/facts/assessment-overview.md @@ -0,0 +1,10 @@ +# Assessment Overview + +This directory contains supplementary architecture and analysis documents generated during application assessment. + +- [architecture-diagram.md](./architecture-diagram.md) — High-level and component-level architecture diagrams. +- [dependency-map.md](./dependency-map.md) — External dependency inventory and compatibility observations. +- [api-service-contracts.md](./api-service-contracts.md) — Service catalog, endpoint contracts, and communication sequence. +- [data-architecture.md](./data-architecture.md) — Persistence model, repository methods, and data classification notes. +- [configuration-inventory.md](./configuration-inventory.md) — Configuration sources, profiles, properties, and secrets workflow. +- [business-workflows.md](./business-workflows.md) — Core business processes and decision logic. diff --git a/.github/modernize/assessment/reports/report-20260521063406/facts/business-workflows.md b/.github/modernize/assessment/reports/report-20260521063406/facts/business-workflows.md new file mode 100644 index 000000000..f0da716a4 --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260521063406/facts/business-workflows.md @@ -0,0 +1,72 @@ +# Core Business Workflows + +The application enables users to upload, browse, inspect, and delete photos in a lightweight gallery experience. Core workflows focus on validating uploads and managing a photo collection lifecycle. + +## Domain Entities + +| Entity | Service / Bounded Context | Description | Key Relationships | +|---|---|---|---| +| Photo | Photo Management | Canonical record for stored image content and metadata | Used by upload, gallery listing, detail viewing, and deletion workflows | +| UploadResult | Photo Management | Operation result object for per-file upload outcomes | Produced by upload workflow and aggregated into response payload | + +## Service-to-Domain Mapping + +| Service | Domain Context | Owned Entities | External Dependencies | +|---|---|---|---| +| photo-album | Photo Management | `Photo`, `UploadResult` | Oracle database via repository layer | + +## Primary Workflows + +### Workflow 1: Upload Photos to Gallery + +Entry point: `POST /upload` +1. User selects one or more files and submits upload. +2. Service validates MIME type, file size, and non-empty content. +3. Service extracts image dimensions and prepares persisted `Photo` entity. +4. Repository saves metadata and binary content. +5. Response aggregates successful and failed files for user feedback. + +### Workflow 2: Browse, View Detail, and Delete + +Entry points: `GET /`, `GET /detail/{id}`, `POST /detail/{id}/delete`, `GET /photo/{id}` +1. Gallery page requests photo list sorted by newest uploads. +2. Detail page resolves specific photo plus previous/next navigation candidates. +3. Binary endpoint streams image bytes for rendering. +4. Delete action removes selected photo and returns to gallery with status message. + +## Cross-Service Data Flows + +No cross-service composition is present. All workflow data is owned and served by a single service and one backing datastore, so business responses are assembled internally without downstream service joins or fallback routing. + +## Business Workflow Sequence + +```mermaid +sequenceDiagram + participant User as "Gallery User" + participant UI as "HomeController" + participant Service as "PhotoServiceImpl" + participant Repo as "PhotoRepository" + participant DB as "Oracle Database" + + User->>UI: Submit photo upload request + UI->>Service: Process uploaded files + Service->>Service: Validate file type and size rules + alt File valid + Service->>Repo: Save photo record + Repo->>DB: Persist metadata and image content + DB-->>Repo: Save successful + Repo-->>Service: Persisted photo id + else File invalid + Service-->>Service: Mark upload as failed + end + Service-->>UI: Return upload summary + UI-->>User: Show success/failure results in gallery +``` + +## Business Rules & Decision Logic + +- Uploads must be image MIME types from an allowed list and within configured maximum size. +- Empty files are rejected before persistence. +- Navigation logic selects previous/next photos based on upload timestamp ordering. +- Deletion only succeeds when the target photo exists; otherwise user receives not-found feedback. +- Transaction boundary is at service layer (`@Transactional`) to keep write operations consistent. diff --git a/.github/modernize/assessment/reports/report-20260521063406/facts/configuration-inventory.md b/.github/modernize/assessment/reports/report-20260521063406/facts/configuration-inventory.md new file mode 100644 index 000000000..8f02b3837 --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260521063406/facts/configuration-inventory.md @@ -0,0 +1,85 @@ +# Configuration & Externalized Settings Inventory + +Configuration is primarily file-based with Spring properties for server, datasource, JPA, upload limits, and logging. Runtime behavior switches mainly through Spring profiles (`default`, `docker`, and `test`) and container environment overrides. + +## Configuration Sources + +| Source | Type | Path/Location | Notes | +|---|---|---|---| +| Main Spring properties | Application config | `src/main/resources/application.properties` | Base server, datasource, JPA, upload, logging settings | +| Docker profile properties | Application config | `src/main/resources/application-docker.properties` | Overrides for containerized runtime profile | +| Test profile properties | Test config | `src/test/resources/application-test.properties` | H2 in-memory datasource for tests | +| Docker Compose service env | Container runtime config | `docker-compose.yml` | Injects active profile and datasource credentials | +| Docker image runtime options | Container startup config | `Dockerfile` | Defines `JAVA_OPTS` and jar startup command | +| Azure setup env output | Provisioning config artifact | `.env` (generated by `azure-setup.ps1`) | Script writes resource and DB environment values | + +## Build Profiles + +| Profile | Activation | Purpose | Key Dependencies/Plugins | +|---|---|---|---| +| Maven default build | Standard `mvn` lifecycle | Build/packaging Spring Boot application jar | `spring-boot-maven-plugin` | + +## Runtime Profiles + +| Profile | Activation Method | Config Files | Key Overrides | +|---|---|---|---| +| default | No explicit profile variable | `application.properties` | Oracle datasource, debug-level app logging | +| docker | `SPRING_PROFILES_ACTIVE=docker` | `application.properties` + `application-docker.properties` | Docker-specific Oracle URL and adjusted logging levels | +| test | `@ActiveProfiles("test")` in tests | `application-test.properties` | H2 datasource and non-SQL logging for tests | + +## Properties Inventory + +| Property Key | Default | Profiles | Source | +|---|---|---|---| +| `server.port` | `8080` | default, docker | application properties files | +| `spring.datasource.url` | Oracle JDBC URL | default, docker, test override | application / docker / test properties | +| `spring.datasource.username` | `photoalbum` (runtime), `sa` (test) | default, docker, test | application / docker / test properties | +| `spring.datasource.password` | configured (runtime), blank (test) | default, docker, test | application / docker / test properties | +| `spring.jpa.hibernate.ddl-auto` | `create` (`create-drop` in test) | default, docker, test | application / docker / test properties | +| `spring.servlet.multipart.max-file-size` | `10MB` | default, docker | application properties files | +| `spring.servlet.multipart.max-request-size` | `50MB` | default, docker | application properties files | +| `app.file-upload.max-file-size-bytes` | `10485760` | default, docker, test | application / docker / test properties | +| `app.file-upload.allowed-mime-types` | jpeg/png/gif/webp list | default, docker, test | application / docker / test properties | +| `logging.level.com.photoalbum` | DEBUG/INFO by profile | default, docker, test | application / docker / test properties | + +## Startup Parameters & Resource Requirements + +| Service | JVM/Runtime Options | Memory | Instance Count | +|---|---|---|---| +| photo-album container | `java $JAVA_OPTS -jar app.jar` | `JAVA_OPTS="-Xmx512m -Xms256m"` in Dockerfile | 1 instance in docker-compose | +| oracle-db container | Oracle image defaults | Not explicitly constrained in compose | 1 instance in docker-compose | + +## Startup Dependency Chain + +1. `oracle-db` starts first and must pass container health check. +2. `photoalbum-java-app` starts after `oracle-db` is healthy (`depends_on` with `condition: service_healthy`). +3. Application handles requests after datasource initialization succeeds. + +## Secrets & Sensitive Configuration + +| Secret Reference | Type | Storage (masked) | +|---|---|---| +| `spring.datasource.password` | Database credential | Application property / environment variable (`[MASKED]`) | +| `ORACLE_PASSWORD`, `APP_USER_PASSWORD` | Container DB credential | `docker-compose.yml` environment (`[MASKED]`) | +| `POSTGRES_PASSWORD` (script-generated) | Provisioning credential | `.env` output from setup script (`[MASKED]`) | + +### Secrets Provisioning Workflow + +Secrets are provided through local configuration files and environment variables. In local/container flows, docker-compose injects DB credentials directly to Oracle and the app service; in scripted Azure setup, credentials are generated/set and written to `.env` for subsequent use by tooling and deployment steps. No managed identity or external secret manager integration is declared in this repository. + +## Feature Flags + +| Flag Name | Default | Controlled By | +|---|---|---| +| None detected | N/A | N/A | + +## Framework & Runtime Versions + +| Component | Version | Source | +|---|---|---| +| Spring Boot | 2.7.18 | `pom.xml` parent | +| Java target | 8 | `pom.xml` properties and Docker base image | +| Maven (build image) | 3.9.6 | `Dockerfile` build stage | +| Oracle JDBC driver | `ojdbc8` | `pom.xml` dependency | +| Container JRE | Eclipse Temurin 8 JRE | `Dockerfile` runtime stage | +| Oracle container DB | `gvenzl/oracle-free:latest` | `docker-compose.yml` | diff --git a/.github/modernize/assessment/reports/report-20260521063406/facts/data-architecture.md b/.github/modernize/assessment/reports/report-20260521063406/facts/data-architecture.md new file mode 100644 index 000000000..b1b3e851b --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260521063406/facts/data-architecture.md @@ -0,0 +1,61 @@ +# Data Architecture & Persistence Layer + +The data layer centers on a single relational model for photo metadata and binary image content using JPA/Hibernate. Runtime persistence uses Oracle, while tests use an in-memory H2 profile. + +## Database Configuration + +| Service/Module | DB Type | Profile | Driver | Connection | Migration Tool | +|---|---|---|---|---|---| +| photo-album | Oracle | default | Oracle JDBC | Oracle service host and port in datasource URL | None detected | +| photo-album | Oracle | docker | Oracle JDBC | Containerized Oracle endpoint in datasource URL | None detected | +| photo-album (tests) | H2 in-memory | test | H2 Driver | In-memory JDBC URL | None detected | + +## Data Ownership per Service + +| Service | Tables Owned | ORM Framework | Caching | Notes | +|---|---|---|---|---| +| photo-album | `PHOTOS` | Spring Data JPA / Hibernate | None detected | Stores both metadata and image BLOB in one table | + +## Entity Model + +```mermaid +erDiagram + PHOTO { + string id PK + string originalFileName + bytes photoData + string storedFileName + string filePath + long fileSize + string mimeType + datetime uploadedAt + int width + int height + } +``` + +## Key Repository Methods + +| Service | Repository | Notable Methods | Purpose | +|---|---|---|---| +| photo-album | `PhotoRepository` (`src/main/java/com/photoalbum/repository/PhotoRepository.java`) | `findAllOrderByUploadedAtDesc()` | Returns gallery list newest first | +| photo-album | `PhotoRepository` | `findPhotosUploadedBefore(LocalDateTime)` | Fetches older photos for previous navigation | +| photo-album | `PhotoRepository` | `findPhotosUploadedAfter(LocalDateTime)` | Fetches newer photos for next navigation | +| photo-album | `PhotoRepository` | `findPhotosByUploadMonth(String,String)` | Oracle-specific month filtering | +| photo-album | `PhotoRepository` | `findPhotosWithPagination(int,int)` | Oracle `ROWNUM` pagination window | +| photo-album | `PhotoRepository` | `findPhotosWithStatistics()` | Uses analytic functions for ranking and running totals | + +## Caching Strategy + +No explicit cache provider or Spring cache annotations were found. Reads and writes are executed directly through repository/database access within transactional service methods. + +## Data Ownership Boundaries + +The application uses a shared single-database and single-service topology: one service both owns and accesses all persisted photo data. There is no cross-service data access pattern, CQRS split, or inter-service aggregation at the data layer. + +### Data Classification & Sensitivity + +| Entity | Sensitive Fields | Classification (PII/PHI/PCI/None) | Controls in Place | +|---|---|---|---| +| `Photo` | `originalFileName` (may contain user-identifying text), `photoData` (image content may include personal data) | PII (potential) | No explicit encryption-at-rest, masking, or field-level access control configured in code | +| `Photo` | No payment or medical attributes detected | None for PCI/PHI | N/A | diff --git a/.github/modernize/assessment/reports/report-20260521063406/facts/dependency-map.md b/.github/modernize/assessment/reports/report-20260521063406/facts/dependency-map.md new file mode 100644 index 000000000..107743232 --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260521063406/facts/dependency-map.md @@ -0,0 +1,72 @@ +# Dependency Map + +Photo Album declares 8 non-test dependencies and 2 test-scope dependencies in a single Maven module. + +## Dependencies + +```mermaid +flowchart LR + App["Photo Album"] + Parent["spring-boot-starter-parent 2.7.18"] + + subgraph Web["Web Frameworks"] + WebStarter["spring-boot-starter-web"] + Thymeleaf["spring-boot-starter-thymeleaf"] + end + + subgraph DB["Database / ORM"] + Jpa["spring-boot-starter-data-jpa"] + Ojdbc["ojdbc8 runtime"] + end + + subgraph Sec["Security"] + Validation["spring-boot-starter-validation"] + end + + subgraph Util["Utilities"] + CommonsIo["commons-io 2.11.0"] + Json["spring-boot-starter-json"] + Devtools["spring-boot-devtools optional"] + end + + App -->|"managed by"| Parent + App -->|"web"| Web + App -->|"persistence"| DB + App -->|"validation"| Sec + App -->|"utilities"| Util + Parent -.->|"version management"| WebStarter + Parent -.->|"version management"| Thymeleaf + Parent -.->|"version management"| Jpa + Parent -.->|"version management"| Validation + Parent -.->|"version management"| Json + Parent -.->|"version management"| Devtools +``` + +### Dependency Summary + +| Category | Count | Key Libraries | Notes | +|---|---:|---|---| +| Web Frameworks | 2 | `spring-boot-starter-web`, `spring-boot-starter-thymeleaf` | Server-rendered MVC application | +| Database / ORM | 2 | `spring-boot-starter-data-jpa`, `ojdbc8` | JPA/Hibernate with Oracle runtime driver | +| Security | 1 | `spring-boot-starter-validation` | Bean validation for upload constraints | +| Utilities | 3 | `commons-io`, `spring-boot-starter-json`, `spring-boot-devtools` | JSON support, file IO helper, local dev hot reload | + +### Version & Compatibility Risks + +The project targets Java 8 and Spring Boot 2.7.x, both of which are older baselines for modernization. Oracle-specific native SQL in repositories and reliance on `ojdbc8` can increase migration effort if moving to another database engine or newer framework stack. + +### Notable Observations + +- Dependency versions are mostly managed by the Spring Boot parent BOM, reducing manual version drift risk. +- The runtime DB dependency is Oracle-specific, and several repository queries use Oracle syntax (`ROWNUM`, `NVL`, `TO_CHAR`). +- No dedicated observability or messaging libraries are declared; the system is a synchronous, single-service web app. + +## Test Dependencies + +| Framework | Version | Notes | +|---|---|---| +| spring-boot-starter-test | Managed by Spring Boot 2.7.18 | Includes JUnit 5 and Spring test support | +| h2 | Managed by Spring Boot 2.7.18 | In-memory database used by `test` profile | + +Total test-scope dependencies: 2 +The test stack is minimal but sufficient for context-load and repository-backed integration testing with an embedded DB. diff --git a/.github/modernize/assessment/reports/report-20260521063406/report.html b/.github/modernize/assessment/reports/report-20260521063406/report.html new file mode 100644 index 000000000..231609c68 --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260521063406/report.html @@ -0,0 +1,1312 @@ + + + +Assessment - photo-album + + + + + +
+

photo-album

+
+

Application Information

+
+
+
+
Application Namephoto-album
+
Java Version1.8
+
EffortL (total story points: 51)
+
+
+
Build ToolsMaven
+
FrameworksSpring Boot, Spring
+
+
+
+
+ +
+
+ + +
+
+

Issue Summary

+
+
+
+ + + + +

Cloud Readiness

+
5 issues
+
+
+ + + + + +

Java Upgrade

+
4 issues
+
+
+
+
Mandatory
+
Potential
+
Optional
+
+
+
+
+
+ +
+ + +
+
+
+ +
+ + + +
+
+ Clear all +
+
+

Cloud Readiness

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Issue CategoryCriticalityStory Point
Oracle database found
Potential8
Password found in configuration file
Potential3
Restricted configurations found
Potential2
Server port configuration found
Potential1
Detects usage of Jakarta Persistence (JPA) APIs
Potential5
+
+
+

Java Upgrade

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Issue CategoryCriticalityStory Point
Spring Boot Version Has Reached the End of OSS Support
Mandatory8
Spring Framework Version Has Reached the End of OSS Support
Mandatory8
Java Version Has Reached the End of Support
Mandatory8
Java Version is not the latest LTS
Optional8
+
+
+
+

Architecture Diagram

+

This application is a single Spring Boot web service that serves Thymeleaf pages and REST-style upload/file endpoints for photo management backed by an Oracle database.

+

Application Architecture

+
+flowchart TD + subgraph Client["Client Layer"] + Browser["Web Browser"] + end + + subgraph App["Application Layer - Spring Boot 2.7"] + MVC["Spring MVC Controllers"] + Views["Thymeleaf Templates"] + Service["PhotoService"] + end + + subgraph Data["Data Layer"] + Repo["Spring Data JPA Repository"] + Oracle[("Oracle Database PHOTOS table")] + Blob[("BLOB photo data")] + end + + Browser -->|"GET/POST requests"| MVC + MVC -->|"render views"| Views + MVC -->|"invoke business logic"| Service + Service -->|"CRUD and queries"| Repo + Repo -->|"SQL operations"| Oracle + Oracle -->|"stores image bytes"| Blob +
+

Technology Stack Summary

+
+ + + + + + +
LayerTechnologyVersionPurpose
PresentationSpring MVC + ThymeleafSpring Boot 2.7.18Handles gallery UI and request routing
BusinessSpring Service + ValidationSpring Boot 2.7.18Enforces upload rules and photo lifecycle operations
Data AccessSpring Data JPA + HibernateSpring Boot 2.7.18Repository abstraction and ORM integration
Data StoreOracle JDBC (ojdbc8)Runtime dependencyPersistent storage for metadata and BLOB image data
+

Data Storage & External Services

+

The primary runtime datastore is Oracle, with the PHOTOS table storing both metadata and raw image data in a BLOB column. Test executions use H2 in-memory storage via the test profile, and there are no outbound third-party API integrations in core request flows.

+

Key Architectural Decisions

+
    +
  • Stores photo binary content directly in the database (@Lob) instead of serving from external object storage.
  • +
  • Uses constructor injection and a thin-controller/service/repository layering to keep controller logic focused on HTTP concerns.
  • +
  • Uses environment/profile-based datasource switching (default/docker runtime vs test profile with H2).
  • +
+

Component Relationships

+
+flowchart LR + subgraph Presentation["Presentation"] + HomeCtrl["HomeController"] + DetailCtrl["DetailController"] + FileCtrl["PhotoFileController"] + end + + subgraph Business["Business Logic"] + PhotoSvc["PhotoServiceImpl"] + UploadRes["UploadResult"] + end + + subgraph DataAccess["Data Access"] + PhotoRepo["PhotoRepository"] + PhotoEntity["Photo Entity"] + end + + subgraph Infra["Infrastructure"] + Tx["Spring Transactions"] + Log["SLF4J Logging"] + OracleDB["Oracle DB"] + end + + HomeCtrl -->|"list/upload"| PhotoSvc + DetailCtrl -->|"detail/delete/navigation"| PhotoSvc + FileCtrl -->|"fetch bytes"| PhotoSvc + PhotoSvc -->|"save/query/delete"| PhotoRepo + PhotoRepo -->|"maps rows"| PhotoEntity + PhotoRepo -->|"native SQL"| OracleDB + Tx -.->|"transaction boundary"| PhotoSvc + Log -.->|"cross-cutting logs"| HomeCtrl + Log -.->|"cross-cutting logs"| DetailCtrl + Log -.->|"cross-cutting logs"| FileCtrl +
+

Component Inventory

+
+ + + + + + + + + + + +
ComponentLayerTypeResponsibility
HomeControllerPresentationMVC ControllerRenders gallery and handles batch upload requests
DetailControllerPresentationMVC ControllerRenders single photo detail and delete actions
PhotoFileControllerPresentationMVC ControllerStreams image binary content for /photo/{id}
PhotoServiceImplBusiness LogicServiceValidates files, handles photo persistence and navigation operations
UploadResultBusiness LogicDTOCaptures per-file upload outcome for API responses
PhotoRepositoryData AccessSpring Data RepositoryExecutes CRUD and custom Oracle-native queries
PhotoData AccessJPA EntityRepresents persisted photo metadata and image BLOB
Spring TransactionsInfrastructureFramework ConcernEnsures atomic writes and consistent data operations
SLF4J LoggingInfrastructureCross-cutting ConcernProvides operational/error tracing across controllers and service
+

+
+
+
+
+

API & Service Communication Contracts

+

The application exposes a compact HTTP surface with browser-facing endpoints for gallery browsing, upload, detail navigation, image retrieval, and deletion. Communication is synchronous within a single deployable service.

+

Service Catalog

+
+ + + +
ServicePortCategoryPurpose
photo-album (single Spring Boot module)8080BusinessServes UI pages, upload API, and image delivery endpoints
+

API Endpoints Inventory

+
+ + + + + + + +
ServiceMethodPathRequest TypeResponse Type
photo-album (HomeController)GET/No bodyHTML view (index)
photo-album (HomeController)POST/uploadMultipart files[]JSON map with success, uploadedPhotos, failedUploads
photo-album (DetailController)GET/detail/{id}Path param idHTML view (detail) or redirect
photo-album (DetailController)POST/detail/{id}/deletePath param idRedirect to / with flash message
photo-album (PhotoFileController)GET/photo/{id}Path param idBinary resource with media type headers or 404/500
+

Management & Observability Endpoints

+
+ + + +
ServiceEndpointCustom Metrics (if any)
photo-albumNone explicitly declared in code/configNone detected
+

DTOs & Contracts

+

API contract objects include:

+
    +
  • UploadResult (mutable POJO): service-level upload outcome object used to represent success/failure and associated photo id.
  • +
  • Photo (domain entity reused in API/view model): used for response data in controllers and template rendering.
  • +
  • Upload response payload is composed as a dynamic Map with uploaded/failed item lists.
  • +
+

No OpenAPI/Swagger, GraphQL schema, or protobuf contract files were detected. Serialization relies on Spring Boot JSON/Jackson defaults.

+

Communication Patterns

+

All service communication is synchronous request/response over HTTP between browser clients and the single backend service. Controllers delegate to PhotoServiceImpl, which performs transactional database work through PhotoRepository. No async messaging, circuit breaker, retry policy, or service discovery framework is present. API availability depends on datasource readiness; if Oracle is unavailable, persistence-backed operations fail. Security posture: no explicit authentication, authorization, or TLS enforcement is configured in application code.

+

Service Technology Matrix

+
+ + + +
ServiceWebData AccessDiscoveryGatewayActuatorCacheMetrics
photo-albumSpring MVC + ThymeleafSpring Data JPA / Hibernate / Oracle JDBCNoneNoneNone detectedNone detectedNone detected
+

Service Communication Sequence

+
+sequenceDiagram + participant User as "Browser Client" + participant Home as "HomeController" + participant Service as "PhotoServiceImpl" + participant Repo as "PhotoRepository" + participant DB as "Oracle Database" + + User->>Home: POST /upload (multipart files) + Home->>Service: uploadPhoto(file) + Service->>Service: validate mime type and size + alt Validation passes + Service->>Repo: save(Photo) + Repo->>DB: INSERT photo metadata and BLOB + DB-->>Repo: persisted row + Repo-->>Service: saved Photo(id) + Service-->>Home: UploadResult success + Home-->>User: 200 JSON upload summary + else Validation fails + Service-->>Home: UploadResult failure + Home-->>User: 200 JSON with failedUploads + end +
+
+
+

Configuration & Externalized Settings Inventory

+

Configuration is primarily file-based with Spring properties for server, datasource, JPA, upload limits, and logging. Runtime behavior switches mainly through Spring profiles (default, docker, and test) and container environment overrides.

+

Configuration Sources

+
+ + + + + + + + +
SourceTypePath/LocationNotes
Main Spring propertiesApplication configsrc/main/resources/application.propertiesBase server, datasource, JPA, upload, logging settings
Docker profile propertiesApplication configsrc/main/resources/application-docker.propertiesOverrides for containerized runtime profile
Test profile propertiesTest configsrc/test/resources/application-test.propertiesH2 in-memory datasource for tests
Docker Compose service envContainer runtime configdocker-compose.ymlInjects active profile and datasource credentials
Docker image runtime optionsContainer startup configDockerfileDefines JAVA_OPTS and jar startup command
Azure setup env outputProvisioning config artifact.env (generated by azure-setup.ps1)Script writes resource and DB environment values
+

Build Profiles

+
+ + + +
ProfileActivationPurposeKey Dependencies/Plugins
Maven default buildStandard mvn lifecycleBuild/packaging Spring Boot application jarspring-boot-maven-plugin
+

Runtime Profiles

+
+ + + + + +
ProfileActivation MethodConfig FilesKey Overrides
defaultNo explicit profile variableapplication.propertiesOracle datasource, debug-level app logging
dockerSPRING_PROFILES_ACTIVE=dockerapplication.properties + application-docker.propertiesDocker-specific Oracle URL and adjusted logging levels
test@ActiveProfiles("test") in testsapplication-test.propertiesH2 datasource and non-SQL logging for tests
+

Properties Inventory

+
+ + + + + + + + + + + + +
Property KeyDefaultProfilesSource
server.port8080default, dockerapplication properties files
spring.datasource.urlOracle JDBC URLdefault, docker, test overrideapplication / docker / test properties
spring.datasource.usernamephotoalbum (runtime), sa (test)default, docker, testapplication / docker / test properties
spring.datasource.passwordconfigured (runtime), blank (test)default, docker, testapplication / docker / test properties
spring.jpa.hibernate.ddl-autocreate (create-drop in test)default, docker, testapplication / docker / test properties
spring.servlet.multipart.max-file-size10MBdefault, dockerapplication properties files
spring.servlet.multipart.max-request-size50MBdefault, dockerapplication properties files
app.file-upload.max-file-size-bytes10485760default, docker, testapplication / docker / test properties
app.file-upload.allowed-mime-typesjpeg/png/gif/webp listdefault, docker, testapplication / docker / test properties
logging.level.com.photoalbumDEBUG/INFO by profiledefault, docker, testapplication / docker / test properties
+

Startup Parameters & Resource Requirements

+
+ + + + +
ServiceJVM/Runtime OptionsMemoryInstance Count
photo-album containerjava $JAVA_OPTS -jar app.jarJAVA_OPTS="-Xmx512m -Xms256m" in Dockerfile1 instance in docker-compose
oracle-db containerOracle image defaultsNot explicitly constrained in compose1 instance in docker-compose
+

Startup Dependency Chain

+
    +
  1. oracle-db starts first and must pass container health check.
  2. +
  3. photoalbum-java-app starts after oracle-db is healthy (depends_on with condition: service_healthy).
  4. +
  5. Application handles requests after datasource initialization succeeds.
  6. +
+

Secrets & Sensitive Configuration

+
+ + + + + +
Secret ReferenceTypeStorage (masked)
spring.datasource.passwordDatabase credentialApplication property / environment variable ([MASKED])
ORACLE_PASSWORD, APP_USER_PASSWORDContainer DB credentialdocker-compose.yml environment ([MASKED])
POSTGRES_PASSWORD (script-generated)Provisioning credential.env output from setup script ([MASKED])
+

Secrets Provisioning Workflow

+

Secrets are provided through local configuration files and environment variables. In local/container flows, docker-compose injects DB credentials directly to Oracle and the app service; in scripted Azure setup, credentials are generated/set and written to .env for subsequent use by tooling and deployment steps. No managed identity or external secret manager integration is declared in this repository.

+

Feature Flags

+
+ + + +
Flag NameDefaultControlled By
None detectedN/AN/A
+

Framework & Runtime Versions

+
+ + + + + + + + +
ComponentVersionSource
Spring Boot2.7.18pom.xml parent
Java target8pom.xml properties and Docker base image
Maven (build image)3.9.6Dockerfile build stage
Oracle JDBC driverojdbc8pom.xml dependency
Container JREEclipse Temurin 8 JREDockerfile runtime stage
Oracle container DBgvenzl/oracle-free:latestdocker-compose.yml
+
+
+

Core Business Workflows

+

The application enables users to upload, browse, inspect, and delete photos in a lightweight gallery experience. Core workflows focus on validating uploads and managing a photo collection lifecycle.

+

Domain Entities

+
+ + + + +
EntityService / Bounded ContextDescriptionKey Relationships
PhotoPhoto ManagementCanonical record for stored image content and metadataUsed by upload, gallery listing, detail viewing, and deletion workflows
UploadResultPhoto ManagementOperation result object for per-file upload outcomesProduced by upload workflow and aggregated into response payload
+

Service-to-Domain Mapping

+
+ + + +
ServiceDomain ContextOwned EntitiesExternal Dependencies
photo-albumPhoto ManagementPhoto, UploadResultOracle database via repository layer
+

Primary Workflows

+ +

Entry point: POST /upload

+
    +
  1. User selects one or more files and submits upload.
  2. +
  3. Service validates MIME type, file size, and non-empty content.
  4. +
  5. Service extracts image dimensions and prepares persisted Photo entity.
  6. +
  7. Repository saves metadata and binary content.
  8. +
  9. Response aggregates successful and failed files for user feedback.
  10. +
+

Workflow 2: Browse, View Detail, and Delete

+

Entry points: GET /, GET /detail/{id}, POST /detail/{id}/delete, GET /photo/{id}

+
    +
  1. Gallery page requests photo list sorted by newest uploads.
  2. +
  3. Detail page resolves specific photo plus previous/next navigation candidates.
  4. +
  5. Binary endpoint streams image bytes for rendering.
  6. +
  7. Delete action removes selected photo and returns to gallery with status message.
  8. +
+

Cross-Service Data Flows

+

No cross-service composition is present. All workflow data is owned and served by a single service and one backing datastore, so business responses are assembled internally without downstream service joins or fallback routing.

+

Business Workflow Sequence

+
+sequenceDiagram + participant User as "Gallery User" + participant UI as "HomeController" + participant Service as "PhotoServiceImpl" + participant Repo as "PhotoRepository" + participant DB as "Oracle Database" + + User->>UI: Submit photo upload request + UI->>Service: Process uploaded files + Service->>Service: Validate file type and size rules + alt File valid + Service->>Repo: Save photo record + Repo->>DB: Persist metadata and image content + DB-->>Repo: Save successful + Repo-->>Service: Persisted photo id + else File invalid + Service-->>Service: Mark upload as failed + end + Service-->>UI: Return upload summary + UI-->>User: Show success/failure results in gallery +
+

Business Rules & Decision Logic

+
    +
  • Uploads must be image MIME types from an allowed list and within configured maximum size.
  • +
  • Empty files are rejected before persistence.
  • +
  • Navigation logic selects previous/next photos based on upload timestamp ordering.
  • +
  • Deletion only succeeds when the target photo exists; otherwise user receives not-found feedback.
  • +
  • Transaction boundary is at service layer (@Transactional) to keep write operations consistent.
  • +
+
+
+

Dependency Map

+

Photo Album declares 8 non-test dependencies and 2 test-scope dependencies in a single Maven module.

+

Dependencies

+
+flowchart LR + App["Photo Album"] + Parent["spring-boot-starter-parent 2.7.18"] + + subgraph Web["Web Frameworks"] + WebStarter["spring-boot-starter-web"] + Thymeleaf["spring-boot-starter-thymeleaf"] + end + + subgraph DB["Database / ORM"] + Jpa["spring-boot-starter-data-jpa"] + Ojdbc["ojdbc8 runtime"] + end + + subgraph Sec["Security"] + Validation["spring-boot-starter-validation"] + end + + subgraph Util["Utilities"] + CommonsIo["commons-io 2.11.0"] + Json["spring-boot-starter-json"] + Devtools["spring-boot-devtools optional"] + end + + App -->|"managed by"| Parent + App -->|"web"| Web + App -->|"persistence"| DB + App -->|"validation"| Sec + App -->|"utilities"| Util + Parent -.->|"version management"| WebStarter + Parent -.->|"version management"| Thymeleaf + Parent -.->|"version management"| Jpa + Parent -.->|"version management"| Validation + Parent -.->|"version management"| Json + Parent -.->|"version management"| Devtools +
+

Dependency Summary

+
+ + + + + + +
CategoryCountKey LibrariesNotes
Web Frameworks2spring-boot-starter-web, spring-boot-starter-thymeleafServer-rendered MVC application
Database / ORM2spring-boot-starter-data-jpa, ojdbc8JPA/Hibernate with Oracle runtime driver
Security1spring-boot-starter-validationBean validation for upload constraints
Utilities3commons-io, spring-boot-starter-json, spring-boot-devtoolsJSON support, file IO helper, local dev hot reload
+

Version & Compatibility Risks

+

The project targets Java 8 and Spring Boot 2.7.x, both of which are older baselines for modernization. Oracle-specific native SQL in repositories and reliance on ojdbc8 can increase migration effort if moving to another database engine or newer framework stack.

+

Notable Observations

+
    +
  • Dependency versions are mostly managed by the Spring Boot parent BOM, reducing manual version drift risk.
  • +
  • The runtime DB dependency is Oracle-specific, and several repository queries use Oracle syntax (ROWNUM, NVL, TO_CHAR).
  • +
  • No dedicated observability or messaging libraries are declared; the system is a synchronous, single-service web app.
  • +
+

Test Dependencies

+
+ + + + +
FrameworkVersionNotes
spring-boot-starter-testManaged by Spring Boot 2.7.18Includes JUnit 5 and Spring test support
h2Managed by Spring Boot 2.7.18In-memory database used by test profile
+

Total test-scope dependencies: 2

+

The test stack is minimal but sufficient for context-load and repository-backed integration testing with an embedded DB.

+
+
+

Data Architecture & Persistence Layer

+

The data layer centers on a single relational model for photo metadata and binary image content using JPA/Hibernate. Runtime persistence uses Oracle, while tests use an in-memory H2 profile.

+

Database Configuration

+
+ + + + + +
Service/ModuleDB TypeProfileDriverConnectionMigration Tool
photo-albumOracledefaultOracle JDBCOracle service host and port in datasource URLNone detected
photo-albumOracledockerOracle JDBCContainerized Oracle endpoint in datasource URLNone detected
photo-album (tests)H2 in-memorytestH2 DriverIn-memory JDBC URLNone detected
+

Data Ownership per Service

+
+ + + +
ServiceTables OwnedORM FrameworkCachingNotes
photo-albumPHOTOSSpring Data JPA / HibernateNone detectedStores both metadata and image BLOB in one table
+

Entity Model

+
+erDiagram + PHOTO { + string id PK + string originalFileName + bytes photoData + string storedFileName + string filePath + long fileSize + string mimeType + datetime uploadedAt + int width + int height + } +
+

Key Repository Methods

+
+ + + + + + + + +
ServiceRepositoryNotable MethodsPurpose
photo-albumPhotoRepository (src/main/java/com/photoalbum/repository/PhotoRepository.java)findAllOrderByUploadedAtDesc()Returns gallery list newest first
photo-albumPhotoRepositoryfindPhotosUploadedBefore(LocalDateTime)Fetches older photos for previous navigation
photo-albumPhotoRepositoryfindPhotosUploadedAfter(LocalDateTime)Fetches newer photos for next navigation
photo-albumPhotoRepositoryfindPhotosByUploadMonth(String,String)Oracle-specific month filtering
photo-albumPhotoRepositoryfindPhotosWithPagination(int,int)Oracle ROWNUM pagination window
photo-albumPhotoRepositoryfindPhotosWithStatistics()Uses analytic functions for ranking and running totals
+

Caching Strategy

+

No explicit cache provider or Spring cache annotations were found. Reads and writes are executed directly through repository/database access within transactional service methods.

+

Data Ownership Boundaries

+

The application uses a shared single-database and single-service topology: one service both owns and accesses all persisted photo data. There is no cross-service data access pattern, CQRS split, or inter-service aggregation at the data layer.

+

Data Classification & Sensitivity

+
+ + + + +
EntitySensitive FieldsClassification (PII/PHI/PCI/None)Controls in Place
PhotooriginalFileName (may contain user-identifying text), photoData (image content may include personal data)PII (potential)No explicit encryption-at-rest, masking, or field-level access control configured in code
PhotoNo payment or medical attributes detectedNone for PCI/PHIN/A
+
+ + + +
diff --git a/.github/modernize/assessment/reports/report-20260521063406/report.json b/.github/modernize/assessment/reports/report-20260521063406/report.json new file mode 100644 index 000000000..dfee7e5f0 --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260521063406/report.json @@ -0,0 +1,1021 @@ +{ + "version": "1.0.0", + "producer": "Java AppCAT CLI", + "metadata": { + "analysisStartTime": "2026-05-21T06:34:06.574215787Z", + "analysisEndTime": "2026-05-21T06:34:46.406537424Z", + "status": "Complete", + "privacyMode": "Protected", + "privacyModeHelpUrl": "https://aka.ms/appcat-privacy-mode", + "targetIds": [ + "azure-container-apps", + "azure-aks", + "azure-appservice" + ], + "targetDisplayNames": [ + "Azure Container Apps", + "Azure Kubernetes Service", + "Azure App Service" + ], + "capabilities": [], + "os": [] + }, + "summary": { + "totalProjects": 1, + "totalIssues": 9, + "totalIncidents": 27, + "totalEffort": 172, + "charts": { + "severity": { + "mandatory": 11, + "optional": 2, + "potential": 14, + "information": 0 + }, + "category": { + "database-migration": 6, + "framework-upgrade": 10, + "jakarta-migration": 1, + "java-version-upgrade": 3, + "local-credential": 3, + "spring-migration": 4 + } + } + }, + "projects": [ + { + "path": ".", + "issues": 9, + "storyPoints": 172, + "properties": { + "appName": "photo-album", + "jdkVersion": "1.8", + "frameworks": [ + "Spring Boot", + "Spring" + ], + "languages": [ + "Java", + "Python" + ], + "tools": [ + "Maven" + ] + }, + "incidents": [ + { + "ruleId": "spring-boot-to-azure-restricted-config-01000", + "incidentId": "5339c29e-1288-460c-ad1b-f5a7c3a92c86", + "location": "src/main/resources/application-docker.properties", + "locationKind": "File", + "line": 24, + "column": 0, + "targets": { + "azure-container-apps": { + "effort": 2, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-restricted-config-01000", + "incidentId": "8b7da11e-cadc-4600-a97c-55bb9144c563", + "location": "src/main/resources/application.properties", + "locationKind": "File", + "line": 2, + "column": 0, + "targets": { + "azure-container-apps": { + "effort": 2, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "bf2a6c87-fc6e-4505-bfbd-522dacb383f4", + "location": "pom.xml", + "locationKind": "File", + "line": 34, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "b3f5a575-5060-40fd-9316-9cd5a4d98504", + "location": "pom.xml", + "locationKind": "File", + "line": 72, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "3e9b7c8f-ecf1-477f-bfb2-a947cc4a2ff1", + "location": "pom.xml", + "locationKind": "File", + "line": 78, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "42086582-92b4-47b8-9906-642c0b38052d", + "location": "pom.xml", + "locationKind": "File", + "line": 59, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "f10dd654-1ac2-446c-b754-60ada9c8b2a7", + "location": "pom.xml", + "locationKind": "File", + "line": 46, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "e07aaf50-b890-4814-b838-78dc28fa869c", + "location": "pom.xml", + "locationKind": "File", + "line": 92, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-spring-boot-version-01000", + "incidentId": "66e37a78-4d70-4c60-9913-ad0d33efa71e", + "location": "pom.xml", + "locationKind": "File", + "line": 40, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "0af2c545-7169-4d8c-ac88-6b7c56d97a9f", + "location": "pom.xml", + "locationKind": "File", + "line": 52, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "9defd73b-7532-425e-be2e-c9b911f0c48b", + "location": "src/main/resources/application.properties", + "locationKind": "File", + "line": 10, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "b4efee14-2634-4317-8fc3-88a95dad9caf", + "location": "docker-compose.yml", + "locationKind": "File", + "line": 32, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "5ab2deac-c0fe-4db2-a45a-784c3f00c44f", + "location": "src/main/resources/application-docker.properties", + "locationKind": "File", + "line": 2, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "69979f45-7b26-40ef-a932-e48bea1040ea", + "location": "src/main/resources/application-docker.properties", + "locationKind": "File", + "line": 5, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-database-microsoft-oracle-07000", + "incidentId": "470012ec-79b8-4428-96d6-e374554c1bba", + "location": "src/main/resources/application.properties", + "locationKind": "File", + "line": 13, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "potential" + }, + "azure-appservice": { + "effort": 8, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 8, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-framework-version-01000", + "incidentId": "e417fa8e-fdd0-4bdf-8d1b-e8d706717031", + "location": "pom.xml", + "locationKind": "File", + "line": 46, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-framework-version-01000", + "incidentId": "39ec6c04-c8ac-46ed-9fcb-2317df2b6562", + "location": "pom.xml", + "locationKind": "File", + "line": 78, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-framework-version-01000", + "incidentId": "ef63c09f-7fc8-4270-a52d-371c3c2ecd0d", + "location": "pom.xml", + "locationKind": "File", + "line": 34, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-password-01000", + "incidentId": "5aa700fc-e9b3-4109-a641-d12c6cf3b7be", + "location": "src/test/resources/application-test.properties", + "locationKind": "File", + "line": 5, + "column": 0, + "targets": { + "azure-aks": { + "effort": 3, + "severity": "potential" + }, + "azure-appservice": { + "effort": 3, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 3, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-password-01000", + "incidentId": "c7f9de9d-2dcf-4108-b3a8-756820aa7826", + "location": "src/main/resources/application-docker.properties", + "locationKind": "File", + "line": 4, + "column": 0, + "targets": { + "azure-aks": { + "effort": 3, + "severity": "potential" + }, + "azure-appservice": { + "effort": 3, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 3, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-password-01000", + "incidentId": "b67e0c9f-86a8-4107-a7bc-152799fafc29", + "location": "src/main/resources/application.properties", + "locationKind": "File", + "line": 12, + "column": 0, + "targets": { + "azure-aks": { + "effort": 3, + "severity": "potential" + }, + "azure-appservice": { + "effort": 3, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 3, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-java-version-01000", + "incidentId": "79dc55da-34a7-408d-96a6-7d3954588176", + "location": "pom.xml", + "locationKind": "File", + "line": 24, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "mandatory" + }, + "azure-appservice": { + "effort": 8, + "severity": "mandatory" + }, + "azure-container-apps": { + "effort": 8, + "severity": "mandatory" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-java-version-02000", + "incidentId": "1b38e54b-939d-4f8b-a761-9e770f77d89b", + "location": "pom.xml", + "locationKind": "File", + "line": 25, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "optional" + }, + "azure-appservice": { + "effort": 8, + "severity": "optional" + }, + "azure-container-apps": { + "effort": 8, + "severity": "optional" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "azure-java-version-02000", + "incidentId": "5d28c961-cc46-40fd-b389-3c35f16f1f8e", + "location": "pom.xml", + "locationKind": "File", + "line": 26, + "column": 0, + "targets": { + "azure-aks": { + "effort": 8, + "severity": "optional" + }, + "azure-appservice": { + "effort": 8, + "severity": "optional" + }, + "azure-container-apps": { + "effort": 8, + "severity": "optional" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-port-01000", + "incidentId": "e0cc4f59-64a6-45a9-998f-2fea624ebfa2", + "location": "src/main/resources/application-docker.properties", + "locationKind": "File", + "line": 24, + "column": 0, + "targets": { + "azure-aks": { + "effort": 1, + "severity": "potential" + }, + "azure-appservice": { + "effort": 1, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 1, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "spring-boot-to-azure-port-01000", + "incidentId": "d5504021-a9cc-4b36-90e9-c1d00b82a64d", + "location": "src/main/resources/application.properties", + "locationKind": "File", + "line": 2, + "column": 0, + "targets": { + "azure-aks": { + "effort": 1, + "severity": "potential" + }, + "azure-appservice": { + "effort": 1, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 1, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=azure/springboot" + ] + }, + { + "ruleId": "jakarta-database-00002", + "incidentId": "fa3b84a2-0e8d-4249-891d-7449cba855ab", + "location": "pom.xml", + "locationKind": "File", + "line": 46, + "column": 0, + "targets": { + "azure-aks": { + "effort": 5, + "severity": "potential" + }, + "azure-appservice": { + "effort": 5, + "severity": "potential" + }, + "azure-container-apps": { + "effort": 5, + "severity": "potential" + } + }, + "labels": [ + "type=violation", + "ruleset=cloud-readiness" + ] + } + ] + } + ], + "rules": { + "azure-database-microsoft-oracle-07000": { + "id": "azure-database-microsoft-oracle-07000", + "description": "Oracle database found. To migrate a Java application that uses an Oracle database to Azure, you can follow these recommendations:\n\n * **Migrate to Azure Database for PostgreSQL**: Azure recommends migrating Oracle databases to Azure Database for PostgreSQL Flexible Server as it provides better cost-effectiveness and performance. Create a managed PostgreSQL Flexible Server database in Azure and choose the appropriate pricing tier based on your application's requirements.\n\n * **Use migration tools**: Utilize the Azure Database Migration Service (DMS) or third-party tools to migrate your Oracle database schema and data to PostgreSQL. Consider using ora2pg or similar tools to convert Oracle-specific SQL to PostgreSQL-compatible SQL.\n\n * **Update database drivers and connection strings**: Replace Oracle JDBC drivers with PostgreSQL drivers in your Java application. Update connection strings from Oracle format (jdbc:oracle:thin:) to PostgreSQL format (jdbc:postgresql:).\n\n * **Review and convert Oracle-specific code**: Identify and convert Oracle-specific SQL functions, stored procedures, and PL/SQL code to PostgreSQL equivalents. Pay attention to data types, syntax differences, and built-in functions.\n\n * Enable **monitoring and diagnostics**: Utilize Azure Monitor to gain insights into the performance and health of your Java application and the underlying PostgreSQL database. Set up metrics, alerts, and log analytics to proactively identify and resolve issues.\n\n * Implement **security** measures: Apply security best practices to protect your Java application and the PostgreSQL database. This includes implementing authentication and authorization mechanisms with passwordless connections and leveraging Microsoft Defender for Cloud for threat detection and vulnerability assessments.\n\n * **Backup** your data: Azure Database for PostgreSQL provides automated backups by default. You can configure the retention period for backups based on your requirements. You can also enable geo-redundant backups, if needed, to enhance data durability and availability.", + "title": "Oracle database found", + "severity": "potential", + "effort": 8, + "links": [ + { + "url": "https://learn.microsoft.com/azure/postgresql", + "title": "Azure Database for PostgreSQL documentation" + }, + { + "url": "https://learn.microsoft.com/azure/postgresql/migrate/how-to-migrate-oracle-ora2pg", + "title": "Oracle to PostgreSQL migration guide" + }, + { + "url": "https://learn.microsoft.com/azure/dms", + "title": "Azure Database Migration Service documentation" + }, + { + "url": "https://learn.microsoft.com/azure/azure-monitor", + "title": "Azure Monitor documentation" + }, + { + "url": "https://learn.microsoft.com/azure/defender-for-cloud", + "title": "Microsoft Defender for Cloud" + } + ], + "labels": [ + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "source", + "domain=cloud-readiness", + "category=database-migration", + "database", + "oracle", + "os=windows", + "os=linux" + ] + }, + "azure-java-version-01000": { + "id": "azure-java-version-01000", + "description": "The application is using a Java version that has reached the end of support. It is strongly recommended to plan and execute a migration strategy to upgrade your application to a supported Java version.\nSupported Java versions receive long-term support (LTS) from the Java community, including bug fixes and updates. Migrating to a supported version provides you with a stable and well-maintained platform for your application.", + "title": "Java Version Has Reached the End of Support", + "severity": "mandatory", + "effort": 8, + "labels": [ + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "source", + "domain=java-upgrade", + "category=java-version-upgrade", + "version", + "os=windows", + "os=linux" + ] + }, + "azure-java-version-02000": { + "id": "azure-java-version-02000", + "description": "The application is not using the latest LTS Java version. It is recommended to consider upgrading to the latest LTS version to take advantage of the newest language features, performance improvements, and extended support timelines.\nUpgrading to the latest LTS version ensures your application benefits from the most recent security enhancements and a longer support lifecycle.", + "title": "Java Version is not the latest LTS", + "severity": "optional", + "effort": 8, + "labels": [ + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "source", + "domain=java-upgrade", + "category=java-version-upgrade", + "version", + "os=windows", + "os=linux" + ] + }, + "azure-password-01000": { + "id": "azure-password-01000", + "description": "Using clear passwords in property files is a security risk, as they can be easily compromised if the files are accessed by unauthorized individuals. To enhance the security of your application, it is recommended to employ secure credential management practices.\n\n * **Azure Key Vault**: Utilize Azure Key Vault to securely store and manage your application's passwords and other sensitive credentials. Azure Key Vault provides a centralized and highly secure location for storing secrets, keys, and certificates.\n\n * **Passwordless connections**: You can provide an additional layer of security and convenience for accessing resources in Azure by eliminating the need for passwords. This way you can reduce the risk of password-related vulnerabilities, such as weak passwords or password theft.", + "title": "Password found in configuration file", + "severity": "potential", + "effort": 3, + "links": [ + { + "url": "https://learn.microsoft.com/azure/key-vault", + "title": "Azure Key Vault documentation" + }, + { + "url": "https://learn.microsoft.com/azure/developer/intro/passwordless-overview", + "title": "Passwordless connections for Azure services" + }, + { + "url": "https://learn.microsoft.com/azure/developer/java/migration/migrate-spring-boot-to-azure-container-apps#inventory-configuration-sources-and-secrets", + "title": "Password found in configuration file" + }, + { + "url": "https://docs.microsoft.com/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-key-vault", + "title": "Read a secret from Azure Key Vault in a Spring Boot application" + }, + { + "url": "https://search.maven.org/artifact/com.azure.spring/azure-spring-boot-starter-keyvault-secrets", + "title": "Azure Spring Boot Starter for Azure Key Vault Secrets" + } + ], + "labels": [ + "source", + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "domain=cloud-readiness", + "category=local-credential", + "password", + "security", + "os=windows", + "os=linux" + ] + }, + "jakarta-database-00002": { + "id": "jakarta-database-00002", + "description": "The application depends on **Jakarta Persistence (JPA)** APIs (`jakarta.persistence.*` or legacy `javax.persistence.*`), which are used for object-relational mapping (ORM) and database interaction in Jakarta EE or Java EE applications.\n\nWhen migrating to Azure:\n- Ensure that the database connection, JPA provider (e.g., Hibernate, EclipseLink), and dialect are compatible with your target Azure database service.\n- Recommended database services include **Azure Database for PostgreSQL**, **Azure Database for MySQL**, or **Azure SQL Database**.\n- For containerized deployments, these JPA-based applications can run on **Azure Kubernetes Service (AKS)** or **Azure App Service for Linux/Windows**.\n- If using **Spring Data JPA**, verify that connection pool settings and environment variables are properly configured for the cloud environment.\n- Consider leveraging **Azure Key Vault** for secure storage of database credentials and connection strings.", + "title": "Detects usage of Jakarta Persistence (JPA) APIs", + "severity": "potential", + "effort": 5, + "links": [ + { + "url": "https://jakarta.ee/specifications/persistence/", + "title": "Jakarta Persistence Specification" + }, + { + "url": "https://learn.microsoft.com/en-us/azure/architecture/guide/technology-choices/data-stores-getting-started#common-database-scenarios", + "title": "Prepare to choose a data store in Azure" + } + ], + "labels": [ + "source=java", + "source=java-ee", + "target=azure-aks", + "target=azure-container-apps", + "target=azure-appservice", + "domain=cloud-readiness", + "category=jakarta-migration", + "os=windows", + "os=linux" + ] + }, + "spring-boot-to-azure-port-01000": { + "id": "spring-boot-to-azure-port-01000", + "description": "The application is setting the server port. To migrate a Java application that sets the server port to Azure Container Apps:\n\n * **Azure Container Apps allows you to expose port according to your Azure Container Apps resource configuration. For instance, a Spring Boot application listens to port of 8080 by default, but it can be set with server.port or environment variable SERVER_PORT as you need.", + "title": "Server port configuration found", + "severity": "potential", + "effort": 1, + "links": [ + { + "url": "https://learn.microsoft.com/azure/developer/java/migration/migrate-spring-boot-to-azure-container-apps#identify-any-clients-relying-on-a-non-standard-port", + "title": "Identify any clients relying on a non-standard port" + } + ], + "labels": [ + "source=springboot", + "target=azure-aks", + "target=azure-appservice", + "target=azure-container-apps", + "domain=cloud-readiness", + "category=spring-migration", + "port", + "server port", + "os=windows", + "os=linux" + ] + }, + "spring-boot-to-azure-restricted-config-01000": { + "id": "spring-boot-to-azure-restricted-config-01000", + "description": "The application uses restricted configurations for Azure Container Apps.\n These properties can be automatically injected into your application environment by Azure Container Apps to access managed Config Server and managed Eureka Server.\n Please remove them from your application, including configuration files, config server files, command line parameters, Java system attributes, and environment variables.\n\n If configured in **configuration files**: they will be ignored and overrided by Azure Container Apps.\n \n If configured in **Config Server files**, **command line parameters**, **Java system attribute**, **environment variable**: they need to be removed or you might experience conflicts and unexpected behavior.", + "title": "Restricted configurations found", + "severity": "potential", + "effort": 2, + "links": [ + { + "url": "https://learn.microsoft.com/azure/developer/java/migration/migrate-spring-cloud-to-azure-container-apps#remove-restricted-configurations", + "title": "Migrate Spring Boot applications to Azure Container Apps - Remove restricted configurations" + }, + { + "url": "https://learn.microsoft.com/azure/container-apps/java-config-server?tabs=azure-cli", + "title": "Connect to a managed Config Server for Spring in Azure Container Apps" + }, + { + "url": "https://learn.microsoft.com/azure/container-apps/java-eureka-server?tabs=azure-cli", + "title": "Connect to a managed Eureka Server for Spring in Azure Container Apps" + } + ], + "labels": [ + "target=azure-container-apps", + "source=springboot", + "domain=cloud-readiness", + "category=spring-migration", + "os=windows", + "os=linux" + ] + }, + "spring-boot-to-azure-spring-boot-version-01000": { + "id": "spring-boot-to-azure-spring-boot-version-01000", + "description": "The application is using a Spring Boot version that has reached its End of OSS Support.\nWith the officially supported new versions from Spring, you can get the best experience. Here are some steps you can take to update your application to the latest version of Spring Boot:\n\n* Choose a **supported Spring Boot version**: Check out Spring Boot Support Versions and determine the most suitable supported Spring Boot version.\n\n* **Update Spring Boot version**: Update the Spring Boot version of your application. There are automated tools like Rewrite to help you with the migration.\n\n* **Address code compatibility**: Review your application's codebase for any potential compatibility issues with the target Spring Boot version. Update deprecated APIs or features, address any language or library changes, and ensure that your code follows best practices and standards.\n\n* **Test thoroughly**: Execute a comprehensive testing process to verify the compatibility and functionality of your application with the new Spring Boot version. Perform unit tests, integration tests, and system tests to validate that all components and dependencies work as expected.", + "title": "Spring Boot Version Has Reached the End of OSS Support", + "severity": "mandatory", + "effort": 8, + "links": [ + { + "url": "https://learn.microsoft.com/azure/developer/java/migration/migrate-spring-boot-to-azure-container-apps", + "title": "Migrate Spring Boot applications to Azure Container Apps" + }, + { + "url": "https://learn.microsoft.com/azure/container-apps/java-microservice-get-started?tabs=azure-cli", + "title": "Launch your first Java microservice application with managed Java components in Azure Container Apps" + }, + { + "url": "https://spring.io/projects/spring-boot/#support", + "title": "Spring Boot Supported Versions" + }, + { + "url": "https://github.com/spring-projects/spring-boot/wiki/Supported-Versions", + "title": "Spring Boot Support Policy" + } + ], + "labels": [ + "source=springboot", + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "domain=java-upgrade", + "category=framework-upgrade", + "version", + "os=windows", + "os=linux" + ] + }, + "spring-framework-version-01000": { + "id": "spring-framework-version-01000", + "description": "Your application is using a Spring Framework version that has reached its End of OSS Support.\nUpgrading to a supported version ensures better performance, security, and compatibility with modern tools.\n 1. Pick a Supported Version: Review the Spring Framework support policy and choose an actively supported version.\n 2. Update Your Project: Change the Spring Framework version in your pom.xml or build.gradle.\n 3. Fix Compatibility Issues: Update deprecated code, replace removed features, and ensure dependencies are compatible with the new Spring Framework version.\n 4. Thoroughly Test: Run unit, integration, and end-to-end tests to make sure everything still works after the upgrade.", + "title": "Spring Framework Version Has Reached the End of OSS Support", + "severity": "mandatory", + "effort": 8, + "links": [ + { + "url": "https://spring.io/projects/spring-framework#support", + "title": "Spring Framework Supported Versions" + }, + { + "url": "https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions", + "title": "Spring Framework Support Policy" + } + ], + "labels": [ + "source=spring", + "target=azure-appservice", + "target=azure-aks", + "target=azure-container-apps", + "domain=java-upgrade", + "category=framework-upgrade", + "version", + "os=windows", + "os=linux" + ] + } + } +} \ No newline at end of file diff --git a/.github/modernize/assessment/reports/report-20260521063406/report.md b/.github/modernize/assessment/reports/report-20260521063406/report.md new file mode 100644 index 000000000..60b0aa3bf --- /dev/null +++ b/.github/modernize/assessment/reports/report-20260521063406/report.md @@ -0,0 +1,137 @@ +# photo-album + +## Summary + +| Metric | Value | +|--------|-------| +| Total Issues | 9 | +| Mandatory Blockers | 3 | +| Potential Issues | 5 | + +## Application Information + +| Property | Value | +|----------|-------| +| Language | Java, Python | +| Frameworks | Spring Boot, Spring | +| Build tools | Maven | +| JDK version | 1.8 | + +## Cloud Readiness Issues + +| Issue Name | Criticality | Story Points | Occurrences | +|------------|-------------|--------------|-------------| +| Oracle database found | Potential | 8 | [6](#Oracle_database_found) | +| Password found in configuration file | Potential | 3 | [3](#Password_found_in_configuration_file) | +| Restricted configurations found | Potential | 2 | [2](#Restricted_configurations_found) | +| Server port configuration found | Potential | 1 | [2](#Server_port_configuration_found) | +| Detects usage of Jakarta Persistence (JPA) APIs | Potential | 5 | [1](#Detects_usage_of_Jakarta_Persistence_JPA_APIs) | + +### Issue Details + +
+Oracle database found — affected files + +- `pom.xml (line 52)` +- `src/main/resources/application.properties (line 10)` +- `docker-compose.yml (line 32)` +- `src/main/resources/application-docker.properties (line 2)` +- `src/main/resources/application-docker.properties (line 5)` +- `src/main/resources/application.properties (line 13)` + +
+ +
+Password found in configuration file — affected files + +- `src/test/resources/application-test.properties (line 5)` +- `src/main/resources/application-docker.properties (line 4)` +- `src/main/resources/application.properties (line 12)` + +
+ +
+Restricted configurations found — affected files + +- `src/main/resources/application-docker.properties (line 24)` +- `src/main/resources/application.properties (line 2)` + +
+ +
+Server port configuration found — affected files + +- `src/main/resources/application-docker.properties (line 24)` +- `src/main/resources/application.properties (line 2)` + +
+ +
+Detects usage of Jakarta Persistence (JPA) APIs — affected files + +- `pom.xml (line 46)` + +
+ +## Upgrade Issues + +| Issue Name | Criticality | Story Points | Occurrences | +|------------|-------------|--------------|-------------| +| Spring Boot Version Has Reached the End of OSS Support | Mandatory | 8 | [7](#Spring_Boot_Version_Has_Reached_the_End_of_OSS_Support) | +| Spring Framework Version Has Reached the End of OSS Support | Mandatory | 8 | [3](#Spring_Framework_Version_Has_Reached_the_End_of_OSS_Support) | +| Java Version Has Reached the End of Support | Mandatory | 8 | [1](#Java_Version_Has_Reached_the_End_of_Support) | +| Java Version is not the latest LTS | Optional | 8 | [2](#Java_Version_is_not_the_latest_LTS) | + +### Issue Details + +
+Spring Boot Version Has Reached the End of OSS Support — affected files + +- `pom.xml (line 34)` +- `pom.xml (line 72)` +- `pom.xml (line 78)` +- `pom.xml (line 59)` +- `pom.xml (line 46)` +- `pom.xml (line 92)` +- `pom.xml (line 40)` + +
+ +
+Spring Framework Version Has Reached the End of OSS Support — affected files + +- `pom.xml (line 46)` +- `pom.xml (line 78)` +- `pom.xml (line 34)` + +
+ +
+Java Version Has Reached the End of Support — affected files + +- `pom.xml (line 24)` + +
+ +
+Java Version is not the latest LTS — affected files + +- `pom.xml (line 25)` +- `pom.xml (line 26)` + +
+ +--- + +## Codebase Insights + +> **Note:** These documents are generated by AI and may contain inaccuracies or incomplete information. Please review carefully. + +1. **[Architecture Diagram](facts/architecture-diagram.md)** — Understand the big picture: system layers and component relationships +2. **[Dependency Map](facts/dependency-map.md)** — Know what the project depends on and where the risks are +3. **[API & Service Contracts](facts/api-service-contracts.md)** — See how services communicate and what contracts they expose +4. **[Data Architecture](facts/data-architecture.md)** — Explore data models, storage, and data flow patterns +5. **[Configuration Inventory](facts/configuration-inventory.md)** — Review how the application is configured across environments +6. **[Business Workflows](facts/business-workflows.md)** — Trace end-to-end business processes and domain logic + +[Share feedback](https://aka.ms/ghcp-appmod/feedback)