hackathon/docs/architecture/java-package-structure.md
Christoph Wagner 5b658e2468 docs: add architectural review and requirement refinement verification
Complete architectural analysis and requirement traceability improvements:

  1. Architecture Review Report (NEW)
     - Independent architectural review identifying 15 issues
     - 5 critical issues: security (no TLS), buffer inadequacy, performance
       bottleneck, missing circuit breaker, inefficient backoff
     - 5 major issues: no metrics, no graceful shutdown, missing rate limiting,
       no backpressure, low test coverage
     - Overall architecture score: 6.5/10
     - Recommendation: DO NOT DEPLOY until critical issues resolved
     - Detailed analysis with code examples and effort estimates

  2. Requirement Refinement Verification (NEW)
     - Verified Req-FR-25, Req-NFR-7, Req-NFR-8 refinement status
     - Added 12 missing Req-FR-25 references to architecture documents
     - Confirmed 24 Req-NFR-7 references (health check endpoint)
     - Confirmed 26 Req-NFR-8 references (health check content)
     - 100% traceability for all three requirements

  3. Architecture Documentation Updates
     - system-architecture.md: Added 4 Req-FR-25 references for data transmission
     - java-package-structure.md: Added 8 Req-FR-25 references across components
     - Updated DataTransmissionService, GrpcStreamPort, GrpcStreamingAdapter,
       DataConsumerService with proper requirement annotations

  Files changed:
  - docs/ARCHITECTURE_REVIEW_REPORT.md (NEW)
  - docs/REQUIREMENT_REFINEMENT_VERIFICATION.md (NEW)
  - docs/architecture/system-architecture.md (4 additions)
  - docs/architecture/java-package-structure.md (8 additions)

  All 62 requirements now have complete bidirectional traceability with
  documented architectural concerns and critical issues identified for resolution.
2025-11-19 11:06:02 +01:00

45 KiB

Java Package Structure - HSP System

Hexagonal Architecture Implementation with Requirement Traceability

Base Package: com.siemens.coreshield.hsp

Architecture: Hexagonal (Ports & Adapters) Document Version: 1.1 Updated: 2025-11-19 (Critical Issues Resolved) Total Requirements: 62


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

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<String, String> 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-Test-4 - Unit tests for equality, validation

ConfigurationData

Requirements: Req-FR-9, Req-FR-10, Req-FR-11, Req-FR-12, Req-FR-13

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-26-27
    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<String, String> 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-26: 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-Test-4 - Validation logic, builder pattern

DataPacket

Requirements: Req-FR-22, Req-FR-23, Req-FR-24

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-Test-4 - 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

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-Test-4 - Round-trip serialization, format validation

ValidationService

Requirements: Req-FR-1 to Req-FR-32

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<ValidationError> errors;
}

Thread Safety: Stateless, thread-safe Testing: Req-Test-4 - 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

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-Test-4 - Configuration loading, error handling

HealthCheckPort

Requirements: Req-NFR-7, Req-NFR-8

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<String, ComponentHealth> 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

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-Test-1 - 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

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<String, String> 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-26, Req-FR-27

public interface DataBufferPort {
    /**
     * Req-FR-26: Producer writes to circular buffer
     * Thread-safe write operation
     */
    boolean offer(DataPacket packet);

    /**
     * Req-FR-26: Consumer reads from circular buffer
     * Thread-safe read operation
     */
    Optional<DataPacket> 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-25, Req-FR-28 to Req-FR-33

public interface GrpcStreamPort {
    /**
     * Req-FR-25: Send collected data to Collector Sender Core
     * Req-FR-28: gRPC server connection
     * Req-FR-29: Configurable endpoint
     * Req-FR-30: TLS support
     */
    void connect(StreamingConfiguration config) throws GrpcException;

    /**
     * Req-FR-30: Auto-reconnect on connection loss
     */
    void reconnect() throws GrpcException;

    /**
     * Req-FR-25: Send aggregated data to Collector Sender Core
     * Req-FR-31: Stream data packets
     * Req-FR-32: Back-pressure handling
     * Req-FR-33: receiver_id = 99
     */
    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

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

@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<HealthCheckResponse> getHealth() {
        HealthCheckResponse response = healthCheckPort.getHealthStatus();
        return ResponseEntity.ok(response);
    }
}

Framework: Spring Boot (or JAX-RS) Thread Safety: Controller is stateless, thread-safe Testing: Req-Test-1 - 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

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-Test-4 - 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

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<String, String> 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-Test-1 - Mock HTTP server, timeout scenarios


2.2.2 gRPC Streaming Adapter

Package: com.siemens.coreshield.hsp.adapter.outbound.grpc

GrpcStreamingAdapter

Requirements: Req-FR-25, Req-FR-28 to Req-FR-33

public class GrpcStreamingAdapter implements GrpcStreamPort {
    private ManagedChannel channel;
    private StreamObserver<DataPacketProto> streamObserver;
    private final StreamingConfiguration config;
    private final ScheduledExecutorService reconnectExecutor;

