# Configuration Architecture

## Overview

Configuration in this codebase is spread across application configuration classes, test-scoped bootstrapping, and verification tests that keep properties, localization resources, and runtime settings aligned. The result is a small but clear configuration surface: web behavior is customized through Spring MVC configuration, caching is enabled through JCache, environment properties are inspected during integration runs, and tests enforce that localized resources stay synchronized.

This architecture matters because the application relies on configuration for behavior that is not purely business logic: locale selection, cache activation, profile-specific bootstrapping, error response shaping, and consistency checks for translated content.

## Implementation Patterns

### Spring configuration classes define runtime behavior

The main application-level configuration is implemented as Spring `@Configuration` classes.

- [`WebConfiguration`](../../src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java) implements `WebMvcConfigurer` and contributes locale handling beans.
- [`CacheConfiguration`](../../src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) enables caching and registers the application cache.

This keeps configuration close to the framework integration point rather than scattering it across controllers or services.

### Locale and i18n are configured through MVC infrastructure

[`WebConfiguration`](../../src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java) uses:

- a session-based [`LocaleResolver`](../../src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java)
- a [`LocaleChangeInterceptor`](../../src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java) bound to the `lang` request parameter

This pattern lets the application switch languages per request without coupling locale handling to individual endpoints.

### Caching is enabled centrally and exposed through JCache

[`CacheConfiguration`](../../src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) uses `@EnableCaching` and creates the `vets` cache through a `JCacheManagerCustomizer`.

The implementation emphasizes two ideas:

- cache setup is centralized in one class
- statistics are enabled programmatically so the cache can be observed through JMX-capable tooling

### Environment-specific behavior is driven by Spring Boot properties and profiles

[`PostgresIntegrationTests`](../../src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java) shows the typical pattern for runtime environment configuration in tests:

- `@SpringBootTest` with inline properties
- `@ActiveProfiles("postgres")` to switch the application to a Postgres-backed setup
- Docker Compose arguments supplied through Spring properties

This makes the test itself the source of truth for the infrastructure assumptions it needs.

### Configuration is verified by tests, not just defined

The codebase includes tests that act as configuration safeguards:

- [`I18nPropertiesSyncTest`](../../src/test/java/org/springframework/samples/petclinic/system/I18nPropertiesSyncTest.java) checks for untranslated literals and verifies message bundles stay in sync.
- [`CrashControllerIntegrationTests`](../../src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java) overrides Spring Boot error and management settings to validate error responses in a controlled environment.
- [`PostgresIntegrationTests`](../../src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java) confirms profile-based startup and logs resolved properties during boot.

### Property visibility is treated as part of the runtime story

[`PropertiesLogger`](../../src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java) is embedded in the Postgres integration test and listens for `ApplicationPreparedEvent`. It iterates over enumerable property sources and logs resolved values versus source values.

That pattern is useful when debugging layered configuration because it shows how source properties, overrides, and effective environment values relate.

## Key Classes

### [`WebConfiguration`](../../src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java)

The web configuration entry point for localization. It defines the session locale resolver and the language-switch interceptor, and then registers that interceptor with Spring MVC.

Use this class as the reference point for anything related to request-driven locale changes or default language behavior.

### [`CacheConfiguration`](../../src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java)

The caching configuration entry point. It enables Spring caching, creates the `vets` cache, and turns on cache statistics.

Use this class as the reference point for application cache wiring and for understanding which cache names are expected to exist.

### [`PropertiesLogger`](../../src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java)

A test utility listener used to inspect the effective environment during startup. It is not part of the application runtime, but it documents how the application’s property sources are layered and resolved.

This class is especially helpful when adding new properties or debugging overrides from profiles, Docker Compose, or test-specific settings.

### [`TestConfiguration`](../../src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java)

A nested test bootstrap class that defines the minimal application context for the crash-controller integration test. It excludes data-source and JPA auto-configuration so the test can focus on web/error behavior.

This is a pattern for narrowing the Spring Boot context in tests when only a slice of behavior needs to be validated.

### [`I18nPropertiesSyncTest`](../../src/test/java/org/springframework/samples/petclinic/system/I18nPropertiesSyncTest.java)

A guardrail test for configuration-adjacent content. It enforces two things:

- HTML and Java sources do not contain unsupported hard-coded user-visible strings
- localized message bundles contain the same keys across locales

This keeps configuration and content resources aligned over time.

## How It Fits Together

```mermaid
flowchart TD
A["Spring Boot application"] --> B["WebConfiguration"]
A --> C["CacheConfiguration"]
A --> D["Profile and property sources"]
D --> E["PropertiesLogger"]
B --> F["Session locale resolver"]
B --> G["LocaleChangeInterceptor"]
C --> H["vets cache"]
I["I18nPropertiesSyncTest"] --> J["messages property bundles"]
K["CrashControllerIntegrationTests"] --> L["Error and management properties"]
M["PostgresIntegrationTests"] --> N["postgres profile and Docker Compose settings"]
M --> E
```

The basic flow is:

1. Spring Boot starts with a set of property sources and active profiles.
2. `WebConfiguration` wires request-time locale handling.
3. `CacheConfiguration` wires the named application cache.
4. Tests verify that configuration assumptions remain true over time.
5. `PropertiesLogger` makes effective runtime configuration visible during integration startup.

## Notes for Developers

- Prefer adding new runtime behavior through focused `@Configuration` classes rather than embedding configuration decisions in controllers or services.
- If you introduce a new cache, register it in [`CacheConfiguration`](../../src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) and consider whether statistics should be enabled.
- If you add or rename localized text keys, update the relevant `messages*.properties` files and expect [`I18nPropertiesSyncTest`](../../src/test/java/org/springframework/samples/petclinic/system/I18nPropertiesSyncTest.java) to enforce consistency.
- When changing profile-specific behavior, check both inline Spring Boot test properties and active profile declarations, especially in [`PostgresIntegrationTests`](../../src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java).
- Treat integration tests as documentation for configuration intent: they show which properties are required, which auto-configurations are excluded, and which startup assumptions are expected to hold.
- For debugging, the `PropertiesLogger` pattern is a good reference for printing effective configuration without guessing how the environment was resolved.