rama creada apartir de master en j

This commit is contained in:
jrojas
2026-06-26 10:29:23 +02:00
parent 319fd3dfb0
commit c1517fda87
2810 changed files with 1927392 additions and 25392 deletions
+196
View File
@@ -0,0 +1,196 @@
# adas-core.module.ProxyDevices — Proxy Devices Module
> A **functional module** of the ADAS Core platform.
> Encapsulates all logic for proxying communication with external hardware devices over HTTP. This module acts as a configurable gateway layer that the Host registers at startup, translating internal requests into authenticated HTTP calls to remote endpoints.
---
## Table of Contents
1. [Overview](#overview)
2. [Responsibilities](#responsibilities)
3. [Project Structure](#project-structure)
4. [Dependencies](#dependencies)
5. [Device Proxy Architecture](#device-proxy-architecture)
6. [ProxyDeviceService Flow](#proxydeviceservice-flow)
7. [Design Rules](#design-rules)
---
## Overview
`adas-core.module.ProxyDevices` is a modular satellite project that provides a **proxy gateway** for interacting with external hardware devices over HTTP. It abstracts the complexity of device authentication, connection management, and response handling behind a uniform `IProxyDevice` contract.
Key characteristics:
- **Modular Monolith Pattern** — Self-contained module with its own device drivers, service orchestration, and configuration model. No other module depends on it directly.
- **Plugin Architecture** — New device types are added by creating a class that implements `IProxyDevice` and naming it `{Type}Device`. The service discovers and instantiates them at runtime via reflection.
- **Digest Authentication Support** — The built-in `HttpDevice` supports HTTP Digest authentication via `NetworkCredential`.
- **Instance Caching** — `ProxyDeviceService` maintains an in-memory cache of initialized device instances to avoid repeated construction and initialization overhead.
- **Dual Operation Modes** — Each device supports both `Process()` (full response) and `Stream()` (response-headers-read) operations.
- **Configuration-Driven** — All devices, their types, and parameters are defined in `ProxyDeviceSettings` bound from `appsettings.json`.
---
## Responsibilities
| Concern | What this project does |
|---------|----------------------|
| **Device Proxying** | Acts as an intermediary between the Host and external HTTP-based devices, shielding the rest of the system from protocol specifics. |
| **Device Lifecycle** | Manages device initialization, caching, and disposal through the `IProxyDevice` contract. |
| **HTTP Communication** | `HttpDevice` performs authenticated and unauthenticated HTTP GET requests with timeout handling. |
| **Digest Authentication** | Supports HTTP Digest auth via `username`, `password`, and optional `domain` parameters. |
| **Reflection-Based Factory** | `ProxyDeviceService` dynamically instantiates device classes by type name at runtime (`{Type}Device`). |
| **Instance Caching** | Caches initialized `IProxyDevice` instances per `deviceId` to minimize repeated setup costs. |
| **Streaming vs Processing** | Offers `Process()` for complete responses and `Stream()` for streaming (headers-first) scenarios. |
| **Error Translation** | Converts `HttpRequestException`, `TaskCanceledException`, and missing-device errors into standardized `HttpResponseMessage` responses. |
| **Configuration Model** | Defines `ProxyDeviceSettings` and `ProxyDevice` as strongly-typed configuration objects bound from the Host's configuration system. |
| **Audit Logging** | Emits audit events for device access and proxy operations via `AuditLogs`. |
---
## Project Structure
```
adas-core.module.ProxyDevices/
├── ProxyDeviceSettings.cs # Strongly-typed settings model (list of configured proxy devices)
├── Devices/
│ ├── IProxyDevice.cs # Core contract: Initialize, Process, Stream
│ └── HttpDevice.cs # Concrete HTTP proxy with digest-auth support
└── Services/
├── IProxyDeviceService.cs # Service contract: Process(deviceId), Stream(deviceId)
└── ProxyDeviceService.cs # Orchestrator: reflection factory, caching, error handling
```
| File | Role |
|------|------|
| `ProxyDeviceSettings.cs` | Configuration root. A `List<ProxyDevice>` bound from `appsettings.json`. Each entry defines `Id`, `Type`, `Enabled`, and `Parameters`. |
| `IProxyDevice.cs` | Interface contract. All proxy devices implement `Initialize(Dictionary)`, `Process()`, and `Stream()`. |
| `HttpDevice.cs` | Concrete proxy for HTTP endpoints. Validates `url`, optional digest auth, performs GET requests, handles timeouts. |
| `IProxyDeviceService.cs` | Application-facing contract. Host controllers depend on this interface, not on module internals. |
| `ProxyDeviceService.cs` | Implementation. Reads settings, looks up devices by `Id`, lazily instantiates and caches drivers, delegates to `Process()` or `Stream()`. |
---
## Dependencies
### Downstream References
This project has **no direct project references** to other ADAS Core projects. It is a completely decoupled satellite module.
| Package | Version | Purpose |
|---------|---------|---------|
| `Microsoft.Extensions.DependencyInjection` | 10.0.8 | DI registration helpers used during Host startup. |
| `Microsoft.Extensions.Hosting` | 10.0.8 | Hosting abstractions for optional background proxy services. |
### Upstream References (projects that depend on this)
| Project | Reason |
|---------|--------|
| `adas-core` (Host) | Registers `IProxyDeviceService` and `ProxyDeviceSettings` at startup. Host controllers invoke `Process()` and `Stream()` through the service interface. |
### NuGet Packages
| Package | Version | Purpose |
|---------|---------|---------|
| `Microsoft.Extensions.DependencyInjection` | 10.0.8 | Service-collection registration helpers. |
| `Microsoft.Extensions.Hosting` | 10.0.8 | Hosting abstractions for background services. |
| `Serilog` | 4.3.1 | Structured logging for timeout and HTTP error events. |
| `AuditLogs` | 1.0.59 | Audit trail emission for device access and proxy operations. |
| `SharpCompress` | 0.49.0 | Available for potential compression pipelines in future device types. |
| `Snappier` | 1.3.1 | Fast compression library for future streaming optimization. |
---
## Device Proxy Architecture
### `IProxyDevice` Contract
```csharp
public interface IProxyDevice
{
void Initialize(Dictionary<string, object?> deviceParameters);
Task<HttpResponseMessage> Process();
Task<HttpResponseMessage> Stream();
}
```
| Member | Purpose |
|--------|---------|
| `Initialize(parameters)` | One-time setup. Validates required keys (`url`), extracts optional keys (`name`, `username`, `password`, `domain`), and marks the device as ready. |
| `Process()` | Performs a full HTTP GET request and returns the complete `HttpResponseMessage`. |
| `Stream()` | Performs an HTTP GET with `HttpCompletionOption.ResponseHeadersRead`, enabling callers to stream the body without buffering. |
### `HttpDevice` — Built-in HTTP Proxy
- **URI Validation** — Requires a non-empty, absolute `url` in parameters. Throws `ArgumentNullException` if missing or invalid.
- **Single Initialization Guard** — Throws `InvalidOperationException` if `Initialize()` is called twice.
- **Optional Digest Auth** — When `username` is provided, sets `HttpClientHandler.Credentials` with `NetworkCredential(username, password, domain)`.
- **Timeout Translation** — Catches `TaskCanceledException` (timeout) and re-throws as `TimeoutException` with a descriptive message.
- **Diagnostics** — Overrides `ToString()` to emit `[HttpDevice] (name uri username password domain)` for logging.
### Adding a New Device Type
1. Create a class in `Devices/` that implements `IProxyDevice`.
2. Name it `{Type}Device` (e.g., `TcpDevice`, `UdpDevice`).
3. Register the type string in `appsettings.json` under `ProxyDeviceSettings`.
4. `ProxyDeviceService` will resolve it automatically via reflection at first use.
## ProxyDeviceService Flow
### Device Resolution & Caching
```
[Host Controller] --> [ProxyDeviceService.Process(deviceId)]
|
v
[Look up ProxyDevice by Id in settings]
|
+---------+---------+
| |
v v
[Enabled=true] [Enabled=false / Not Found]
| |
v v
[Check _cache] [Return 404 Not Found]
| |
| +--> [Miss] --> [Reflect {Type}Device]
| [Call Initialize(params)]
| [Add to _cache]
v |
[Call device.Process()] <--+
|
v
[Return HttpResponseMessage]
```
### Key Behaviors
- **Thread-Safe Cache** — The `_cache` dictionary is guarded by a `lock` during read/write to prevent race conditions.
- **Lazy Instantiation** — Devices are created only on first access, not at startup.
- **Graceful Degradation** — If a device is not found, disabled, or throws `HttpRequestException`, the service returns an `HttpResponseMessage` with an appropriate status code rather than crashing.
- **No Dispose Lifecycle** — Cached instances are reused for the lifetime of the service. The Host manages the service scope (typically Singleton).
---
## Design Rules
1. **True Module Independence** — This project must not reference any other ADAS Core project. It communicates with the Host exclusively through its own public interfaces and the .NET configuration/options system.
2. **Configuration-Driven Discovery** — Device types, endpoints, and credentials must come exclusively from `ProxyDeviceSettings` bound to `appsettings.json`. No hardcoded URLs or auth secrets.
3. **Reflection Factory** — New device types are added by convention (`{Type}Device` implementing `IProxyDevice`). No central switch statement needs modification (Open/Closed).
4. **Cache Safety** — The device instance cache is protected by a `lock` during writes. Reads inside the lock are safe because initialization is atomic.
5. **Fail Securely** — Missing or disabled devices return `404 Not Found`. HTTP failures are translated into `HttpResponseMessage` with the original status code. Timeouts become `TimeoutException`.
6. **No Business Logic** — This module handles transport only. Any transformation, validation, or business-rule enforcement belongs in `Application` or the Host.
7. **Lazy Initialization** — Devices are instantiated on first request, not at Host startup. This prevents delaying startup when a remote device is unreachable.
8. **Digest Auth Only**`HttpDevice` supports HTTP Digest authentication. Basic auth, bearer tokens, or mTLS must be implemented in a separate `IProxyDevice` implementation if needed.
9. **Audit Every Access** — Every `Process()` and `Stream()` call emits an audit event via `AuditLogs` tagging the device ID and outcome.
10. **Singleton Service**`ProxyDeviceService` is registered as a **Singleton** because it holds cached device instances and settings that are immutable after startup.
---
<p align="center">
Back to <a href="../README.md">adas-core Root README</a>
</p>