hackathon/ARCHITECTURE_ALIGNMENT_REPORT.md
Christoph Wagner a489c15cf5 feat: Add complete HSP implementation with integration tests passing
Initial implementation of HTTP Sender Plugin following TDD methodology
  with hexagonal architecture. All 313 tests passing (0 failures).

  This commit adds:
  - Complete domain model and port interfaces
  - All adapter implementations (HTTP, gRPC, file logging, config)
  - Application services (data collection, transmission, backpressure)
  - Comprehensive test suite with 18 integration tests

  Test fixes applied during implementation:
  - Fix base64 encoding validation in DataCollectionServiceIntegrationTest
  - Fix exception type handling in IConfigurationPortTest
  - Fix CompletionException unwrapping in IHttpPollingPortTest
  - Fix sequential batching in DataTransmissionServiceIntegrationTest
  - Add test adapter failure simulation for reconnection tests
  - Use adapter counters for gRPC verification

  Files added:
  - pom.xml with all dependencies (JUnit 5, Mockito, WireMock, gRPC, Jackson)
  - src/main/java: Domain model, ports, adapters, application services
  - src/test/java: Unit tests, integration tests, test utilities
2025-11-20 22:38:55 +01:00

208 lines
8.0 KiB
Markdown

# 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<EndpointConfig> 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<String, String> headers; // Per-endpoint headers!
}
```
### Builder API (Correct Usage)
```java
// ✅ CORRECT: Use static factory method
Configuration config = Configuration.builder()
.endpoints(endpointList) // List<EndpointConfig>
.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<String>) // Wrong type - needs List<EndpointConfig>
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<EndpointConfig>) // 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<String,String> 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<String,String>)
- **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<EndpointConfig>` 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<String,String> headers = endpointConfig.getHeaders();
```
4. Implement pollEndpoint(String url, Map<String,String> headers, Duration timeout)
### 3. RateLimitedHttpPollingAdapter (3 errors)
**Fix Strategy**:
1. Implement pollEndpoint(String url, Map<String,String> 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.