# Org / Springframework / Samples / Petclinic / System

## Overview

The `org.springframework.samples.petclinic.system` package contains the small set of system-level web components that support the Petclinic application’s shared behavior. This module appears to focus on cross-cutting concerns rather than domain data: home-page routing, error demo behavior, cache setup, and internationalization support.

A new engineer reading this package should understand it as the place where the application’s global web defaults are assembled. It wires a language-switching MVC configuration, exposes a root welcome page, and defines a controlled failure route used by tests to verify Spring Boot’s error handling.

## Key Classes and Interfaces

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

`CacheConfiguration` is a Spring `@Configuration` class that enables caching for the application and creates the JCache cache used by the app.

Its main role is to register the `vets` cache with statistics enabled. That is useful because it lets the application observe cache behavior through JMX or other management tooling, which is especially valuable in a sample app that demonstrates caching integration.

**Key methods**

- [`petclinicCacheConfigurationCustomizer()`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java:35)
  - Returns a `JCacheManagerCustomizer`.
  - The customizer creates a cache named `vets` by calling `createCache("vets", cacheConfiguration())`.
  - Side effect: when the cache manager is initialized, the application gets a preconfigured cache entry for veterinarian data.

- [`cacheConfiguration()`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java:49)
  - Returns a `javax.cache.configuration.Configuration<Object, Object>`.
  - Builds a `MutableConfiguration` and enables statistics with `setStatisticsEnabled(true)`.
  - The method is private and encapsulates the minimal programmatic JCache setup used by the customizer.

**Design notes**

This class relies on JCache abstractions rather than a vendor-specific cache API. The code comments make it clear that JCache’s standard configuration surface is intentionally limited, so deeper tuning is expected to come from the concrete cache provider.

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

`CrashController` is a small MVC controller whose purpose is to deliberately throw an exception when a specific route is hit. It exists to demonstrate error handling and to support tests that verify how the application responds to a server-side failure.

**Key method**

- [`triggerException()`](src/main/java/org/springframework/samples/petclinic/system/CrashController.java:31)
  - Mapped to `GET /oups`.
  - Returns `String`, but never actually returns a view name because it immediately throws a `RuntimeException`.
  - The exception message is a fixed string: `Expected: controller used to showcase what happens when an exception is thrown`.
  - Side effect: request processing is aborted and control is transferred to Spring Boot’s error handling.

**Design notes**

This appears to be intentionally simple and test-oriented. The controller does not depend on any services or data sources; it is only a trigger for the framework’s error pipeline.

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

`WebConfiguration` configures internationalization support for the web layer. It implements `WebMvcConfigurer`, which allows it to register MVC interceptors and define infrastructure beans used across requests.

The class is responsible for two related pieces of behavior: storing the user’s locale in the session, and allowing the locale to be changed through a query parameter such as `?lang=de`.

**Key methods**

- [`localeResolver()`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java:32)
  - Returns a `LocaleResolver`.
  - Instantiates `SessionLocaleResolver` and sets the default locale to `Locale.ENGLISH`.
  - Side effect: if the user has not chosen a language yet, the application falls back to English.

- [`localeChangeInterceptor()`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java:44)
  - Returns a `LocaleChangeInterceptor`.
  - Configures the interceptor to look for the request parameter named `lang`.
  - Side effect: requests can switch locale without changing the application state elsewhere.

- [`addInterceptors(InterceptorRegistry registry)`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java:55)
  - Registers the locale change interceptor with the MVC interceptor registry.
  - Parameter: `registry`, the MVC registry where interceptors are added.
  - Side effect: the interceptor runs on each request, so locale switching works consistently.

**Design notes**

This configuration uses session storage instead of a stateless cookie or header-based approach. That choice keeps the user’s language stable across navigation while remaining easy to reason about in a sample application.

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

`WelcomeController` provides the application’s root route and directs the user to the welcome page.

**Key method**

- [`welcome()`](src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java:25)
  - Mapped to `GET /`.
  - Returns the view name `welcome`.
  - Side effect: forwards the root URL to the welcome template rather than rendering content directly from the controller.

**Design notes**

This is a conventional view controller. It keeps the startup path minimal and delegates presentation to the view layer.

### [`package-info.java`](src/main/java/org/springframework/samples/petclinic/system/package-info.java:1)

The package-info file declares the package and serves as the package-level documentation anchor. In this module, it does not add behavior of its own, but it establishes the namespace for the system-level controllers and configuration.

## How It Works

### Request flow for the home page

1. A browser requests `GET /`.
2. Spring MVC routes the request to [`WelcomeController.welcome()`](src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java:25).
3. The controller returns the logical view name `welcome`.
4. The view resolver renders the corresponding page template.

This flow keeps the root route simple and avoids embedding presentation logic in the controller.

### Request flow for language selection

1. A request arrives with a `lang` query parameter, such as `?lang=de`.
2. [`WebConfiguration.localeChangeInterceptor()`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java:44) provides the interceptor that watches for the parameter.
3. [`WebConfiguration.addInterceptors(InterceptorRegistry registry)`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java:55) ensures the interceptor runs on each request.
4. The locale resolver created by [`localeResolver()`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java:32) stores the selected locale in the session.
5. Future requests reuse that session locale until the user changes it again.

### Request flow for the crash route