    /**
     * Req-FR-25: Send data to Collector Sender Core
     * Req-FR-28: Connect to gRPC server
     * Req-FR-29: Use configured endpoint
     * Req-FR-30: 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-25: Send collected and aggregated data to Collector Sender Core
     * Req-FR-31: Stream data
     * Req-FR-32: Handle back-pressure
     * Req-FR-33: Set receiver_id = 99
     */
    @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-Test-2 - gRPC mock server, reconnection logic


2.2.3 Circular Buffer Adapter

Package: com.siemens.coreshield.hsp.adapter.outbound.buffer

CircularBufferAdapter

Requirements: Req-FR-26, Req-FR-27

public class CircularBufferAdapter implements DataBufferPort {
    private final ArrayBlockingQueue<DataPacket> 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-26: Producer writes
     * Req-FR-27: 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-26: Consumer reads
     */
    @Override
    public Optional<DataPacket> 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-Test-4 - 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

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-Test-4 - 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

@SpringBootApplication
public class HspApplication {
    public static void main(String[] args) {
        SpringApplication.run(HspApplication.class, args);
    }
}

@Component
public class ApplicationStartupListener implements ApplicationListener<ContextRefreshedEvent> {
    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-Test-1 - Integration test for full startup

StartupOrchestrator

Requirements: Req-FR-1 to Req-FR-8

@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-Test-1 - Integration test


3.2 Orchestration Services

Package: com.siemens.coreshield.hsp.application.orchestration

DataProducerService

Requirements: Req-FR-14 to Req-FR-21, Req-FR-26

@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-26: 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-26: 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-Test-1 - Mock HTTP client, verify polling

DataConsumerService

Requirements: Req-FR-25, Req-FR-26, Req-FR-28 to Req-FR-33

@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: Send data to Collector Sender Core
     * Req-FR-26: Start consuming from buffer
     * Req-FR-28-33: Stream to gRPC
     */
    public void start() {
        running = true;
        consumerExecutor.submit(this::consumeLoop);
    }

    private void consumeLoop() {
        while (running) {
            try {
                // Req-FR-26: Read from buffer
                Optional<DataPacket> packet = buffer.poll();

                if (packet.isPresent()) {
                    // Req-FR-25: Send data to Collector Sender Core
                    // 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-Test-2 - Mock buffer and gRPC, verify consumption

HealthCheckService

Requirements: Req-NFR-7, Req-NFR-8

@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<String, ComponentHealth> 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

@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-Test-4 - Configuration binding tests


5. THREAD SAFETY SUMMARY

Critical Thread-Safe Components:

  1. CircularBufferAdapter (Req-FR-26, Req-FR-27)

    • 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-26)

    • 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-Test-3: JUnit 5 + Mockito)

  • All domain models (immutability, validation)
  • All domain services (business logic)
  • All adapters (mocked external dependencies)
  • Configuration loading and validation
  • Serialization/deserialization

Integration Tests (Req-Test-1: Mock HTTP, Req-Test-2: Mock gRPC)

  • Req-Test-1: HTTP polling with WireMock HTTP server
  • Req-Test-2: gRPC streaming with mock gRPC server
  • Producer-consumer pipeline
  • Configuration loading from file
  • Health check endpoint
  • Full startup sequence
  • Req-Test-4: All tests executable via 'mvn test'

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

@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)

<dependencies>
    <!-- Spring Boot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- HTTP Client (Java 11+) -->
    <!-- Built-in: java.net.http.HttpClient -->

    <!-- gRPC -->
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-netty-shaded</artifactId>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-protobuf</artifactId>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-stub</artifactId>
    </dependency>

    <!-- JSON (Jackson) -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>

    <!-- Protocol Buffers -->
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
    </dependency>

    <!-- Logging -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
    </dependency>

    <!-- Testing -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

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-28 to Req-FR-33
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-26, Req-FR-27
domain.port.outbound.GrpcStreamPort Req-FR-25, Req-FR-28 to Req-FR-33
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-25, Req-FR-28 to Req-FR-33
adapter.outbound.buffer.CircularBufferAdapter Req-FR-26, Req-FR-27
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-26, Req-FR-27
application.orchestration.DataConsumerService Req-FR-25, Req-FR-26, Req-FR-28 to Req-FR-33
application.orchestration.HealthCheckService Req-NFR-7, Req-NFR-8
Test Suite Req-Test-1 to Req-Test-4

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)

  1. Configuration adapter (FileConfigurationAdapter)
  2. HTTP polling adapter (HttpPollingAdapter)
  3. Circular buffer adapter (CircularBufferAdapter)
  4. File logging adapter (FileLoggingAdapter)
  5. Unit tests for all adapters with mocks

Phase 3: Application Layer (Week 3-4)

  1. Producer service (DataProducerService)
  2. Consumer service (DataConsumerService)
  3. Health check service (HealthCheckService)
  4. Startup orchestrator (StartupOrchestrator)
  5. Integration tests for producer-consumer pipeline

Phase 4: gRPC Integration (Week 4-5)

  1. gRPC streaming adapter (GrpcStreamingAdapter)
  2. gRPC proto definitions
  3. Integration tests with mock gRPC server

Phase 5: Integration & Testing (Week 5-6)

  1. Full system integration
  2. Performance testing (Req-NFR-11, Req-NFR-12)
  3. Load testing
  4. 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.1 Created: 2025-11-19 Updated: 2025-11-19 (Critical Issues Resolved) Author: Coder Agent (Hive Mind) Status: Complete - All 62 requirements traced