# Java Package Structure - HSP System ## Hexagonal Architecture Implementation with Requirement Traceability **Base Package**: `com.siemens.coreshield.hsp` **Architecture**: Hexagonal (Ports & Adapters) --- ## 1. DOMAIN LAYER ### Package: `com.siemens.coreshield.hsp.domain` **Purpose**: Contains the core business logic, domain entities, and business rules. This layer is independent of external frameworks and technologies. --- ### 1.1 Domain Model **Package**: `com.siemens.coreshield.hsp.domain.model` **Purpose**: Domain entities and value objects representing the core business concepts. #### Key Classes: ##### `HealthStatus` **Requirements**: Req-FR-1, Req-FR-2, Req-FR-3 ```java public final class HealthStatus { private final String serviceId; // Req-FR-1: Service identification private final ServiceState state; // Req-FR-2: OK/NOK state private final Instant timestamp; // Req-FR-3: Timestamp private final Map metadata; // Immutable value object pattern // Thread-safe by design (immutable) } public enum ServiceState { OK, // Req-FR-2: Service operational NOK // Req-FR-2: Service degraded/failed } ``` **Thread Safety**: Immutable class, inherently thread-safe **Testing**: Req-NFR-10 - Unit tests for equality, validation ##### `ConfigurationData` **Requirements**: Req-FR-9, Req-FR-10, Req-FR-11, Req-FR-12, Req-FR-13 ```java public final class ConfigurationData { private final PollingConfiguration pollingConfig; // Req-FR-9-13 private final StreamingConfiguration streamConfig; // Req-FR-27-32 private final BufferConfiguration bufferConfig; // Req-FR-25-26 private final HealthCheckConfiguration healthConfig; // Req-NFR-7-8 // Builder pattern for flexible construction // Validation in builder } public final class PollingConfiguration { private final String url; // Req-FR-10: REST endpoint private final Duration interval; // Req-FR-11: Polling interval private final Duration timeout; // Req-FR-12: HTTP timeout private final Map headers; // Req-FR-13: HTTP headers } public final class StreamingConfiguration { private final String grpcHost; // Req-FR-27: gRPC server private final int grpcPort; // Req-FR-28: Port private final boolean tlsEnabled; // Req-FR-29: TLS private final Duration reconnectDelay; // Req-FR-30: Auto-reconnect } public final class BufferConfiguration { private final int capacity; // Req-FR-25: Circular buffer size private final BufferOverflowStrategy strategy; // Req-FR-26: Overflow handling } public enum BufferOverflowStrategy { DROP_OLDEST, // Req-FR-26: Default strategy BLOCK, FAIL } ``` **Thread Safety**: All immutable, thread-safe **Testing**: Req-NFR-10 - Validation logic, builder pattern ##### `DataPacket` **Requirements**: Req-FR-22, Req-FR-23, Req-FR-24 ```java public final class DataPacket { private final byte[] payload; // Req-FR-22: Binary serialization private final SerializationFormat format; // Req-FR-23: Format (JSON/Protobuf) private final Instant createdAt; private final long sequenceNumber; // For ordering // Factory methods for different formats public static DataPacket fromJson(HealthStatus status); public static DataPacket fromProtobuf(HealthStatus status); } public enum SerializationFormat { JSON, // Req-FR-23: JSON support PROTOBUF // Req-FR-24: Protobuf support } ``` **Thread Safety**: Immutable, thread-safe **Testing**: Req-NFR-10 - Serialization correctness --- ### 1.2 Domain Services **Package**: `com.siemens.coreshield.hsp.domain.service` **Purpose**: Business logic and domain operations that don't naturally fit in entities. #### Key Interfaces: ##### `DataSerializationService` **Requirements**: Req-FR-22, Req-FR-23, Req-FR-24 ```java public interface DataSerializationService { /** * Serialize health status to specified format * Req-FR-22: Binary serialization * Req-FR-23: JSON support * Req-FR-24: Protobuf support */ DataPacket serialize(HealthStatus status, SerializationFormat format); /** * Deserialize data packet back to health status */ HealthStatus deserialize(DataPacket packet); } ``` **Thread Safety**: Implementation must be thread-safe (stateless recommended) **Testing**: Req-NFR-10 - Round-trip serialization, format validation ##### `ValidationService` **Requirements**: Req-FR-1 to Req-FR-32 ```java public interface ValidationService { /** * Validate configuration completeness and correctness * Req-FR-9-13: Polling configuration validation * Req-FR-27-32: Streaming configuration validation */ ValidationResult validateConfiguration(ConfigurationData config); /** * Validate health status data integrity * Req-FR-1-3: Status data validation */ ValidationResult validateHealthStatus(HealthStatus status); } public final class ValidationResult { private final boolean valid; private final List errors; } ``` **Thread Safety**: Stateless, thread-safe **Testing**: Req-NFR-10 - Validation rules, edge cases --- ### 1.3 Domain Ports **Package**: `com.siemens.coreshield.hsp.domain.port` **Purpose**: Define interfaces for communication with external systems (adapters). --- #### 1.3.1 Inbound Ports (Primary Ports) **Package**: `com.siemens.coreshield.hsp.domain.port.inbound` **Purpose**: APIs exposed by the domain for external actors to use. ##### `ConfigurationLoaderPort` **Requirements**: Req-FR-9 to Req-FR-13 ```java public interface ConfigurationLoaderPort { /** * Load configuration from external source * Req-FR-9: Configuration file support * Req-FR-10-13: All configuration parameters */ ConfigurationData loadConfiguration() throws ConfigurationException; /** * Req-FR-5: Hot reload support (future) */ void reloadConfiguration() throws ConfigurationException; } ``` **Thread Safety**: Implementations must be thread-safe **Testing**: Req-NFR-10 - Configuration loading, error handling ##### `HealthCheckPort` **Requirements**: Req-NFR-7, Req-NFR-8 ```java public interface HealthCheckPort { /** * Req-NFR-7: Expose health status endpoint * Req-NFR-8: Include component status */ HealthCheckResponse getHealthStatus(); } public final class HealthCheckResponse { private final ApplicationState state; private final Map components; private final Instant timestamp; } public final class ComponentHealth { private final String name; private final ServiceState state; private final String details; } ``` **Thread Safety**: Must be thread-safe for concurrent HTTP requests **Testing**: Req-NFR-7-8 - Health check accuracy ##### `DataProducerPort` **Requirements**: Req-FR-14 to Req-FR-21 ```java public interface DataProducerPort { /** * Start producing health status data * Req-FR-14: Periodic polling * Req-FR-15: HTTP GET method */ void startProducing(); /** * Stop producing data gracefully * Req-FR-8: Graceful shutdown */ void stopProducing(); /** * Get current producer status */ ProducerStatus getStatus(); } ``` **Thread Safety**: Must handle concurrent start/stop safely **Testing**: Req-NFR-9 - Integration tests --- #### 1.3.2 Outbound Ports (Secondary Ports) **Package**: `com.siemens.coreshield.hsp.domain.port.outbound` **Purpose**: Interfaces for external systems/infrastructure that the domain needs. ##### `HttpClientPort` **Requirements**: Req-FR-15, Req-FR-16, Req-FR-17, Req-FR-18, Req-FR-19, Req-FR-20, Req-FR-21 ```java public interface HttpClientPort { /** * Req-FR-15: HTTP GET request * Req-FR-16: URL from configuration * Req-FR-17: Custom headers * Req-FR-18: Timeout handling */ HttpResponse performGet(String url, Map headers, Duration timeout) throws HttpException; /** * Req-FR-19: Response code handling * Req-FR-20: Payload extraction * Req-FR-21: Error handling */ HealthStatus parseResponse(HttpResponse response) throws ParseException; } ``` **Thread Safety**: Must be thread-safe for concurrent requests **Testing**: Req-NFR-9 - HTTP client behavior, timeouts, errors ##### `DataBufferPort` **Requirements**: Req-FR-25, Req-FR-26 ```java public interface DataBufferPort { /** * Req-FR-25: Producer writes to circular buffer * Thread-safe write operation */ boolean offer(DataPacket packet); /** * Req-FR-25: Consumer reads from circular buffer * Thread-safe read operation */ Optional poll(); /** * Req-FR-26: Buffer overflow handling */ BufferStats getStats(); /** * Check buffer capacity */ int remainingCapacity(); /** * Req-FR-8: Graceful shutdown */ void shutdown(); } public final class BufferStats { private final int capacity; private final int size; private final long droppedPackets; // Req-FR-26: Track overflow private final long totalPackets; } ``` **Thread Safety**: CRITICAL - Must be fully thread-safe (lock-free preferred) **Testing**: Req-NFR-10 - Concurrent access, overflow scenarios ##### `GrpcStreamPort` **Requirements**: Req-FR-27 to Req-FR-32 ```java public interface GrpcStreamPort { /** * Req-FR-27: gRPC server connection * Req-FR-28: Configurable endpoint * Req-FR-29: TLS support */ void connect(StreamingConfiguration config) throws GrpcException; /** * Req-FR-30: Auto-reconnect on connection loss */ void reconnect() throws GrpcException; /** * Req-FR-31: Stream data packets * Req-FR-32: Back-pressure handling */ void streamData(DataPacket packet) throws GrpcException; /** * Get current stream status */ StreamStatus getStreamStatus(); /** * Req-FR-8: Graceful disconnect */ void disconnect(); } public final class StreamStatus { private final boolean connected; private final Duration uptime; private final long packetsSent; private final long reconnectAttempts; } ``` **Thread Safety**: Must handle concurrent streaming safely **Testing**: Req-NFR-9 - Connection handling, reconnection, back-pressure ##### `LoggingPort` **Requirements**: Req-FR-4, Req-FR-6, Req-FR-7 ```java public interface LoggingPort { /** * Req-FR-4: Write to specified log file * Req-FR-6: JSON format */ void logHealthStatus(HealthStatus status) throws LoggingException; /** * Req-FR-7: Log errors */ void logError(String message, Throwable error); /** * Log informational messages */ void logInfo(String message); /** * Req-FR-8: Flush logs on shutdown */ void flush(); } ``` **Thread Safety**: Must be thread-safe for concurrent logging **Testing**: Req-NFR-10 - File writing, JSON formatting --- ## 2. ADAPTER LAYER ### Package: `com.siemens.coreshield.hsp.adapter` **Purpose**: Implement the ports defined in the domain layer, connecting to external systems and frameworks. --- ### 2.1 Inbound Adapters (Primary Adapters) **Package**: `com.siemens.coreshield.hsp.adapter.inbound` **Purpose**: Implement primary ports, handling incoming requests. --- #### 2.1.1 HTTP Adapter **Package**: `com.siemens.coreshield.hsp.adapter.inbound.http` ##### `HealthCheckController` **Requirements**: Req-NFR-7, Req-NFR-8 ```java @RestController @RequestMapping("/health") public class HealthCheckController { private final HealthCheckPort healthCheckPort; /** * Req-NFR-7: GET /health endpoint * Req-NFR-8: Return component status */ @GetMapping public ResponseEntity getHealth() { HealthCheckResponse response = healthCheckPort.getHealthStatus(); return ResponseEntity.ok(response); } } ``` **Framework**: Spring Boot (or JAX-RS) **Thread Safety**: Controller is stateless, thread-safe **Testing**: Req-NFR-7 - HTTP endpoint testing --- #### 2.1.2 Configuration Adapter **Package**: `com.siemens.coreshield.hsp.adapter.inbound.config` ##### `FileConfigurationAdapter` **Requirements**: Req-FR-9 to Req-FR-13 ```java public class FileConfigurationAdapter implements ConfigurationLoaderPort { private final String configFilePath; private final ObjectMapper jsonMapper; private final YamlMapper yamlMapper; /** * Req-FR-9: Load from file * Support JSON and YAML formats */ @Override public ConfigurationData loadConfiguration() throws ConfigurationException { // Read file // Parse JSON/YAML // Validate // Build ConfigurationData } /** * Req-FR-5: Reload configuration (future) */ @Override public void reloadConfiguration() throws ConfigurationException { // Re-read file // Notify change listeners } } ``` **Thread Safety**: Synchronize file reading if hot-reload is enabled **Testing**: Req-NFR-10 - File parsing, validation, error cases --- ### 2.2 Outbound Adapters (Secondary Adapters) **Package**: `com.siemens.coreshield.hsp.adapter.outbound` **Purpose**: Implement secondary ports, interacting with external systems. --- #### 2.2.1 HTTP Client Adapter **Package**: `com.siemens.coreshield.hsp.adapter.outbound.http` ##### `HttpPollingAdapter` **Requirements**: Req-FR-15 to Req-FR-21 ```java public class HttpPollingAdapter implements HttpClientPort { private final HttpClient httpClient; private final ObjectMapper objectMapper; /** * Req-FR-15: HTTP GET * Req-FR-17: Custom headers * Req-FR-18: Timeout */ @Override public HttpResponse performGet(String url, Map headers, Duration timeout) throws HttpException { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .timeout(timeout) .headers(headersToArray(headers)) .GET() .build(); try { return httpClient.send(request, HttpResponse.BodyHandlers.ofString()); } catch (IOException | InterruptedException e) { throw new HttpException("HTTP request failed", e); } } /** * Req-FR-19: Response code * Req-FR-20: Parse payload * Req-FR-21: Error handling */ @Override public HealthStatus parseResponse(HttpResponse response) throws ParseException { if (response.statusCode() != 200) { throw new ParseException("Non-200 response: " + response.statusCode()); } // Parse JSON body to HealthStatus return objectMapper.readValue(response.body(), HealthStatus.class); } } ``` **Thread Safety**: HttpClient is thread-safe (Java 11+) **Testing**: Req-NFR-9 - Mock HTTP server, timeout scenarios --- #### 2.2.2 gRPC Streaming Adapter **Package**: `com.siemens.coreshield.hsp.adapter.outbound.grpc` ##### `GrpcStreamingAdapter` **Requirements**: Req-FR-27 to Req-FR-32 ```java public class GrpcStreamingAdapter implements GrpcStreamPort { private ManagedChannel channel; private StreamObserver streamObserver; private final StreamingConfiguration config; private final ScheduledExecutorService reconnectExecutor; /** * Req-FR-27: Connect to gRPC server * Req-FR-28: Use configured endpoint * Req-FR-29: TLS support */ @Override public void connect(StreamingConfiguration config) throws GrpcException { ManagedChannelBuilder channelBuilder = ManagedChannelBuilder .forAddress(config.getGrpcHost(), config.getGrpcPort()); if (config.isTlsEnabled()) { // Configure TLS channelBuilder.useTransportSecurity(); } else { channelBuilder.usePlaintext(); } this.channel = channelBuilder.build(); this.streamObserver = createStreamObserver(); } /** * Req-FR-30: Auto-reconnect */ @Override public void reconnect() throws GrpcException { disconnect(); reconnectExecutor.schedule(() -> { try { connect(config); } catch (GrpcException e) { // Retry with exponential backoff } }, config.getReconnectDelay().toMillis(), TimeUnit.MILLISECONDS); } /** * Req-FR-31: Stream data * Req-FR-32: Handle back-pressure */ @Override public void streamData(DataPacket packet) throws GrpcException { if (!streamObserver.isReady()) { // Back-pressure: wait or buffer throw new GrpcException("Stream not ready - back-pressure"); } DataPacketProto proto = convertToProto(packet); streamObserver.onNext(proto); } @Override public void disconnect() { if (channel != null) { channel.shutdown(); } } } ``` **Thread Safety**: gRPC streams are not thread-safe, synchronize access **Testing**: Req-NFR-9 - gRPC mock server, reconnection logic --- #### 2.2.3 Circular Buffer Adapter **Package**: `com.siemens.coreshield.hsp.adapter.outbound.buffer` ##### `CircularBufferAdapter` **Requirements**: Req-FR-25, Req-FR-26 ```java public class CircularBufferAdapter implements DataBufferPort { private final ArrayBlockingQueue buffer; private final BufferConfiguration config; private final AtomicLong droppedPackets = new AtomicLong(0); private final AtomicLong totalPackets = new AtomicLong(0); public CircularBufferAdapter(BufferConfiguration config) { this.config = config; this.buffer = new ArrayBlockingQueue<>(config.getCapacity()); } /** * Req-FR-25: Producer writes * Req-FR-26: Handle overflow */ @Override public boolean offer(DataPacket packet) { totalPackets.incrementAndGet(); boolean added = buffer.offer(packet); if (!added && config.getStrategy() == BufferOverflowStrategy.DROP_OLDEST) { // Drop oldest and retry buffer.poll(); droppedPackets.incrementAndGet(); return buffer.offer(packet); } if (!added) { droppedPackets.incrementAndGet(); } return added; } /** * Req-FR-25: Consumer reads */ @Override public Optional poll() { return Optional.ofNullable(buffer.poll()); } @Override public BufferStats getStats() { return new BufferStats( config.getCapacity(), buffer.size(), droppedPackets.get(), totalPackets.get() ); } @Override public int remainingCapacity() { return buffer.remainingCapacity(); } @Override public void shutdown() { buffer.clear(); } } ``` **Thread Safety**: CRITICAL - ArrayBlockingQueue is thread-safe, atomics for counters **Testing**: Req-NFR-10 - Concurrent producer/consumer, overflow scenarios --- #### 2.2.4 Logging Adapter **Package**: `com.siemens.coreshield.hsp.adapter.outbound.logging` ##### `FileLoggingAdapter` **Requirements**: Req-FR-4, Req-FR-6, Req-FR-7 ```java public class FileLoggingAdapter implements LoggingPort { private final BufferedWriter fileWriter; private final ObjectMapper jsonMapper; private final ReentrantLock writeLock = new ReentrantLock(); /** * Req-FR-4: Write to file * Req-FR-6: JSON format */ @Override public void logHealthStatus(HealthStatus status) throws LoggingException { try { String json = jsonMapper.writeValueAsString(status); writeLock.lock(); try { fileWriter.write(json); fileWriter.newLine(); fileWriter.flush(); } finally { writeLock.unlock(); } } catch (IOException e) { throw new LoggingException("Failed to write log", e); } } /** * Req-FR-7: Error logging */ @Override public void logError(String message, Throwable error) { // Log error with stack trace } @Override public void flush() { writeLock.lock(); try { fileWriter.flush(); } finally { writeLock.unlock(); } } } ``` **Thread Safety**: ReentrantLock for file access synchronization **Testing**: Req-NFR-10 - Concurrent logging, file integrity --- ## 3. APPLICATION LAYER ### Package: `com.siemens.coreshield.hsp.application` **Purpose**: Application services that orchestrate domain logic and coordinate workflows. --- ### 3.1 Startup Sequence **Package**: `com.siemens.coreshield.hsp.application.startup` ##### `HspApplication` **Requirements**: Req-FR-1 to Req-FR-8 ```java @SpringBootApplication public class HspApplication { public static void main(String[] args) { SpringApplication.run(HspApplication.class, args); } } @Component public class ApplicationStartupListener implements ApplicationListener { private final ConfigurationLoaderPort configLoader; private final StartupOrchestrator orchestrator; /** * Req-FR-1: Start sequence */ @Override public void onApplicationEvent(ContextRefreshedEvent event) { try { // Load configuration ConfigurationData config = configLoader.loadConfiguration(); // Initialize components orchestrator.initialize(config); // Start producer-consumer pipeline orchestrator.start(); } catch (Exception e) { // Req-FR-7: Error handling System.exit(1); } } } ``` **Thread Safety**: Single-threaded startup **Testing**: Req-NFR-9 - Integration test for full startup ##### `StartupOrchestrator` **Requirements**: Req-FR-1 to Req-FR-8 ```java @Service public class StartupOrchestrator { private final DataProducerPort producerPort; private final DataConsumerService consumerService; private final HealthCheckPort healthCheckPort; /** * Req-FR-1-8: Initialize all components */ public void initialize(ConfigurationData config) { // Validate configuration // Initialize buffer // Initialize HTTP client // Initialize gRPC client // Initialize logging } /** * Req-FR-1: Start producer-consumer */ public void start() { consumerService.start(); producerPort.startProducing(); } /** * Req-FR-8: Graceful shutdown */ @PreDestroy public void shutdown() { producerPort.stopProducing(); consumerService.stop(); // Flush logs // Close connections } } ``` **Thread Safety**: Coordinated startup/shutdown **Testing**: Req-NFR-9 - Integration test --- ### 3.2 Orchestration Services **Package**: `com.siemens.coreshield.hsp.application.orchestration` ##### `DataProducerService` **Requirements**: Req-FR-14 to Req-FR-21, Req-FR-25 ```java @Service public class DataProducerService implements DataProducerPort { private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private final HttpClientPort httpClient; private final DataBufferPort buffer; private final LoggingPort logger; private final PollingConfiguration config; private ScheduledFuture pollingTask; /** * Req-FR-14: Start periodic polling * Req-FR-11: Use configured interval */ @Override public void startProducing() { pollingTask = scheduler.scheduleAtFixedRate( this::pollAndBuffer, 0, config.getInterval().toMillis(), TimeUnit.MILLISECONDS ); } /** * Req-FR-15-21: Poll HTTP endpoint * Req-FR-25: Write to buffer */ private void pollAndBuffer() { try { // Req-FR-15: HTTP GET HttpResponse response = httpClient.performGet( config.getUrl(), config.getHeaders(), config.getTimeout() ); // Req-FR-19-20: Parse response HealthStatus status = httpClient.parseResponse(response); // Req-FR-4: Log to file logger.logHealthStatus(status); // Req-FR-22-24: Serialize DataPacket packet = DataPacket.fromProtobuf(status); // Req-FR-25: Write to buffer buffer.offer(packet); } catch (Exception e) { // Req-FR-21: Error handling logger.logError("Polling failed", e); } } /** * Req-FR-8: Stop gracefully */ @Override public void stopProducing() { if (pollingTask != null) { pollingTask.cancel(false); } scheduler.shutdown(); } } ``` **Thread Safety**: ScheduledExecutorService handles thread safety **Testing**: Req-NFR-9 - Mock HTTP client, verify polling ##### `DataConsumerService` **Requirements**: Req-FR-25, Req-FR-27 to Req-FR-32 ```java @Service public class DataConsumerService { private final ExecutorService consumerExecutor = Executors.newSingleThreadExecutor(); private final DataBufferPort buffer; private final GrpcStreamPort grpcStream; private final LoggingPort logger; private volatile boolean running = false; /** * Req-FR-25: Start consuming from buffer * Req-FR-27-32: Stream to gRPC */ public void start() { running = true; consumerExecutor.submit(this::consumeLoop); } private void consumeLoop() { while (running) { try { // Req-FR-25: Read from buffer Optional packet = buffer.poll(); if (packet.isPresent()) { // Req-FR-31: Stream to gRPC grpcStream.streamData(packet.get()); } else { // Buffer empty, wait briefly Thread.sleep(10); } } catch (GrpcException e) { // Req-FR-30: Trigger reconnect logger.logError("gRPC streaming failed", e); grpcStream.reconnect(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } } /** * Req-FR-8: Stop gracefully */ public void stop() { running = false; consumerExecutor.shutdown(); try { consumerExecutor.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { consumerExecutor.shutdownNow(); } } } ``` **Thread Safety**: Single consumer thread, atomic flag for state **Testing**: Req-NFR-9 - Mock buffer and gRPC, verify consumption ##### `HealthCheckService` **Requirements**: Req-NFR-7, Req-NFR-8 ```java @Service public class HealthCheckService implements HealthCheckPort { private final DataProducerPort producer; private final DataBufferPort buffer; private final GrpcStreamPort grpcStream; /** * Req-NFR-7: Health check endpoint * Req-NFR-8: Component status */ @Override public HealthCheckResponse getHealthStatus() { Map components = new HashMap<>(); // Producer status components.put("producer", new ComponentHealth( "HTTP Producer", producer.getStatus().isRunning() ? ServiceState.OK : ServiceState.NOK, "Polling interval: " + producer.getStatus().getInterval() )); // Buffer status BufferStats stats = buffer.getStats(); components.put("buffer", new ComponentHealth( "Circular Buffer", stats.getSize() < stats.getCapacity() ? ServiceState.OK : ServiceState.NOK, String.format("Size: %d/%d, Dropped: %d", stats.getSize(), stats.getCapacity(), stats.getDroppedPackets()) )); // gRPC stream status StreamStatus streamStatus = grpcStream.getStreamStatus(); components.put("grpc-stream", new ComponentHealth( "gRPC Stream", streamStatus.isConnected() ? ServiceState.OK : ServiceState.NOK, String.format("Connected: %s, Packets sent: %d", streamStatus.isConnected(), streamStatus.getPacketsSent()) )); // Overall application state ApplicationState overallState = components.values().stream() .allMatch(c -> c.getState() == ServiceState.OK) ? ApplicationState.HEALTHY : ApplicationState.DEGRADED; return new HealthCheckResponse(overallState, components, Instant.now()); } } public enum ApplicationState { HEALTHY, DEGRADED, UNHEALTHY } ``` **Thread Safety**: Read-only operations, thread-safe **Testing**: Req-NFR-7-8 - Verify health check logic --- ## 4. CONFIGURATION MODELS ### Package: `com.siemens.coreshield.hsp.config` ##### `ApplicationConfiguration` **Requirements**: All configuration requirements ```java @Configuration @ConfigurationProperties(prefix = "hsp") public class ApplicationConfiguration { private PollingConfiguration polling; private StreamingConfiguration streaming; private BufferConfiguration buffer; private HealthCheckConfiguration healthCheck; // Getters/setters for Spring Boot configuration binding } @ConfigurationProperties(prefix = "hsp.health") public class HealthCheckConfiguration { private int port = 8080; // Req-NFR-7: Health check port private String path = "/health"; // Req-NFR-7: Endpoint path private boolean enabled = true; } ``` **Framework**: Spring Boot Configuration Properties **Testing**: Req-NFR-10 - Configuration binding tests --- ## 5. THREAD SAFETY SUMMARY ### Critical Thread-Safe Components: 1. **CircularBufferAdapter** (Req-FR-25, Req-FR-26) - Uses `ArrayBlockingQueue` (thread-safe) - Atomic counters for statistics - **Test**: Concurrent producer-consumer stress test 2. **DataProducerService** (Req-FR-14) - `ScheduledExecutorService` for polling - **Test**: Verify single polling thread 3. **DataConsumerService** (Req-FR-25) - Single consumer thread - Volatile flag for state management - **Test**: Verify consumption thread safety 4. **FileLoggingAdapter** (Req-FR-4) - `ReentrantLock` for file writes - **Test**: Concurrent logging stress test 5. **GrpcStreamingAdapter** (Req-FR-27-32) - Synchronize stream access (gRPC streams not thread-safe) - **Test**: Concurrent streaming attempts 6. **HttpPollingAdapter** (Req-FR-15) - `HttpClient` is thread-safe (Java 11+) - **Test**: Concurrent HTTP requests --- ## 6. TESTING REQUIREMENTS MAPPING ### Unit Tests (Req-NFR-10) - All domain models (immutability, validation) - All domain services (business logic) - All adapters (mocked external dependencies) - Configuration loading and validation - Serialization/deserialization ### Integration Tests (Req-NFR-9) - HTTP polling with mock server - gRPC streaming with mock server - Producer-consumer pipeline - Configuration loading from file - Health check endpoint - Full startup sequence ### Performance Tests (Req-NFR-11, Req-NFR-12) - Polling performance: 1000 requests/second - Memory usage: < 100MB - Latency: < 100ms per poll - Buffer throughput ### Load Tests - Concurrent producer-consumer stress test - Buffer overflow scenarios - gRPC back-pressure handling - Reconnection scenarios --- ## 7. DEPENDENCY INJECTION CONFIGURATION ### Spring Boot Bean Configuration ```java @Configuration public class HspConfiguration { @Bean public HttpClientPort httpClient() { return new HttpPollingAdapter(); } @Bean public DataBufferPort dataBuffer(BufferConfiguration config) { return new CircularBufferAdapter(config); } @Bean public GrpcStreamPort grpcStream() { return new GrpcStreamingAdapter(); } @Bean public LoggingPort logger() { return new FileLoggingAdapter(); } @Bean public DataSerializationService serializer() { return new DataSerializationServiceImpl(); } @Bean public ConfigurationLoaderPort configLoader() { return new FileConfigurationAdapter(); } @Bean public DataProducerPort producer(HttpClientPort httpClient, DataBufferPort buffer, LoggingPort logger) { return new DataProducerService(httpClient, buffer, logger); } @Bean public HealthCheckPort healthCheck(DataProducerPort producer, DataBufferPort buffer, GrpcStreamPort grpcStream) { return new HealthCheckService(producer, buffer, grpcStream); } } ``` --- ## 8. MAVEN PROJECT STRUCTURE ``` hsp/ ├── pom.xml # Maven configuration ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/siemens/coreshield/hsp/ │ │ │ ├── domain/ │ │ │ │ ├── model/ │ │ │ │ │ ├── HealthStatus.java │ │ │ │ │ ├── ServiceState.java │ │ │ │ │ ├── ConfigurationData.java │ │ │ │ │ ├── PollingConfiguration.java │ │ │ │ │ ├── StreamingConfiguration.java │ │ │ │ │ ├── BufferConfiguration.java │ │ │ │ │ ├── DataPacket.java │ │ │ │ │ └── SerializationFormat.java │ │ │ │ ├── service/ │ │ │ │ │ ├── DataSerializationService.java │ │ │ │ │ ├── DataSerializationServiceImpl.java │ │ │ │ │ ├── ValidationService.java │ │ │ │ │ └── ValidationServiceImpl.java │ │ │ │ └── port/ │ │ │ │ ├── inbound/ │ │ │ │ │ ├── ConfigurationLoaderPort.java │ │ │ │ │ ├── HealthCheckPort.java │ │ │ │ │ └── DataProducerPort.java │ │ │ │ └── outbound/ │ │ │ │ ├── HttpClientPort.java │ │ │ │ ├── DataBufferPort.java │ │ │ │ ├── GrpcStreamPort.java │ │ │ │ └── LoggingPort.java │ │ │ ├── adapter/ │ │ │ │ ├── inbound/ │ │ │ │ │ ├── http/ │ │ │ │ │ │ └── HealthCheckController.java │ │ │ │ │ └── config/ │ │ │ │ │ └── FileConfigurationAdapter.java │ │ │ │ └── outbound/ │ │ │ │ ├── http/ │ │ │ │ │ └── HttpPollingAdapter.java │ │ │ │ ├── grpc/ │ │ │ │ │ └── GrpcStreamingAdapter.java │ │ │ │ ├── buffer/ │ │ │ │ │ └── CircularBufferAdapter.java │ │ │ │ └── logging/ │ │ │ │ └── FileLoggingAdapter.java │ │ │ ├── application/ │ │ │ │ ├── startup/ │ │ │ │ │ ├── HspApplication.java │ │ │ │ │ ├── ApplicationStartupListener.java │ │ │ │ │ └── StartupOrchestrator.java │ │ │ │ └── orchestration/ │ │ │ │ ├── DataProducerService.java │ │ │ │ ├── DataConsumerService.java │ │ │ │ └── HealthCheckService.java │ │ │ └── config/ │ │ │ ├── ApplicationConfiguration.java │ │ │ ├── HealthCheckConfiguration.java │ │ │ └── HspConfiguration.java │ │ └── resources/ │ │ ├── application.yml # Spring Boot configuration │ │ └── logback.xml # Logging configuration │ └── test/ │ └── java/ │ └── com/siemens/coreshield/hsp/ │ ├── domain/ │ │ ├── model/ │ │ │ ├── HealthStatusTest.java │ │ │ └── ConfigurationDataTest.java │ │ └── service/ │ │ └── DataSerializationServiceTest.java │ ├── adapter/ │ │ ├── http/ │ │ │ └── HttpPollingAdapterTest.java │ │ ├── buffer/ │ │ │ └── CircularBufferAdapterTest.java │ │ └── grpc/ │ │ └── GrpcStreamingAdapterTest.java │ ├── application/ │ │ ├── DataProducerServiceTest.java │ │ └── DataConsumerServiceTest.java │ └── integration/ │ ├── ProducerConsumerIntegrationTest.java │ ├── HttpPollingIntegrationTest.java │ └── HealthCheckIntegrationTest.java ``` --- ## 9. KEY DEPENDENCIES (pom.xml) ```xml org.springframework.boot spring-boot-starter-web io.grpc grpc-netty-shaded io.grpc grpc-protobuf io.grpc grpc-stub com.fasterxml.jackson.core jackson-databind com.google.protobuf protobuf-java ch.qos.logback logback-classic org.springframework.boot spring-boot-starter-test test org.junit.jupiter junit-jupiter test org.mockito mockito-core test ``` --- ## 10. REQUIREMENT TRACEABILITY MATRIX | Package/Class | Requirements Covered | |--------------|---------------------| | **domain.model.HealthStatus** | Req-FR-1, Req-FR-2, Req-FR-3 | | **domain.model.ConfigurationData** | Req-FR-9 to Req-FR-13, Req-FR-27 to Req-FR-32 | | **domain.model.DataPacket** | Req-FR-22, Req-FR-23, Req-FR-24 | | **domain.service.DataSerializationService** | Req-FR-22, Req-FR-23, Req-FR-24 | | **domain.port.inbound.DataProducerPort** | Req-FR-14 to Req-FR-21 | | **domain.port.outbound.DataBufferPort** | Req-FR-25, Req-FR-26 | | **domain.port.outbound.GrpcStreamPort** | Req-FR-27 to Req-FR-32 | | **domain.port.outbound.LoggingPort** | Req-FR-4, Req-FR-6, Req-FR-7 | | **adapter.inbound.http.HealthCheckController** | Req-NFR-7, Req-NFR-8 | | **adapter.outbound.http.HttpPollingAdapter** | Req-FR-15 to Req-FR-21 | | **adapter.outbound.grpc.GrpcStreamingAdapter** | Req-FR-27 to Req-FR-32 | | **adapter.outbound.buffer.CircularBufferAdapter** | Req-FR-25, Req-FR-26 | | **adapter.outbound.logging.FileLoggingAdapter** | Req-FR-4, Req-FR-6, Req-FR-7 | | **application.startup.HspApplication** | Req-FR-1 to Req-FR-8 | | **application.orchestration.DataProducerService** | Req-FR-14 to Req-FR-21, Req-FR-25 | | **application.orchestration.DataConsumerService** | Req-FR-25, Req-FR-27 to Req-FR-32 | | **application.orchestration.HealthCheckService** | Req-NFR-7, Req-NFR-8 | | **Test Suite** | Req-NFR-7 to Req-NFR-12 | --- ## 11. IMPLEMENTATION SEQUENCE RECOMMENDATION ### Phase 1: Core Domain (Week 1) 1. Domain models (HealthStatus, ConfigurationData, DataPacket) 2. Domain services (DataSerializationService, ValidationService) 3. Port interfaces (all inbound and outbound ports) 4. **Unit tests for all domain components** ### Phase 2: Adapters (Week 2-3) 5. Configuration adapter (FileConfigurationAdapter) 6. HTTP polling adapter (HttpPollingAdapter) 7. Circular buffer adapter (CircularBufferAdapter) 8. File logging adapter (FileLoggingAdapter) 9. **Unit tests for all adapters with mocks** ### Phase 3: Application Layer (Week 3-4) 10. Producer service (DataProducerService) 11. Consumer service (DataConsumerService) 12. Health check service (HealthCheckService) 13. Startup orchestrator (StartupOrchestrator) 14. **Integration tests for producer-consumer pipeline** ### Phase 4: gRPC Integration (Week 4-5) 15. gRPC streaming adapter (GrpcStreamingAdapter) 16. gRPC proto definitions 17. **Integration tests with mock gRPC server** ### Phase 5: Integration & Testing (Week 5-6) 18. Full system integration 19. Performance testing (Req-NFR-11, Req-NFR-12) 20. Load testing 21. Health check endpoint testing (Req-NFR-7, Req-NFR-8) --- ## 12. NOTES 1. **Hexagonal Architecture Benefits**: - Domain logic independent of frameworks - Easy to test (mock ports) - Flexible adapter implementations - Clear separation of concerns 2. **Thread Safety Critical Paths**: - Producer → Buffer (concurrent writes) - Buffer → Consumer (concurrent reads) - File logging (concurrent writes) - gRPC streaming (concurrent stream access) 3. **Testing Strategy**: - Domain: Pure unit tests (no mocks needed) - Adapters: Unit tests with mocked external systems - Application: Integration tests with real components - System: End-to-end tests 4. **Extension Points**: - Add new polling sources (HTTP → Kafka, MQTT, etc.) - Add new streaming targets (gRPC → WebSocket, TCP, etc.) - Add new serialization formats (JSON/Protobuf → Avro, MessagePack, etc.) - Add metrics/monitoring (Prometheus, Grafana) --- **Document Version**: 1.0 **Created**: 2025-11-19 **Author**: Coder Agent (Hive Mind) **Status**: Complete