1. A client requests `GET /oups`.
2. Spring MVC dispatches the request to [`CrashController.triggerException()`](src/main/java/org/springframework/samples/petclinic/system/CrashController.java:31).
3. The method throws a `RuntimeException` immediately.
4. Spring Boot’s error handling converts that exception into an error response.
5. Depending on the request’s `Accept` header, the response becomes JSON or an HTML error page.

### Cache initialization flow

1. The application context starts and caching is enabled by [`CacheConfiguration`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java:31).
2. [`petclinicCacheConfigurationCustomizer()`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java:35) registers a customizer with the cache manager.
3. When the cache manager is ready, it creates the `vets` cache.
4. [`cacheConfiguration()`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java:49) supplies a minimal JCache configuration with statistics enabled.
5. The cache can now be used by application code and monitored through cache statistics.

```mermaid
flowchart TD
  WebConfiguration["WebConfiguration"] --> LocaleResolverBean["LocaleResolver bean"]
  WebConfiguration --> LocaleChangeInterceptorBean["LocaleChangeInterceptor bean"]
  WebConfiguration --> InterceptorRegistry["InterceptorRegistry"]
  WelcomeController["WelcomeController"] --> WelcomeView["welcome view"]
  CrashController["CrashController"] --> OupsRoute["GET /oups"]
  OupsRoute --> ErrorHandling["Spring error handling"]
  CacheConfiguration["CacheConfiguration"] --> VetsCache["vets cache"]
  CacheConfiguration --> JCacheStats["JCache statistics"]
  CrashControllerTests["CrashControllerTests"] --> CrashController
  CrashControllerIntegrationTests["CrashControllerIntegrationTests"] --> CrashController
  I18nPropertiesSyncTest["I18nPropertiesSyncTest"] --> MessageFiles["messages*.properties"]
```

## Data Model

This package does not define domain entities or DTOs. Its data-related concerns are limited to framework objects and configuration values:

- `Locale` for default language selection in [`WebConfiguration.localeResolver()`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java:32)
- `LocaleResolver` and `LocaleChangeInterceptor` for MVC internationalization infrastructure
- JCache `Configuration<Object, Object>` and `MutableConfiguration` for cache setup
- Error response payloads produced by Spring Boot when [`CrashController`](src/main/java/org/springframework/samples/petclinic/system/CrashController.java:28) throws an exception

## Dependencies and Integration

This module integrates primarily with Spring MVC, Spring Boot caching, and Spring Boot’s error handling.

- **Spring MVC**
  - [`WelcomeController`](src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java:22) and [`CrashController`](src/main/java/org/springframework/samples/petclinic/system/CrashController.java:28) are MVC controllers.
  - [`WebConfiguration`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java:23) extends MVC behavior through `WebMvcConfigurer`.

- **Internationalization**
  - [`WebConfiguration`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java:23) configures session-based locale resolution and a request parameter for switching languages.
  - [`I18nPropertiesSyncTest`](src/test/java/org/springframework/samples/petclinic/system/I18nPropertiesSyncTest.java:25) enforces consistency across message property files and catches untranslated keys.

- **Caching**
  - [`CacheConfiguration`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java:31) enables caching and creates a `vets` cache.
  - Statistics are turned on so the cache can be inspected operationally.

- **Error handling**
  - [`CrashControllerIntegrationTests`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java:50) exercises Spring Boot’s JSON and HTML error rendering for the `/oups` route.
  - [`CrashControllerTests`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java:31) verifies that the controller throws the expected exception message.

## Notes for Developers

- The `CrashController` route is intentionally named `/oups` and intentionally fails. Treat it as a test/demo endpoint, not a real application workflow.
- [`WebConfiguration`](src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java:23) assumes language switching happens through the `lang` query parameter. If you add new internationalized pages, they should respect the same resolver and message bundle conventions.
- [`CacheConfiguration`](src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java:31) creates only the `vets` cache. If the application needs more caches, this is the place to register them.
- The tests in this package are part behavioral verification and part documentation of expected framework integration. They are especially useful when changing error handling or i18n setup.
- [`I18nPropertiesSyncTest`](src/test/java/org/springframework/samples/petclinic/system/I18nPropertiesSyncTest.java:25) is a guardrail against accidental hard-coded UI text and translation drift. If you add user-facing strings, make sure the relevant properties files stay aligned.

## Test Coverage

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

A focused unit test that instantiates `CrashController` directly and asserts that [`triggerException()`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java:35) throws a `RuntimeException` containing the expected message.

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

An integration test that starts the application on a random port and calls `/oups` over HTTP.

It verifies two response modes:

- **JSON error response** when the request accepts the default content type
- **HTML error page** when the request explicitly accepts `text/html`

This test also confirms the error payload contains useful fields such as `timestamp`, `status`, `error`, `message`, and `path`, and that the HTML page is not the default whitelabel page.

The nested [`TestConfiguration`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java:95) class is a minimal `@SpringBootApplication` used to bootstrap the test context without unrelated persistence auto-configuration.

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

This test suite checks two things:

1. HTML files do not contain hard-coded user-facing strings where internationalized message references should be used.
2. The `messages*.properties` files remain in sync so translated bundles do not drift from the base set of keys.

Together, these tests help keep the system-level UI consistent across languages.
