# Config

> Configuration Layer

- Skill: `harshamendu/config` (Agent Skill, multi-file: 24 files)
- Install (CLI): `npx skillmds@latest add harshamendu/config`
- Raw SKILL.md: https://api.skillmd.com/api/skills/harshamendu/config/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Harshamendu (https://skillmd.com/u/harshamendu)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/harshamendu/config

---

# Configuration Layer

> **📝 Note:** This guide uses generic placeholder names to be reusable across any Spring Boot microservice.
> Replace with your actual implementation:
> - `{YourService}` → Your service name (e.g., `OrderService`, `PaymentService`)
> - `BusinessService` → Your core service (e.g., `OrderService`, `UserService`)
> - `DataService` → Your data processing service (e.g., `PaymentService`, `InventoryService`)
> - `IntegrationService` → Your external integration (e.g., `PaymentGatewayService`)
> - `{RequestType}` → Your request DTO (e.g., `CreateOrderRequest`)
> - `{ResponseType}` → Your response DTO (e.g., `OrderResponse`)


## Overview
The configuration layer centralizes all Spring Boot configuration classes, defining beans, API clients, security, async processing, caching, and external service integrations. This layer establishes the application's runtime behavior and dependencies.

**Architecture:** Configuration Classes Pattern with property-based, environment-specific configuration using Spring profiles (local, docker, production).

## Package Structure
```
config/
├── ApiClientConfiguration.java      # External API base URLs and endpoints
├── ApplicationConfiguration.java    # Application-level properties
├── BeanConfiguration.java           # Core bean definitions (ObjectMapper, RestTemplate)
├── ClientConfiguration.java         # HTTP client and template configurations
├── LibraryConfig.java              # Third-party libraries (SQS, cache)
├── SecurityConfiguration.java       # Spring Security settings
├── SwaggerConfiguration.java        # API documentation (Swagger/OpenAPI)
├── WebConfiguration.java           # Web MVC config (CORS, converters)
└── model/rest/ServiceGroup.java    # Service group data model
```

## Configuration Classes

| Class | Purpose | Key Beans |
|-------|---------|-----------|
| `ApiClientConfiguration` | External API endpoints | Token API, Auth API, Profile API URLs |
| `ApplicationConfiguration` | Application properties | Entitlement TTL, SQS queue URLs |
| `BeanConfiguration` | Core beans | ObjectMapper, RestTemplate |
| `ClientConfiguration` | HTTP client setup | RestTemplate with timeouts |
| `LibraryConfig` | Third-party integration | SQS client, cache manager |
| `SecurityConfiguration` | Security settings | Security rules, CSRF config |
| `SwaggerConfiguration` | API documentation | Swagger Docket, API info |
| `WebConfiguration` | Web MVC config | CORS, converters, interceptors |

## Quick Reference

### Centralized API Configuration
```java
@Value("${token.api.base.url}")
private String tokenApiBaseUrl;

@Bean
public String getTokenEndpoint() {
    return tokenApiBaseUrl + "/token";
}
```
**See:** `examples/ApiClientConfigurationExample.java`

### Bean Definition
```java
@Bean
public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.registerModule(new JavaTimeModule());
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    return mapper;
}
```
**See:** `examples/BeanFactoryExample.java`

### Property Injection with Defaults
```java
@Value("${resource access.ttl.seconds:3600}")
private Long resource accessTtlSeconds;
```
**See:** `examples/PropertyBindingExample.java`

### HTTP Client with Timeouts
```java
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder
            .setConnectTimeout(Duration.ofSeconds(30))
            .setReadTimeout(Duration.ofSeconds(30))
            .build();
}
```
**See:** `examples/HttpClientConfigExample.java`

### Connection Pooling
```java
PoolingHttpClientConnectionManager connectionManager = 
    new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(100);
connectionManager.setDefaultMaxPerRoute(20);
```
**See:** `examples/ConnectionPoolingExample.java`

