# Configuration Architecture

## Overview

Configuration in this codebase is deliberately split across a small set of focused Spring components and supporting tests. The application uses Spring configuration classes to define shared infrastructure such as caching and locale handling, while tests verify that properties, translations, and environment-driven startup behavior stay aligned.

The result is a configuration model that is easy to reason about:

- runtime behavior is assembled through Spring `@Configuration` classes
- environment and profile settings shape application startup
- tests guard cross-cutting configuration concerns such as i18n completeness and property resolution
- feature-like behavior is expressed through framework configuration rather than scattered ad hoc code

## Implementation Patterns

### Spring configuration classes define infrastructure

The main runtime configuration is centralized in small dedicated classes under `org.springframework.samples.petclinic.system`:

- [`CacheConfiguration`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) enables caching and creates the application cache.
- [`WebConfiguration`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java) configures locale resolution and request interception for i18n.

This keeps infrastructure concerns separate from business logic and makes the application easier to bootstrap and test.

### Caching is configured programmatically

[`CacheConfiguration`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) uses Spring's caching support and JCache integration:

- `@EnableCaching` activates cache abstraction support.
- a `JCacheManagerCustomizer` bean creates the `vets` cache at startup.
- the cache is backed by a `MutableConfiguration` with statistics enabled.

This is a good example of a configuration-first pattern: the cache is not created by application code at the point of use, but by the infrastructure layer during startup.

### Web locale behavior is configured as request infrastructure

[`WebConfiguration`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java) implements `WebMvcConfigurer` and contributes two beans:

- a `SessionLocaleResolver` that defaults to English
- a `LocaleChangeInterceptor` that watches the `lang` query parameter

The interceptor is registered in `addInterceptors`, which makes language switching a cross-cutting concern handled by the web layer rather than individual controllers.

### Translation completeness is enforced by tests

[`I18nPropertiesSyncTest`](src/test/java/org/springframework/samples/petclinic/system/I18nPropertiesSyncTest.java) treats localization as a configuration contract:

- it scans `src/main` for HTML and Java files
- it flags literal text in HTML that is not internationalized
- it checks that all locale property files stay in sync with the base `messages.properties`

This test prevents partial translations and accidental hard-coded UI text from entering the codebase.

### Environment and profile configuration is validated in integration tests

[`PostgresIntegrationTests`](src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java) shows how runtime environment settings are used to select infrastructure:

- the test runs with the `postgres` profile
- it sets Docker Compose-related properties inline on `@SpringBootTest`
- it uses a startup listener, [`PropertiesLogger`](src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java), to inspect resolved environment properties

This test demonstrates that configuration is not only about static property files; it also includes startup arguments, active profiles, and environment overrides.

### Test-specific bootstrapping isolates configuration concerns

[`CrashControllerIntegrationTests`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java) includes an inner [`TestConfiguration`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java) class annotated with `@SpringBootApplication(exclude = ...)`.

That pattern narrows the application context for a focused test case by excluding data source and JPA auto-configuration. It shows how tests can adjust the configuration graph to isolate a specific web behavior.

## Key Classes

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

Defines the application's cache setup. Its main responsibilities are:

- enabling Spring cache abstraction
- creating the `vets` cache
- enabling cache statistics for observability

This class represents the application's cache policy in one place.

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

Defines locale-related web configuration. Its responsibilities are:

- choosing session-based locale storage
- defaulting to English
- allowing request-driven locale changes via `lang`

This class is the main entry point for i18n behavior in the web layer.

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

An application listener used only in the Postgres integration test. It walks enumerable property sources, resolves each property through the Spring environment, and logs the effective value.

It is useful as a diagnostic tool for understanding how layered configuration is being resolved during startup.

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

A nested test bootstrap class that customizes application startup for one integration test. By excluding unrelated auto-configurations, it keeps the test focused on error handling behavior.

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

A structural test for localization assets. It does not configure runtime behavior directly, but it protects the configuration ecosystem by ensuring the translation files and rendered UI text remain consistent.

## How It Fits Together

```mermaid
flowchart TD
A["Application startup"] --> B["CacheConfiguration"]
A --> C["WebConfiguration"]
A --> D["Profile and property settings"]
A --> E["Integration tests"]
B --> F["JCache vets cache"]
B --> G["Cache statistics"]
C --> H["SessionLocaleResolver"]
C --> I["LocaleChangeInterceptor"]
D --> J["Resolved environment"]
E --> K["PropertiesLogger"]
E --> L["TestConfiguration"]
E --> M["I18nPropertiesSyncTest"]
J --> K
I --> N["lang request parameter"]
H --> N
M --> O["messages.properties sync"]
```

At a high level:

1. Spring loads the application configuration classes during startup.
2. `CacheConfiguration` creates the named application cache and enables statistics.
3. `WebConfiguration` installs locale resolution and request-based language switching.
4. Profiles and properties decide which infrastructure and startup behavior are active.
5. Integration tests verify that those settings resolve correctly and remain internally consistent.

## Notes for Developers

- Prefer small, purpose-built `@Configuration` classes when adding new cross-cutting behavior.
- Keep runtime configuration separate from feature logic so that tests can override or exclude it cleanly.
- When adding a new locale, update the `messages*.properties` files together and keep them in sync with the base bundle.
- When adding configuration-backed behavior, decide whether it belongs in runtime Spring configuration, test bootstrap configuration, or a test-only assertion.
- If you add a new cache, follow the same pattern as `CacheConfiguration`: name it explicitly and make its policy visible in configuration rather than in application code.
- If you introduce more web-level settings, extend `WebConfiguration` or add a sibling configuration class rather than scattering interceptors and resolvers across controllers.
- Use integration tests like `PostgresIntegrationTests` to confirm environment-driven behavior, especially when profiles or external services are involved.
