Files
adas-core/adas-core
..
2026-06-26 10:29:23 +02:00

adas-core — API Host

ASP.NET Core Web API host for the ADAS Core platform.
This project is the Presentation Layer and application entry point. It composes all lower layers (Domain, Application, Infrastructure, Authentication, and Modules) via dependency injection, configures the HTTP pipeline, and exposes REST endpoints, WebSocket hubs, and OpenAPI documentation.


Table of Contents

  1. Overview
  2. Responsibilities
  3. Project Structure
  4. Dependencies
  5. Configuration Profiles
  6. Middleware Pipeline
  7. REST Endpoints
  8. WebSocket / SignalR Hubs
  9. Swagger & OpenAPI
  10. Serilog Bootstrap
  11. Build & Run
  12. Design Rules

Overview

The adas-core project is the executable ASP.NET Core application that hosts the entire ADAS backend. Its sole responsibility is to:

  • Wire every layer and module into the dependency injection container.
  • Load environment-specific configuration.
  • Build the HTTP request pipeline (auth, CORS, error handling, routing).
  • Expose REST controllers, WebSocket (SignalR) hubs, and Prometheus metrics.
  • Bootstrap Serilog structured logging and Swagger API discovery.

It contains no business logic — all domain rules, use cases, and data access live in referenced projects.


Responsibilities

Concern What this project does
Composition Root Registers all repositories, services, authentication strategies, MongoDB, Redis, and SignalR into IServiceCollection.
Configuration Loading Loads layered appsettings.json files (base + environment-specific) using ConfigurationBuilder.
Pipeline Setup Configures middleware order: auth, CORS, WebSockets, error handling, controllers, SignalR hubs.
API Exposure Defines ASP.NET Core controllers that delegate to Application-layer services.
Real-Time Messaging Hosts SignalR hubs (UciHub) for WebSocket-based push communication.
API Documentation Auto-generates Swagger / OpenAPI specs with Newtonsoft.Json and ObjectId schema mapping.
Health & Metrics Exposes /metrics (Prometheus) and Swagger UI at runtime.
Logging Initialization Bootstraps Serilog from configuration with dynamic trace identifiers and contextual enrichers.

Project Structure

adas-core/
├── Program.cs                          # Application bootstrap (DI registration + pipeline)
├── appsettings.json                    # Base configuration
├── appsettings.{Environment}.json    # Environment-specific overrides (see list below)
├── Properties/
│   └── launchSettings.json             # Launch profiles per environment
├── Configurations/
│   └── ServiceExtension.cs             # Extension methods: JWT auth, ProxyDevices, config binding
├── Controllers/                        # ASP.NET Core API controllers
│   ├── UserController.cs
│   ├── PatientController.cs
│   ├── DeviceController.cs
│   ├── AlarmController.cs
│   ├── LightBeaconController.cs
│   ├── ProxyDeviceController.cs
│   ├── RelayController.cs
│   ├── PumpsController.cs
│   ├── ObservationsController.cs
│   ├── TreatmentsController.cs
│   ├── DisplayController.cs
│   ├── ConfigObservationController.cs
│   ├── ConfigDisplayController.cs
│   ├── PointOfCareController.cs
│   ├── AdmissionController.cs
│   ├── DischargeController.cs
│   ├── AuditController.cs
│   ├── RabbitController.cs
│   ├── QXController.cs
│   ├── SendAlertController.cs
│   ├── SensorController.cs
│   ├── RecordingController.cs
│   ├── RecordingAlertController.cs
│   ├── ServiceConfigController.cs
│   ├── MasterListController.cs
│   ├── UnitController.cs
│   ├── NoticeController.cs
│   ├── MedicinesController.cs
│   ├── DiagnosisController.cs
│   ├── BoxController.cs
│   ├── CameraController.cs
│   ├── ApplicationController.cs
│   ├── GroupedObservationsController.cs
│   ├── PatientAppointmentController.cs
│   └── ...
├── ErrorMiddleware/
│   └── ErrorHandlerMiddleware.cs       # Global exception-handling middleware
├── Logging/
│   ├── LogExecutionContext.cs          # Ambient trace-identifier context
│   └── LogProvider.cs                  # Logger resolution helper
├── WebSocket/
│   ├── WebSocketMessageService.cs      # WebSocket outbound message service
│   └── Hubs/
│       └── UciHub.cs                   # SignalR hub for real-time subscriptions
└── Dockerfile                           # Multi-stage Linux container image