### CORS Configuration
```java
@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/api/**")
            .allowedOrigins("https://amcplus.com", "https://www.amcplus.com")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
            .allowCredentials(true)
            .maxAge(3600);
}
```
**See:** `examples/CorsConfigurationExample.java`

### Conditional Bean Creation
```java
@Bean
@ConditionalOnProperty(name = "aws.sqs.enabled", havingValue = "true")
public AmazonSQS amazonSQS() {
    return AmazonSQSClientBuilder.defaultClient();
}
```
**See:** `examples/LibraryIntegrationExample.java`

## Design Patterns
- **Configuration Pattern:** Centralized configuration by concern
- **Factory Pattern:** Bean factory methods for complex objects
- **Builder Pattern:** RestTemplateBuilder, Docket for fluent configuration
- **Strategy Pattern:** Conditional bean creation based on environment
- **Dependency Injection:** Spring IoC container manages dependencies

## Environment Configuration
```properties
# Production - application.properties
token.api.base.url=${TOKEN_API_BASE_URL}
auth.api.base.url=${AUTH_API_BASE_URL}
aws.sqs.enabled=true

# Local - application-local.properties
token.api.base.url=http://localhost:8081
auth.api.base.url=http://localhost:8082
aws.sqs.enabled=false

# Docker - application-docker.properties
token.api.base.url=http://token-api:8081
auth.api.base.url=http://auth-api:8082
aws.sqs.enabled=true
```

## Key Principles
- ✅ Externalize all configuration values
- ✅ Provide default values for non-critical properties
- ✅ Validate required properties at startup
- ✅ Configure proper timeouts on HTTP clients
- ✅ Use connection pooling for performance
- ✅ Explicit CORS origins (no wildcards)
- ✅ Disable CSRF for stateless REST APIs
- ✅ Use `@ConditionalOnProperty` for feature toggles
- ✅ Separate configuration by concern
- ❌ Never commit secrets to configuration files

## Code Formatting
All Java code is formatted using **Spotless** with Google Java Format (AOSP style).

**Format code:**
```bash
./gradlew spotlessApply
```

## Detailed Documentation

### Guides
- **[Patterns Guide](guides/patterns.md)** - Configuration patterns and design principles
- **[Best Practices Guide](guides/best-practices.md)** - Configuration best practices and standards
- **[Testing Guide](guides/testing.md)** - Testing configuration classes
- **[Anti-Patterns Guide](guides/anti-patterns.md)** - Common mistakes to avoid

### Examples
All examples are in `examples/` directory with package: `com.example.microserviceorch.config.example`

**Configuration Examples:**
- `ApiClientConfigurationExample.java` - API client configuration
- `BeanFactoryExample.java` - Bean factory pattern
- `PropertyBindingExample.java` - Property injection
- `HttpClientConfigExample.java` - HTTP client setup
- `ConnectionPoolingExample.java` - Connection pooling
- `CorsConfigurationExample.java` - CORS configuration
- `LibraryIntegrationExample.java` - Third-party integration
- `BuilderPatternExample.java` - Builder pattern
- `SwaggerConfigurationExample.java` - API documentation

**Test Examples:**
- `ApiClientConfigurationExampleTest.java` - Configuration testing
- `PropertyInjectionExampleTest.java` - Property injection testing
- `ConfigurationIntegrationExampleTest.java` - Integration testing
- `ConditionalBeanExampleTest.java` - Conditional bean testing
- `HttpClientConfigExampleTest.java` - HTTP client testing
- `CorsConfigExampleTest.java` - CORS testing
- `SwaggerConfigExampleTest.java` - Swagger testing
- `ProfileConfigurationExampleTest.java` - Profile testing
- `BeanDependencyExampleTest.java` - Dependency testing

## Summary
The configuration layer ensures centralized configuration for external services, environment-specific settings via Spring profiles, type-safe property binding, proper HTTP client configuration with timeouts and pooling, security configuration, third-party library integration, API documentation via Swagger/OpenAPI, and consistent code formatting with Spotless.

This approach provides flexibility, maintainability, and clear separation of concerns across different configuration aspects.

