# Configuration Architecture

## Overview

Configuration in this codebase is intentionally split across application wiring, test-time overrides, and verification checks. The result is a small set of focused configuration classes that keep runtime behavior predictable while still allowing environment-specific tuning for caching, localization, and integration testing.

At a high level, the application configuration is organized around three concerns:

1. **Web and localization settings** — how requests resolve locale and how users switch languages.
2. **Caching** — how shared data is cached and instrumented.
3. **Environment and test configuration** — how tests shape the runtime environment and verify that localized and externalized settings stay consistent.

## Implementation Patterns

### 1. Spring configuration classes define infrastructure concerns

The main application wiring lives in configuration classes under `org.springframework.samples.petclinic.system`.

- [`WebConfiguration`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java) is a `@Configuration` class that implements `WebMvcConfigurer` and registers locale-related beans.
- [`CacheConfiguration`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) is a `@Configuration(proxyBeanMethods = false)` class that enables caching and creates the application cache used by the veterinary repository layer.

This pattern keeps cross-cutting infrastructure separate from domain logic.

### 2. Locale is a first-class request concern

[`WebConfiguration`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java) defines a session-backed locale resolver and a request interceptor:

- a `SessionLocaleResolver` stores the active locale in the user session
- a `LocaleChangeInterceptor` watches for the `lang` request parameter
- `addInterceptors(...)` registers that interceptor for every request

This gives the application a simple, URL-driven localization model without coupling controllers to locale management.

### 3. Caching is enabled centrally and measured via JCache statistics

[`CacheConfiguration`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) enables Spring caching with `@EnableCaching` and supplies a `JCacheManagerCustomizer` bean.

The customizer creates the `vets` cache and uses a `MutableConfiguration` with statistics enabled. That means the cache is not just functional; it is observable through the JCache/JMX path as well.

### 4. Test code validates configuration behavior rather than duplicating it

The test suite includes configuration-oriented checks that enforce consistency:

- [`CrashControllerIntegrationTests`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java) sets test-only Spring properties to control error output and management access.
- [`PostgresIntegrationTests`](src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java) uses `@ActiveProfiles("postgres")` and inline `@SpringBootTest(properties = ...)` to activate a PostgreSQL-backed environment.
- [`I18nPropertiesSyncTest`](src/test/java/org/springframework/samples/petclinic/system/I18nPropertiesSyncTest.java) checks that localization assets stay synchronized and that HTML views do not accidentally hard-code translatable text.

### 5. Environment visibility is explicitly logged in the PostgreSQL integration path

`PostgresIntegrationTests` contains a nested [`PropertiesLogger`](src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java) listener that inspects enumerable property sources on application startup and logs property resolution details. This is a diagnostic pattern rather than a runtime dependency, but it reflects the codebase’s emphasis on understanding which settings come from which source.

## Key Classes

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

This class defines the application’s locale strategy.

- Uses `SessionLocaleResolver` so the locale persists across requests
- Defaults to English when no locale has been selected
- Registers `LocaleChangeInterceptor` with the `lang` parameter
- Applies request interception through `WebMvcConfigurer`

Use this class as the reference point for anything related to internationalization or locale switching.

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

This class configures the caching layer.

- Enables Spring cache abstraction
- Creates the `vets` cache via JCache customization
- Enables cache statistics for visibility and diagnostics

This is the main place to look when changing cache names, cache providers, or observability settings.

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

This nested test helper prints resolved configuration values from enumerable property sources.

- Helps compare raw property source values with the resolved Spring Environment value
- Surfaces overridden properties during test startup
- Serves as a diagnostic tool for environment-sensitive integration runs

It is not part of production application behavior, but it is an important example of how the project inspects configuration.

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

This nested `@SpringBootApplication` class customizes the test application context.

- Excludes `DataSourceAutoConfiguration`
- Excludes `DataSourceTransactionManagerAutoConfiguration`
- Excludes `HibernateJpaAutoConfiguration`

The pattern allows web-focused tests to run without bringing up the persistence stack.

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

This test enforces configuration consistency for localization resources.

- Scans application source for non-internationalized HTML text literals
- Verifies that `messages*.properties` files remain in sync across locales
- Treats translation completeness as a build-time contract

This is a key guardrail for maintaining a coherent internationalization setup.

## How It Fits Together

```mermaid
flowchart TD
  ConfigSources["Configuration sources"] --> WebConfig["WebConfiguration"]
  ConfigSources --> CacheConfig["CacheConfiguration"]
  ConfigSources --> TestConfig["TestConfiguration"]
  ConfigSources --> PropsLogger["PropertiesLogger"]
  ConfigSources --> I18nSyncTest["I18nPropertiesSyncTest"]
  WebConfig --> LocaleResolver["SessionLocaleResolver"]
  WebConfig --> LocaleInterceptor["LocaleChangeInterceptor"]
  LocaleInterceptor --> RequestLocale["Request parameter lang"]
  CacheConfig --> JCache["JCache manager"]
  CacheConfig --> VetsCache["vets cache"]
  PropsLogger --> Environment["Spring Environment"]
  I18nSyncTest --> Messages["messages*.properties"]
  TestConfig --> CrashTest["CrashControllerIntegrationTests"]
```

The configuration story works like this:

- **Request handling** uses `WebConfiguration` to interpret locale settings from the session and the `lang` query parameter.
- **Data access** uses `CacheConfiguration` to make repeated repository access efficient and measurable.
- **Integration tests** reshape the application context with inline properties and profile activation.
- **Consistency tests** ensure that translation files and UI text stay aligned over time.

## Notes for Developers

- Prefer adding cross-cutting settings in dedicated configuration classes rather than scattering them across controllers or services.
- When introducing a new locale-related behavior, update `WebConfiguration` and verify that message bundles still pass `I18nPropertiesSyncTest`.
- When adding or renaming caches, update `CacheConfiguration` and check whether any diagnostics or tests depend on the existing cache name.
- Use `@SpringBootTest(properties = ...)` and `@ActiveProfiles(...)` for test-specific configuration instead of hard-coding environment assumptions in production code.
- If you need to inspect which property source is winning in a test run, the `PropertiesLogger` pattern in `PostgresIntegrationTests` is a good reference.
- Treat translation resource files as part of the configuration surface: they are validated automatically, so missing keys will fail the build.
- Keep configuration classes focused on infrastructure concerns. That makes it easier to reason about environment differences and to test them independently.