Dependencies

Downstream References (this project depends on)

Project Role
adas-core.Domain Domain entities, value objects, and repository contracts used by controllers for DTO mapping and route parameters.
adas-core.Application Application services and DTOs invoked by controllers.
adas-core.Infrastructure Infrastructure implementations registered in DI (repositories, MongoDB, Redis, messaging).
adas-core.Authentication JWT middleware and authentication abstractions wired into the pipeline.
adas-core.LdapLogin LDAP authentication strategy registered conditionally at startup.
adas-core.LocalLogin Local database authentication strategy registered conditionally at startup.
adas-core.module.LightBeacons Module controllers and services registered in DI.
adas-core.module.ProxyDevices Module controllers and services registered in DI.
adas-core.module.Relays Module controllers and services registered in DI.

Upstream References (projects that depend on this)

Project Reason
adas-core.Test Integration tests exercise the full host pipeline, controllers, and DI container.

Configuration Profiles

The host supports multiple runtime environments via layered appsettings files. The base appsettings.json is always loaded first, then an environment-specific override is merged on top.

Profile File Environment Typical Use
appsettings.Local.json Local Developer workstation
appsettings.Develop.json Develop Shared development server
appsettings.LocalTest.json LocalTest Automated integration tests
appsettings.H12O.json H12O Production site H12O
appsettings.HRYCM.json HRYCM Production site HRYCM
appsettings.HPAZ.json HPAZ Production site HPAZ
appsettings.HPAZBastion.json HPAZBastion Bastion / DMZ instance
appsettings.HUVH-UCIN.json HUVH-UCIN Hospital UVH UCIN ward
appsettings.HUVH-UCIA.json HUVH-UCIA Hospital UVH UCIA ward
appsettings.CHUO.json CHUO CHUO institution
appsettings.CENTRAL_PHILIPS.json CENTRAL_PHILIPS Philips central integration
appsettings.NursePlan.json NursePlan Nurse scheduling module
appsettings.BombasBD.json BombasBD Infusion pump database
appsettings.Auditoria.json Auditoria Audit / compliance instance
appsettings.HGMM.json HGMM HGMM environment

How profiles are resolved

var configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false)
    .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true)
    .Build();

Set the active environment via the ASPNETCORE_ENVIRONMENT variable or a launchSettings.json profile.


Middleware Pipeline

The HTTP pipeline is assembled in Program.cs in the following order:

1. Swagger + SwaggerUI         # API docs (dev/staging)
2. Static Files                # Static assets
3. Authentication              # JWT validation
4. Authorization               # Policy enforcement
5. WebSockets                  # Raw WS support
6. SignalR Hubs                # /subscribe, /chatMessage
7. CORS ("OpenCors")           # Allow any origin/method/header
8. ErrorHandlerMiddleware      # Global exception catching
9. Controllers                 # REST API routes

Global Error Handling

ErrorHandlerMiddleware catches unhandled exceptions, logs them via Serilog, and returns a sanitized problem-details response. No exception leaks to the client in production.

CORS Policy

options.AddPolicy("OpenCors", policy =>
{
    policy.AllowAnyOrigin()
          .AllowAnyMethod()
          .AllowAnyHeader();
});

Security Note: Review and restrict this policy for production deployments.


REST Endpoints

Controllers expose domain-oriented resource groups. Each controller delegates to an Application-layer service and returns DTOs. Key controller families:

Domain Controllers
Patients PatientController, AdmissionController, DischargeController, PatientAppointmentController
Observations ObservationsController, GroupedObservationsController, ConfigObservationController, AlarmController, SensorController
Devices DeviceController, ProxyDeviceController, RelayController, LightBeaconController, CameraController, PumpsController, BoxController
Clinical TreatmentsController, MedicinesController, DiagnosisController, PointOfCareController
System UserController, UnitController, MasterListController, ServiceConfigController, DisplayController, ConfigDisplayController
Messaging RabbitController, SendAlertController, NoticeController
Media RecordingController, RecordingAlertController, QXController
Audit AuditController, ApplicationController

All endpoints require authentication ([Authorize] applied globally via a filter). Swagger UI lists available operations per environment.


WebSocket / SignalR Hubs

Hubs

