# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This repository contains a Helm chart for deploying the Property Settings Service V2 on Kubernetes. The chart name is `property-settings-svc-v2-chart` and follows standard Helm chart structure and conventions. **Application Details:** - Java/Tomcat-based service - Docker Image: `localhost:5001/prj-onlinesales-prod-01/os-docker-images/onlinesales/prod/services/java/propertysettingssvcv2:1752740345878` - Service Port: 8080 - Context Path: `/propertySettingsSvcV2` - Database: MySQL 5.7 (bundled or external) - Source Code: `/Volumes/Os/onlinesales/infrastructure/apps/propertySettingsSvcV2/release_kubernetes_2.0` ## Helm Chart Commands ### Update dependencies (required before first install) ```bash cd ./property-settings-svc-v2-chart helm dependency update cd .. ``` ### Install the chart ```bash helm install ./property-settings-svc-v2-chart ``` ### Install with custom values ```bash helm install ./property-settings-svc-v2-chart -f custom-values.yaml ``` ### Upgrade an existing release ```bash helm upgrade ./property-settings-svc-v2-chart ``` ### Dry run to preview rendered templates ```bash helm install ./property-settings-svc-v2-chart --dry-run --debug ``` ### Lint the chart ```bash helm lint ./property-settings-svc-v2-chart ``` ### Package the chart ```bash helm package ./property-settings-svc-v2-chart ``` ### Uninstall a release ```bash helm uninstall ``` ### Template rendering (output YAML without deploying) ```bash helm template ./property-settings-svc-v2-chart ``` ## Architecture ### Chart Structure ``` property-settings-svc-v2-chart/ ├── Chart.yaml # Chart metadata with MySQL dependency ├── values.yaml # Default configuration values ├── sql/ # SQL migration scripts (5 files) │ ├── 000_create_property_settings_db.sql # Creates database │ ├── 001_properties_table.sql # Creates tables & triggers │ ├── 002_populate_properties_table.sql # V1→V2 migration (unused) │ ├── 003_alter_column_property_value.sql # Alters column type │ └── 004_property_settings_db_v2.sql # Complete dump with data (79KB) ├── charts/ # Dependent charts (MySQL) │ └── mysql-*.tgz # WSO2 MySQL chart └── templates/ ├── _helpers.tpl # Template helpers and named templates ├── _db-helpers.tpl # Database connection helpers ├── deployment.yaml # Main application deployment ├── service.yaml # Kubernetes service (ClusterIP on port 8080) ├── serviceaccount.yaml # Service account configuration ├── configmap.yaml # Application configuration files ├── configmap-sql-migrations.yaml # ConfigMap with SQL files (auto-loaded) ├── job-dbinit.yaml # Database initialization Job (Helm hook) ├── secret.yaml # Database configuration (Hibernate with dynamic DB config) ├── ingress.yaml # Optional Ingress resource ├── httproute.yaml # Optional Gateway API HTTPRoute ├── hpa.yaml # Horizontal Pod Autoscaler (enabled by default) └── tests/ └── test-connection.yaml ``` ### Key Template Helpers The `_helpers.tpl` file defines reusable template functions: - `property-settings-svc-v2-chart.name` - Chart name with override support - `property-settings-svc-v2-chart.fullname` - Fully qualified app name (max 63 chars) - `property-settings-svc-v2-chart.chart` - Chart name and version label - `property-settings-svc-v2-chart.labels` - Common labels for all resources - `property-settings-svc-v2-chart.selectorLabels` - Labels for selecting pods - `property-settings-svc-v2-chart.serviceAccountName` - Service account name resolution ### Routing Options The chart supports two routing mechanisms (both disabled by default): 1. **Traditional Ingress** (`ingress.enabled: false`) - Standard Kubernetes Ingress using networking.k8s.io/v1 2. **Gateway API HTTPRoute** (`httpRoute.enabled: false`) - Modern Gateway API routing with advanced traffic management ### Default Configuration - **Image**: `localhost:5001/prj-onlinesales-prod-01/os-docker-images/onlinesales/prod/services/java/propertysettingssvcv2:1752740345878` - **Service Type**: ClusterIP on port 8080 - **Replicas**: 3 (minimum when autoscaling is enabled) - **Probes**: HTTP health checks on `/propertySettingsSvcV2/properties` endpoint with specific query parameters - **Autoscaling**: Enabled by default (3-10 replicas, CPU target 200%, Memory target 80%) - **Resources**: CPU request 500m, Memory request 512Mi - **Configuration Volumes**: - ConfigMap mounted at `/etc/onlinesales/config/propertySettingsSvcV2` - Secret mounted at `/etc/onlinesales/db` ## Working with Templates When modifying templates, remember: - All resource names use the `property-settings-svc-v2-chart.fullname` helper - Labels should use the `property-settings-svc-v2-chart.labels` helper for consistency - Container port in deployment.yaml references `service.port` from values - The deployment uses conditional logic for autoscaling (`.Values.autoscaling.enabled`) - HTTPRoute template includes advanced features like filters and header manipulation ## MySQL Database Configuration The chart includes MySQL as an optional dependency using the WSO2 MySQL Helm chart (version 1.6.9). ### Bundled MySQL (Default) By default, the chart deploys MySQL alongside the application: - **Version**: MySQL 5.7.30 - **Database Name**: `property_settings_db_v2` - **Username**: `propertysettings` - **Password**: `changeme` (should be changed for production) - **Persistence**: 8Gi storage (configurable) - **Initialization**: Automatically creates database schema and tables To deploy with bundled MySQL: ```bash helm install property-settings-v2 ./property-settings-svc-v2-chart ``` ### External MySQL To use an external MySQL database, disable the bundled MySQL and configure connection details: ```yaml # values.yaml or custom-values.yaml mysql: enabled: false externalDatabase: host: "your-mysql-host.example.com" port: 3306 database: "property_settings_db_v2" username: "propertysettings" password: "your-secure-password" ``` Deploy with external MySQL: ```bash helm install property-settings-v2 ./property-settings-svc-v2-chart \ --set mysql.enabled=false \ --set externalDatabase.host=your-mysql-host.example.com \ --set externalDatabase.password=your-secure-password ``` **Important**: When using external MySQL, ensure the database schema is initialized manually using the SQL scripts from `sql/` directory. ### Database Schema and Initialization The chart uses a **Helm Job with ConfigMap approach** for database initialization (same pattern as hades-service): #### How It Works 1. **SQL Files in `sql/` Directory**: All SQL migration scripts are stored as separate files 2. **Auto-Loading via ConfigMap**: The `configmap-sql-migrations.yaml` template uses `.Files.Glob "sql/**.sql"` to automatically load all SQL files 3. **Execution via Helm Job**: The `job-dbinit.yaml` runs as a post-install/post-upgrade hook that: - Waits for MySQL to be ready - Executes SQL files in alphabetical order (000, 001, 002, etc.) - Provides detailed logging and error handling - Fails if any migration fails **Advantages of this approach:** - ✅ No need to embed SQL in values.yaml - ✅ SQL files remain separate and version-controlled - ✅ Automatic file discovery - just add/remove files in `sql/` directory - ✅ Clean execution logs with success/failure reporting - ✅ Runs automatically on install and upgrade #### Available SQL Files The `sql/` directory contains 5 files: 1. **000_create_property_settings_db.sql** - Creates the database 2. **001_properties_table.sql** - Creates properties table with triggers 3. **002_populate_properties_table.sql** - V1→V2 migration (commented out, not used) 4. **003_alter_column_property_value.sql** - Alters property_value column to TEXT 5. **004_property_settings_db_v2.sql** (79KB) - Complete database dump with staging data #### OPTION 1: Clean Installation (Default) For production deployments with an empty database: **Files to keep active:** - 000, 001, 003 (002 is commented out) **To configure:** ```bash # Rename or remove the complete dump file mv sql/004_property_settings_db_v2.sql sql/004_property_settings_db_v2.sql.bak ``` **Result:** - Empty `properties` table with proper schema - Triggers for automatic timestamp tracking - TEXT column type for property_value - Ready for production use #### OPTION 2: Complete Database Dump (With Seed Data) For development/testing with sample data from staging: **File to keep active:** - 004 only **To configure:** ```bash # Rename the incremental files and keep only the dump cd sql/ mv 000_create_property_settings_db.sql 000_create_property_settings_db.sql.bak mv 001_properties_table.sql 001_properties_table.sql.bak mv 002_populate_properties_table.sql 002_populate_properties_table.sql.bak mv 003_alter_column_property_value.sql 003_alter_column_property_value.sql.bak # Keep 004_property_settings_db_v2.sql active ``` **Result:** - Complete database with real staging data - 4 Agency records (TVING staging, TVING QA, etc.) - 24+ Client records with configurations - Moloco account details, payment modes - Schema_info table with migration tracking **⚠️ WARNING**: Do NOT use both options together. The dump file (004) drops and recreates tables, conflicting with incremental files (000-003). #### Schema Details **Table**: `properties` - **Primary Key**: (entity_type, entity_value, property_type) - **Columns**: entity_type (VARCHAR 200), entity_value (VARCHAR 200), property_type (VARCHAR 200), property_value (TEXT), is_active (BOOLEAN), creation_date (DATETIME), last_update (DATETIME), last_updated_by (VARCHAR 150) - **Triggers**: Automatic timestamp and user tracking on INSERT/UPDATE - **Character Set**: UTF-8 - **Engine**: InnoDB #### Controlling Database Initialization To disable automatic database initialization: ```yaml # values.yaml dbInit: enabled: false ``` This is useful when: - Using an external database with existing schema - Managing schema separately - Running in environments where Jobs/Hooks are restricted ### Hibernate Configuration The Hibernate configuration in `secret.yaml` is dynamically generated based on MySQL settings: - Uses `_db-helpers.tpl` to determine connection details - Automatically configures JDBC URL, username, and password - Supports both internal and external MySQL seamlessly ### Database Service Name Convention When using bundled MySQL, the service is named `-mysql`: - Example: With release name `prop`, MySQL service is `prop-mysql` - The database initialization Job and Hibernate config automatically use the correct service name - Connection string format: `jdbc:mysql://-mysql:3306/property_settings_db_v2` ## Configuration Management ### ConfigMap (configmap.yaml) The chart creates a ConfigMap containing application configuration files: - `propertySettingsService.cfg` - Main service configuration (prod/test environments) - `log.cfg` - Logging configuration - `prodRestAccessor.cfg` - Production REST accessor settings - `testRestAccessor.cfg` - Test REST accessor settings - `authConfig.cfg` - Authentication configuration - `statsLogging.cfg` - Statistics logging configuration **Important**: These files contain placeholder content and must be updated with actual configuration before deployment. ### Secret (secret.yaml) The chart creates a Secret for sensitive database configuration: - `propertySettingsV2.hbm.xml` - Hibernate mapping file for database access **Important**: This file contains placeholder XML and must be updated with actual database mapping before deployment. ### Health Check Configuration The service uses a comprehensive health check endpoint: ``` /propertySettingsSvcV2/properties?jsonQuery={encoded-json} ``` This endpoint validates: - Service availability - Database connectivity - Property retrieval functionality The query is URL-encoded and checks for BUSINESS_SEGMENT_SET properties for AGENCY entity type. ## Values Configuration Key values.yaml sections (already configured): - `image.repository` and `image.tag` - Set to Property Settings V2 image - `service.port` - Set to 8080 (Tomcat default) - `replicaCount` - Set to 3 replicas - `resources` - CPU: 500m, Memory: 512Mi - `autoscaling` - Enabled (3-10 replicas, CPU: 200%, Memory: 80%) - `livenessProbe` and `readinessProbe` - Configured for Property Settings endpoint Optional values to configure: - `ingress` or `httpRoute` - Enable one for external access - `nodeSelector`, `tolerations`, `affinity` - For pod scheduling preferences ## Deployment Workflow 1. **Update Chart Dependencies** (Required before first deployment): ```bash cd ./property-settings-svc-v2-chart helm dependency update cd .. ``` 2. **Update Configuration Files** (Required before first deployment): ```bash # Edit the ConfigMap template with actual configuration vim ./property-settings-svc-v2-chart/templates/configmap.yaml # Update MySQL credentials (if needed) vim ./property-settings-svc-v2-chart/values.yaml # Change mysql.mysqlRootPassword and mysql.mysqlPassword ``` 3. **Validate the Chart**: ```bash helm lint ./property-settings-svc-v2-chart helm template test ./property-settings-svc-v2-chart --debug ``` 4. **Deploy to Kubernetes** (with bundled MySQL): ```bash helm install property-settings-v2 ./property-settings-svc-v2-chart \ --set mysql.mysqlRootPassword=your-root-password \ --set mysql.mysqlPassword=your-user-password ``` 5. **Deploy to Kubernetes** (with external MySQL): ```bash helm install property-settings-v2 ./property-settings-svc-v2-chart \ --set mysql.enabled=false \ --set externalDatabase.host=your-mysql-host \ --set externalDatabase.password=your-password ``` 6. **Verify Deployment**: ```bash # Check all pods (application + MySQL if enabled) kubectl get pods -l app.kubernetes.io/instance=property-settings-v2 # Check application logs kubectl logs -l app.kubernetes.io/name=property-settings-svc-v2-chart # Check MySQL logs (if bundled) kubectl logs -l app.kubernetes.io/name=mysql # Verify database connection kubectl exec -it -- sh # Test connection to MySQL ``` ## Important Notes - The chart uses modern Kubernetes API versions (apps/v1, networking.k8s.io/v1) - Service account is created by default with API credentials auto-mounted - **MySQL dependency must be updated** - Run `helm dependency update` before first deployment - **Database passwords should be changed** - Default passwords are insecure and meant for development only - **Configuration files must be updated before deployment** - The ConfigMap contains placeholder content - The deployment automatically mounts configuration volumes - no need to modify deployment.yaml for config changes - The Hibernate configuration is dynamically generated based on MySQL settings (internal or external) - **Database initialization uses Helm Job** - SQL files are auto-loaded from `sql/` directory and executed via a post-install/post-upgrade hook - When enabling HTTPRoute, ensure Gateway API CRDs are installed in the cluster - The image registry (localhost:5001) suggests a local registry - ensure it's accessible from your cluster - For external MySQL, the database schema must be initialized manually using scripts in `sql/` directory ## MySQL Dependency Details **Chart**: WSO2 MySQL (version 1.6.9) **Repository**: https://helm.wso2.com **Condition**: `mysql.enabled` The MySQL chart is conditionally deployed based on the `mysql.enabled` value. When enabled, it creates: - MySQL StatefulSet - PersistentVolumeClaim for data storage - Service for database access - ConfigMap for initialization scripts