Spring Profiles
Secure Link API uses Spring profiles to manage different environments:
Profile Purpose Database devLocal development MySQL prodProduction deployment MySQL testAutomated testing H2 (in-memory)
Activating a Profile
Maven
JAR Execution
Environment Variable
SPRING_PROFILES_ACTIVE = dev mvn spring-boot:run
Environment Variables
The application uses environment variables for sensitive configuration. These can be set in a .env file (loaded automatically) or as system environment variables.
Required Variables
Variable Description Example BASE_URLPublic URL for the API http://localhost:8080DB_HOSTMySQL host address localhostDB_PORTMySQL port 3307DB_NAMEDatabase name secure_linkDB_USERNAMEDatabase user adminDB_PASSWORDDatabase password secure_password
For production deployments, use DB_URL instead of individual host/port/name variables for better security and flexibility.
Example .env File
BASE_URL =http://localhost:8080
DB_HOST =localhost
DB_PORT =3307
DB_NAME =secure_link
DB_USERNAME =your_username
DB_PASSWORD =your_password
Application Properties
Core Configuration
The base configuration in application.properties:
# Application
spring.application.name =secure-link
server.port =8080
# Environment file import
spring.config.import =optional:file:.env[.properties]
# Base URL for link generation
app.base-url =${BASE_URL:http://localhost:8080}
# File storage location
app.storage.path =/tmp/uploads/
# Default link time-to-live (ISO-8601 Duration)
app.link.default-ttl =PT24H
# File upload limits
spring.servlet.multipart.max-file-size =50MB
spring.servlet.multipart.max-request-size =50MB
# CORS configuration
app.cors.allowed-origins =http://localhost:4200,http://127.0.0.1:4200
# Logging pattern (includes correlation ID)
logging.pattern.console =%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%X{correlationId}] %logger{36} - %msg%n
Dev Profile Configuration
Configuration specific to application-dev.properties:
application-dev.properties
# Database
spring.datasource.url =jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3307}/${DB_NAME:secure_link}
spring.datasource.username =${DB_USERNAME}
spring.datasource.password =${DB_PASSWORD}
spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver
# JPA
spring.jpa.hibernate.ddl-auto =validate
spring.jpa.show-sql =false
# Flyway migrations
spring.flyway.enabled =true
spring.flyway.locations =classpath:db/migration
spring.flyway.baseline-on-migrate =true
# Actuator endpoints
management.endpoints.web.exposure.include =health,prometheus
management.endpoint.health.show-details =always
management.health.defaults.enabled =true
# Logging
logging.level.root =INFO
logging.level.br.com.walyson.secure_link =INFO
Production Profile Configuration
Configuration for application-prod.properties:
application-prod.properties
# Database (use full URL for production)
spring.datasource.url =${DB_URL}
spring.datasource.username =${DB_USERNAME}
spring.datasource.password =${DB_PASSWORD}
spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver
# JPA
spring.jpa.hibernate.ddl-auto =validate
spring.jpa.show-sql =false
# Flyway
spring.flyway.enabled =true
# Actuator (restricted in production)
management.endpoints.web.exposure.include =health
management.endpoint.health.show-details =never
management.health.defaults.enabled =true
# Logging
logging.level.root =INFO
logging.level.br.com.walyson.secure_link =INFO
Production profile hides health check details for security. Only the overall status is exposed.
Test Profile Configuration
Configuration for application-test.properties:
application-test.properties
# H2 in-memory database
spring.datasource.url =jdbc:h2:mem:testdb ;DB_CLOSE_DELAY=-1
spring.datasource.driver-class-name =org.h2.Driver
spring.jpa.database-platform =org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto =create-drop
# Disable Flyway for tests
spring.flyway.enabled =false
Configuration Properties Reference
Link Settings
Property Description Default app.link.default-ttlDefault link expiration time (ISO-8601) PT24H (24 hours)app.base-urlBase URL for link generation http://localhost:8080
Storage Settings
Property Description Default app.storage.pathDirectory for uploaded files /tmp/uploads/spring.servlet.multipart.max-file-sizeMaximum file size 50MBspring.servlet.multipart.max-request-sizeMaximum request size 50MB
CORS Settings
Property Description Default app.cors.allowed-originsComma-separated allowed origins http://localhost:4200,http://127.0.0.1:4200
Database Settings
Property Description spring.datasource.urlJDBC connection URL spring.datasource.usernameDatabase username spring.datasource.passwordDatabase password spring.jpa.hibernate.ddl-autoSchema generation strategy (validate recommended)
Actuator Settings
Property Description management.endpoints.web.exposure.includeExposed actuator endpoints management.endpoint.health.show-detailsHealth endpoint detail level
Monitoring and Observability
Health Checks
The application provides detailed health information at /actuator/health:
Database connectivity - Verifies MySQL connection
Disk space - Checks available storage
Storage health - Validates upload directory
Expiration job - Monitors scheduled task status
Prometheus Metrics
Exposed at /actuator/prometheus (dev profile only):
curl http://localhost:8080/actuator/prometheus
Includes custom business metrics:
secure_link_resolve_success_total - Successful link resolutions
secure_link_resolve_failure_total - Failed access attempts
Standard JVM, HTTP, and database metrics
Logging Configuration
Correlation IDs
Every request includes a correlation ID in logs and response headers:
2026-03-04 10:15:30.123 INFO [http-nio-8080-exec-1] [abc-123-def-456] c.w.s.controller.LinkController - Processing request
The correlation ID is also returned in the X-Correlation-Id response header.
Log Levels
Adjust log levels per package:
logging.level.root =INFO
logging.level.br.com.walyson.secure_link =DEBUG
logging.level.org.springframework.web =DEBUG
logging.level.org.hibernate.SQL =DEBUG
Security Configuration
Password Encryption
Link passwords are encrypted using BCrypt with strength 10:
BCryptPasswordEncoder ( 10 )
CORS Policy
Configure allowed origins for cross-origin requests:
app.cors.allowed-origins =https://example.com,https://app.example.com
Database Migration
Flyway automatically manages database schema versions:
Migration scripts: src/main/resources/db/migration/
Naming convention: V{version}__{description}.sql
Baseline on migrate: Enabled for existing databases
Common Flyway Commands
# View migration status
mvn flyway:info
# Repair checksums
mvn flyway:repair
# Migrate to latest
mvn flyway:migrate
Production Recommendations
Security Best Practices:
Use strong database passwords
Set management.endpoint.health.show-details=never
Limit CORS origins to trusted domains
Use HTTPS for BASE_URL in production
Store .env file securely, never commit to version control
# Database connection pool
spring.datasource.hikari.maximum-pool-size =10
spring.datasource.hikari.minimum-idle =5
# JPA batch processing
spring.jpa.properties.hibernate.jdbc.batch_size =20
File Storage
For production, consider using:
Network-attached storage (NAS)
Object storage (S3, MinIO)
Persistent volumes in containerized environments
Update app.storage.path accordingly:
app.storage.path =/var/secure-link/uploads/
Next Steps