Skip to main content

Spring Profiles

Secure Link API uses Spring profiles to manage different environments:
ProfilePurposeDatabase
devLocal developmentMySQL
prodProduction deploymentMySQL
testAutomated testingH2 (in-memory)

Activating a Profile

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

VariableDescriptionExample
BASE_URLPublic URL for the APIhttp://localhost:8080
DB_HOSTMySQL host addresslocalhost
DB_PORTMySQL port3307
DB_NAMEDatabase namesecure_link
DB_USERNAMEDatabase useradmin
DB_PASSWORDDatabase passwordsecure_password
For production deployments, use DB_URL instead of individual host/port/name variables for better security and flexibility.

Example .env File

.env
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.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

PropertyDescriptionDefault
app.link.default-ttlDefault link expiration time (ISO-8601)PT24H (24 hours)
app.base-urlBase URL for link generationhttp://localhost:8080

Storage Settings

PropertyDescriptionDefault
app.storage.pathDirectory for uploaded files/tmp/uploads/
spring.servlet.multipart.max-file-sizeMaximum file size50MB
spring.servlet.multipart.max-request-sizeMaximum request size50MB

CORS Settings

PropertyDescriptionDefault
app.cors.allowed-originsComma-separated allowed originshttp://localhost:4200,http://127.0.0.1:4200

Database Settings

PropertyDescription
spring.datasource.urlJDBC connection URL
spring.datasource.usernameDatabase username
spring.datasource.passwordDatabase password
spring.jpa.hibernate.ddl-autoSchema generation strategy (validate recommended)

Actuator Settings

PropertyDescription
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

Performance Tuning

# 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

Build docs developers (and LLMs) love