# Architecture Alignment Report - Configuration **Date**: 2025-11-20 **Issue**: Adapter code doesn't match actual Configuration domain model API **Root Cause**: Parallel AI agents generated code with mismatched APIs --- ## ✅ Correct Architecture (From Domain Model) ### Configuration Class Structure **System-Wide Settings** (Configuration.java): ```java public final class Configuration { private final List endpoints; // Per-endpoint configs private final Duration pollingInterval; // System-wide private final int bufferCapacity; // System-wide (300) private final String grpcHost; // gRPC target private final int grpcPort; // gRPC port private final boolean tlsEnabled; // TLS flag private final Duration reconnectDelay; // gRPC reconnect (5s) private final int healthCheckPort; // Health endpoint (8080) } ``` **Per-Endpoint Settings** (EndpointConfig.java): ```java public final class EndpointConfig { private final String url; // Endpoint URL private final Duration timeout; // Per-endpoint timeout! private final Map headers; // Per-endpoint headers! } ``` ### Builder API (Correct Usage) ```java // ✅ CORRECT: Use static factory method Configuration config = Configuration.builder() .endpoints(endpointList) // List .pollingInterval(Duration.ofSeconds(5)) .bufferCapacity(300) .grpcHost("localhost") .grpcPort(50051) .tlsEnabled(false) .reconnectDelay(Duration.ofSeconds(5)) .healthCheckPort(8080) .build(); // ❌ WRONG: Direct constructor access (private!) Configuration.Builder builder = new Configuration.Builder(); // Won't compile! ``` --- ## ❌ What Adapters Are Doing Wrong ### ConfigurationFileAdapter Issues **Wrong API Calls**: ```java // ❌ WRONG new Configuration.Builder() // Constructor is private! builder.grpcServerAddress(String) // Method doesn't exist builder.grpcServerPort(int) // Method doesn't exist builder.httpEndpoints(List) // Wrong type - needs List builder.pollingIntervalSeconds(int) // Wrong type - needs Duration builder.bufferSize(int) // Wrong name - should be bufferCapacity builder.httpTimeoutSeconds(int) // Doesn't exist - timeout is per-endpoint! builder.maxRetries(int) // Doesn't exist - adapter implementation detail builder.retryIntervalSeconds(int) // Doesn't exist - adapter implementation detail config.getBufferSize() // Wrong name - should be getBufferCapacity() config.getGrpcServerPort() // Wrong name - should be getGrpcPort() config.getHttpEndpoints() // Wrong name - should be getEndpoints() ``` **Correct API Calls**: ```java // ✅ CORRECT Configuration.builder() // Static factory method .grpcHost(String) // Correct method name .grpcPort(int) // Correct method name .endpoints(List) // Correct type .pollingInterval(Duration) // Correct type .bufferCapacity(int) // Correct name // No timeout here - it's per-endpoint in EndpointConfig! // No retry config - it's adapter implementation detail! .build() config.getBufferCapacity() // Correct name config.getGrpcPort() // Correct name config.getEndpoints() // Correct name ``` ### HttpPollingAdapter Issues **Wrong Assumptions**: ```java // ❌ WRONG: These methods don't exist in Configuration config.getHttpTimeoutSeconds() // Timeout is per-endpoint! config.getMaxRetries() // Retry is adapter detail! config.getRetryIntervalSeconds() // Retry is adapter detail! ``` **Correct Approach**: ```java // ✅ CORRECT: Get timeout from EndpointConfig for (EndpointConfig endpoint : config.getEndpoints()) { Duration timeout = endpoint.getTimeout(); // Per-endpoint timeout Map headers = endpoint.getHeaders(); // Per-endpoint headers // Retry logic is hardcoded in adapter (Req-FR-17) int maxRetries = 3; // Hardcoded per requirements int retryIntervalSeconds = 5; // Hardcoded per requirements } ``` --- ## 📋 Requirements Traceability ### Req-FR-17: HTTP Retry Logic - **Requirement**: "If the HTTP GET request fails HSP shall retry up to 3 times with 5-second intervals" - **Configuration**: `http.max_retries = 3, http.retry_interval_seconds = 5` - **Correct Implementation**: Hardcoded in HttpPollingAdapter (adapter implementation detail) - **NOT** in domain model Configuration class ### Req-FR-12: HTTP Timeout - **Requirement**: "Configurable timeout per endpoint" - **Correct Location**: EndpointConfig.timeout (Duration) - **NOT** in Configuration class (it's per-endpoint, not system-wide!) ### Req-FR-13: HTTP Headers - **Requirement**: "Custom headers per endpoint" - **Correct Location**: EndpointConfig.headers (Map) - **NOT** in Configuration class (it's per-endpoint!) --- ## 🔧 Required Fixes ### 1. ConfigurationFileAdapter (16 errors) **Fix Strategy**: 1. Change `new Configuration.Builder()` → `Configuration.builder()` 2. Parse JSON to create `List` from endpoint strings 3. Use correct method names: - `grpcHost()` instead of `grpcServerAddress()` - `grpcPort()` instead of `grpcServerPort()` - `endpoints()` instead of `httpEndpoints()` - `pollingInterval(Duration)` instead of `pollingIntervalSeconds(int)` - `bufferCapacity()` instead of `bufferSize()` 4. Remove non-existent methods: - `httpTimeoutSeconds()` - use EndpointConfig - `maxRetries()` - hardcode in adapter - `retryIntervalSeconds()` - hardcode in adapter 5. Use correct getter names: - `getBufferCapacity()` instead of `getBufferSize()` - `getGrpcPort()` instead of `getGrpcServerPort()` - `getEndpoints()` instead of `getHttpEndpoints()` ### 2. HttpPollingAdapter (10 errors) **Fix Strategy**: 1. Remove calls to non-existent Configuration methods 2. Hardcode retry logic (Req-FR-17): ```java private static final int MAX_RETRIES = 3; private static final int RETRY_INTERVAL_SECONDS = 5; ``` 3. Get timeout and headers from EndpointConfig: ```java Duration timeout = endpointConfig.getTimeout(); Map headers = endpointConfig.getHeaders(); ``` 4. Implement pollEndpoint(String url, Map headers, Duration timeout) ### 3. RateLimitedHttpPollingAdapter (3 errors) **Fix Strategy**: 1. Implement pollEndpoint(String url, Map headers, Duration timeout) 2. Same as HttpPollingAdapter --- ## 📝 Summary **The Problem**: - Adapters were generated assuming Configuration contains per-endpoint settings (timeout, headers, retries) - Actual architecture: Configuration contains system-wide settings, EndpointConfig contains per-endpoint settings - Retry logic should be hardcoded in adapter (Req-FR-17), not in configuration **The Solution**: 1. ConfigurationFileAdapter: Use correct Configuration API with Builder pattern 2. HttpPollingAdapter: Hardcode retry logic, get timeout/headers from EndpointConfig 3. Follow hexagonal architecture: domain model is simple, adapters handle complexity **Architecture Principle**: - **Domain Model** (Configuration, EndpointConfig): Simple, immutable value objects - **Adapters** (HttpPollingAdapter): Handle implementation details (retry logic, connection management) - **Separation of Concerns**: System-wide config vs per-endpoint config --- **Next Step**: Apply these fixes to achieve compilation.