diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ae91dbe --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +# Multi-stage Dockerfile for Spring Boot Application +FROM maven:3.9-eclipse-temurin-17 AS build +WORKDIR /app + +# Copy dependency files first for better caching +COPY pom.xml . +RUN mvn dependency:go-offline -B + +# Copy source code and build +COPY src ./src +RUN mvn clean package -DskipTests + +# Runtime stage - lean JRE for Spring Boot executable JAR (~200MB vs ~500MB Tomcat) +FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu +WORKDIR /app + +# Create non-root user for security +RUN groupadd -g 1001 appuser && useradd -u 1001 -g appuser -s /bin/sh appuser && \ + chown -R appuser:appuser /app +USER appuser + +COPY --from=build /app/target/*.jar app.jar + +EXPOSE 8080 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=30s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1 + +CMD ["java", "-jar", "app.jar"] diff --git a/catalog-info.yaml b/catalog-info.yaml new file mode 100644 index 0000000..2f616ad --- /dev/null +++ b/catalog-info.yaml @@ -0,0 +1,59 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + annotations: + backstage.io/kubernetes-label-selector: app=jason-pet-1 + backstage.io/kubernetes-namespace: dev + backstage.io/techdocs-ref: dir:. + gitea.kyndemo.live/repo-slug: demo-platform/jason-pet-1 + grafana/alert-label-selector: app=jason-pet-1 + grafana/dashboard-selector: uid == 'app-jason-pet-1' + grafana/grafana-instance: default + humanitec.dev/orgId: skillful-wild-chicken-2617 + humanitec.dev/projectId: jason-pet-1 + prometheus.io/path: /actuator/prometheus + prometheus.io/port: '8080' + prometheus.io/scrape: 'true' + description: Modernized jason-pet-1 service + links: + - icon: web + title: Live Application + url: https://jason-pet-1.kyndemo.live + - icon: github + title: Source Repository + url: https://gitea.kyndemo.live/demo-platform/jason-pet-1 + - icon: dashboard + title: Humanitec Console + url: https://console.humanitec.dev/orgs/skillful-wild-chicken-2617/projects/jason-pet-1/environments/dev + - icon: code + title: CI/CD Pipelines + url: https://gitea.kyndemo.live/demo-platform/jason-pet-1/actions + - icon: dashboard + title: Grafana Dashboard + url: https://grafana.kyndemo.live/d/app-jason-pet-1 + name: jason-pet-1 + tags: + - java + - spring-boot + - maven + - golden-path + - humanitec-v2 + - platform-orchestrator + - score +spec: + lifecycle: production + owner: group:default/platform-engineering + system: jason-pet-1-system + type: website +--- +apiVersion: backstage.io/v1alpha1 +kind: System +metadata: + annotations: + humanitec.dev/orgId: skillful-wild-chicken-2617 + humanitec.dev/projectId: jason-pet-1 + description: System grouping for the jason-pet-1 application + name: jason-pet-1-system +spec: + domain: platform + owner: group:default/platform-engineering diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..fffc52c --- /dev/null +++ b/docs/api.md @@ -0,0 +1,25 @@ +# API Reference + +## Endpoints + +### Health Check + +``` +GET /health +``` + +**Response:** +```json +{"status": "UP", "service": "jason-pet-1"} +``` + +### Root + +``` +GET / +``` + +**Response:** +```json +{"service": "jason-pet-1", "description": "Modernized jason-pet-1 service", "version": "1.0.0"} +``` diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..24d4eb8 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,15 @@ +# Architecture + +## Service Design + +jason-pet-1 is a microservice following cloud-native patterns. + +## Technology Stack + +- **Runtime**: Java Spring Boot +- **Deployment**: Humanitec Platform Orchestrator +- **CI/CD**: Gitea Actions → ACR → Humanitec + +## Dependencies + +See `score.yaml` for external resource dependencies. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..51b4347 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,32 @@ +# jason-pet-1 + +Modernized jason-pet-1 service + +## Overview + +This service is built with **Java Spring Boot** and follows the Golden Path architecture patterns. + +### Key Features + +- 🚀 Production-ready configuration +- 📊 Prometheus metrics exposed +- 🏥 Health check endpoints +- 🔒 Security scanning in CI/CD +- 📦 Containerized deployment + +## Quick Start + +```bash +git clone https://gitea.kyndemo.live/kyndryl-demos/jason-pet-1.git +cd jason-pet-1 +``` + +## Monitoring + +- **Metrics**: Prometheus metrics at `/metrics` +- **Health**: `/health` +- **Grafana**: [View Dashboard](https://grafana.kyndemo.live/d/app-jason-pet-1) + +## Support + +Contact the Platform Engineering team. diff --git a/docs/migration-plan.md b/docs/migration-plan.md new file mode 100644 index 0000000..825472b --- /dev/null +++ b/docs/migration-plan.md @@ -0,0 +1,47 @@ +# Modernization Plan for jason-pet-1 + +## Application Type +Java Application + +## Selected Modernization Strategy +- **Migration Approach**: containerize-optimize +- **Target Platform**: kubernetes-humanitec +- **Observability**: ENABLED (Prometheus metrics, health checks, tracing) +- **Security Scanning**: ENABLED (Trivy vulnerability scanning) + +## Discovery Summary +### Discovery Report + +#### Application Overview +- **Location**: `/tmp/modernize_hd43jt5v` +- **Type**: Java-based application using Spring Boot framework. +- **Build Tools**: Maven and Gradle are both present, indicating flexibility in build management. + +#### Technology Stack +- **Framework**: Spring Boot +- **Primary Language**: Java +- **Database**: H2 (in-memory), MySQL, PostgreSQL +- **Frontend**: Thymeleaf templates, Bootstrap, Font Awesome + +#### Dependencies +The application uses the following ex... + +## Generated Artifacts +1. **Dockerfile**: Optimized with health checks and metrics endpoints +2. **score.yaml**: Platform-agnostic environment intent optimized for kubernetes-humanitec with Prometheus metrics resources +3. **CI Workflow**: Automated build/push to ACR with Trivy security scanning + +## Next Steps +1. Review and customize generated artifacts +2. Test container build and run +3. Deploy to development environment using score.yaml +4. Validate application functionality +5. Promote to staging/production via Humanitec + +## Migration Strategy Details + +### Containerize Optimize +Add cloud-native patterns: health checks, metrics, optimized base images. + +### Platform: kubernetes-humanitec +score.yaml is the single environment intent. Use Humanitec Platform Orchestrator for deployment. diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..733c304 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,13 @@ +site_name: jason-pet-1 +site_description: Modernized jason-pet-1 service + +nav: + - Home: index.md + - Architecture: architecture.md + - API Reference: api.md + +plugins: + - techdocs-core + +theme: + name: material diff --git a/openapi.yaml b/openapi.yaml new file mode 100644 index 0000000..1360964 --- /dev/null +++ b/openapi.yaml @@ -0,0 +1,188 @@ +openapi: 3.0.3 +info: + title: jason-pet-1 + description: Modernized jason-pet-1 service + version: 1.0.0 +servers: +- url: https://jason-pet-1.kyndemo.live + description: Production +- url: http://localhost:8080 + description: Local development +paths: + /health: + get: + summary: Health check + operationId: getHealth + tags: + - System + responses: + '200': + description: Healthy + /vets.html: + get: + summary: GET /vets.html + operationId: getVets.html + responses: + '200': + description: Success + '400': + description: Bad request + /owners/{ownerId}/owners/{ownerId}: + get: + summary: GET /owners/{ownerId}/owners/{ownerId} + operationId: getOwners_ownerId_owners_ownerId + responses: + '200': + description: Success + '400': + description: Bad request + parameters: + - name: ownerId + in: path + required: true + schema: + type: string + - name: ownerId + in: path + required: true + schema: + type: string + /owners/{ownerId}/pets/new: + get: + summary: GET /owners/{ownerId}/pets/new + operationId: getOwners_ownerId_pets_new + responses: + '200': + description: Success + '400': + description: Bad request + parameters: + - name: ownerId + in: path + required: true + schema: + type: string + /owners/{ownerId}/pets/{petId}/edit: + get: + summary: GET /owners/{ownerId}/pets/{petId}/edit + operationId: getOwners_ownerId_pets_petId_edit + responses: + '200': + description: Success + '400': + description: Bad request + parameters: + - name: ownerId + in: path + required: true + schema: + type: string + - name: petId + in: path + required: true + schema: + type: string + /owners/{ownerId}/pets/{petId}/visits/new: + get: + summary: GET /owners/{ownerId}/pets/{petId}/visits/new + operationId: getOwners_ownerId_pets_petId_visits_new + responses: + '200': + description: Success + '400': + description: Bad request + parameters: + - name: ownerId + in: path + required: true + schema: + type: string + - name: petId + in: path + required: true + schema: + type: string + /owners/new: + get: + summary: GET /owners/new + operationId: getOwners_new + responses: + '200': + description: Success + '400': + description: Bad request + /owners/find: + get: + summary: GET /owners/find + operationId: getOwners_find + responses: + '200': + description: Success + '400': + description: Bad request + /owners: + get: + summary: GET /owners + operationId: getOwners + responses: + '200': + description: Success + '400': + description: Bad request + /owners/{ownerId}/edit: + get: + summary: GET /owners/{ownerId}/edit + operationId: getOwners_ownerId_edit + responses: + '200': + description: Success + '400': + description: Bad request + parameters: + - name: ownerId + in: path + required: true + schema: + type: string + /owners/{ownerId}: + get: + summary: GET /owners/{ownerId} + operationId: getOwners_ownerId + responses: + '200': + description: Success + '400': + description: Bad request + parameters: + - name: ownerId + in: path + required: true + schema: + type: string + /: + get: + summary: GET / + operationId: getRoot + responses: + '200': + description: Success + '400': + description: Bad request + /oups: + get: + summary: GET /oups + operationId: getOups + responses: + '200': + description: Success + '400': + description: Bad request + /actuator/prometheus: + get: + summary: Prometheus metrics + operationId: getMetrics + tags: + - System + responses: + '200': + description: text/plain; Prometheus exposition format diff --git a/score.yaml b/score.yaml new file mode 100644 index 0000000..d3f0290 --- /dev/null +++ b/score.yaml @@ -0,0 +1,23 @@ +apiVersion: score.dev/v1b1 +containers: + jason-pet-1: + image: . +metadata: + annotations: + prometheus.io/path: /actuator/prometheus + prometheus.io/port: '8080' + prometheus.io/scrape: 'true' + labels: + app: jason-pet-1 + backstage.io/kubernetes-id: jason-pet-1 + name: jason-pet-1 +resources: + dns: + type: dns + env: + type: environment +service: + ports: + http: + port: 8080 + targetPort: 8080