Hub Route Purpose
UciHub /subscribe Real-time subscription channel for clients
UciHub /chatMessage Bidirectional chat / notification channel

WebSocket Options

var webSocketOptions = new WebSocketOptions
{
    KeepAliveInterval = TimeSpan.FromSeconds(120)
};
app.UseWebSockets(webSocketOptions);

WebSocket Message Service

WebSocketMessageService implements IClientMessageService and handles pushing outbound messages to connected SignalR clients, decoupling domain events from transport concerns.


Swagger & OpenAPI

Swagger is enabled unconditionally:

app.UseSwagger();
app.UseSwaggerUI();

Customizations

  • Newtonsoft.Json serializer registered globally (ReferenceLoopHandling.Ignore, CamelCasePropertyNamesContractResolver, StringEnumConverter, ObjectIdConverter).
  • Schema IDs use fully qualified type names (CustomSchemaIds(type => type.FullName)) to prevent collisions.
  • ObjectId mapping exposed as string with format: objectid.

Access the UI at /swagger/index.html.


Serilog Bootstrap

Serilog is initialized from the Serilog configuration section with fallback to console-only:

builder.Host.UseSerilog((_, loggerConfig) =>
{
    if (configuration.GetSection("Serilog").Exists())
    {
        loggerConfig.ReadFrom.Configuration(configuration, new() { SectionName = "Serilog" });
    }
    else
    {
        loggerConfig.MinimumLevel.Information().WriteTo.Console();
    }

    loggerConfig.Enrich.WithDynamicProperty(
        "TraceIdentifier",
        () => LogExecutionContext.TraceIdentifier);
});

Dynamic Trace Identifier

LogExecutionContext sets a per-request TraceIdentifier (GUID) that flows through all enrichers, enabling end-to-end log correlation across layers and modules.


Build & Run

From CLI

cd adas-core
dotnet run --launch-profile "LOCAL"

Available launch profiles (from Properties/launchSettings.json):

Profile HTTPS HTTP Binding
LOCAL https://localhost:7006 http://localhost:5006 localhost
HPAZ UCIP https://localhost:7006 http://localhost:5006 localhost
HRYCM UCIP https://0.0.0.0:7006 http://0.0.0.0:5006 all interfaces
H12O https://localhost:7006 http://localhost:5006 localhost
HUVH-UCIN https://0.0.0.0:7006 http://0.0.0.0:5006 all interfaces
CHUO https://0.0.0.0:7006 http://0.0.0.0:5006 all interfaces
NursePlan https://0.0.0.0:7006 http://0.0.0.0:5006 all interfaces
BombasBD https://0.0.0.0:7006 http://0.0.0.0:5006 all interfaces
Auditoria https://0.0.0.0:7006 http://0.0.0.0:5006 all interfaces
HUVH-UCIA https://0.0.0.0:7006 http://0.0.0.0:5006 all interfaces
LocalTest https://0.0.0.0:7006 http://0.0.0.0:5006 all interfaces
Develop https://0.0.0.0:7006 http://0.0.0.0:5006 all interfaces
IIS Express IIS Express http://localhost:60532 / SSL 44358
Docker Docker mapped auto-assigned

Docker

docker build -t adas-core:latest .
docker run -p 8080:80 -e ASPNETCORE_ENVIRONMENT=Production adas-core:latest

Design Rules

  1. Thin Controllers — Controllers must only validate input, invoke application services, and return DTOs. No business logic inside controllers.
  2. Global Authorization — The [Authorize] filter is applied globally; anonymous endpoints must be explicitly opted out.
  3. Configuration Over Code — Environment-specific behavior is driven by appsettings profiles, not conditional compilation.
  4. No Circular Dependencies — The Host references all layers but is never referenced by Domain or Application.
  5. Singleton vs Scoped — Repository registrations default to Singleton for stateless MongoDB access; scoped services are used only when per-request state is required (e.g., PumpStateRepository).
  6. Lazy Resolution — Heavy services are wrapped in Lazy<T> to defer instantiation and reduce startup overhead.
  7. Middleware Order Matters — Authentication must precede Authorization; WebSockets must precede SignalR hubs; ErrorHandler must wrap the Controller pipeline.
  8. Sensitive Data Protection — JWT secrets and database connection strings must use User Secrets or environment variables in production; never commit them to source control.

Back to adas-core Root README