Skip to content

Architecture

DBConnectionAPI is a small ASP.NET Core REST API with a thin layering: two controllers delegate to a single singleton service, ConnectionManager, which composes database connection strings from templates and secure settings held in the SAIF Environment API, validates Oracle and SQL Server strings with a throw-away NHibernate connectivity probe, and caches the validated strings in process memory. The service has no entities, repositories, DTO classes or minimal-API endpoints. Host model and middleware order are documented on the hosting pipeline page.

Aspect Finding
Target framework net10.0
Host model Generic host with UseStartup<Startup>() — see Hosting pipeline
Startup type Startup : CoreAPIStartup (DBConnectionAPI/DBConnectionAPI/Startup.cs)

Layer architecture

flowchart TD
    CLIENT["Client request"] --> PIPE["Middleware pipeline<br/>see hosting-pipeline.md"]
    PIPE --> AUTH["Authorization attribute<br/>SecurityApiAuthorize on both controllers"]
    AUTH --> CTRL["ConnectionsController and AdminController<br/>ControllerBase"]
    CTRL --> SVC["Service layer<br/>IConnectionManager / ConnectionManager singleton"]
    SVC --> ENV["Environment client<br/>IEnvironmentClient templates and secure settings"]
    SVC --> NH["Data access<br/>IUnitOfWorkFactory connectivity probes"]
    NH --> DB["Caller-named Oracle or SQL Server database"]
    CTRL --> ERR["Error handling<br/>ConnectionManagerException handled by package middleware"]

Layer responsibilities

Layer Type Responsibility
Program.cs Host entry point Builds and runs the generic host, adds ConfigureOpenTelemetry, and invokes Startup through UseStartup<Startup>()
Startup CoreAPIStartup subclass Service registration (ConfigureServices) and pipeline composition (Configure)
ConnectionsController ControllerBase Three GET endpoints that return composed connection strings; writes an audit log entry per request using IIdentityServiceAccessor
AdminController ControllerBase Three POST endpoints that return the raw credential parts and composed connection string, without probe or cache
ConnectionManager Singleton service (IConnectionManager) Cache, key generation, template formatting, credential retrieval, probe with retry, and error mapping
ConnectionManagerException HttpStatusCodeException subclass Carries the HTTP status code (400, 404 or 500) and application/json content type
EnvironmentKeys Static class Environment API group name and template key names
IUnitOfWorkFactory SAIF.NetCore.NHibernate package type† Opens a unit of work for each probe; the API defines no entities, mappings or repositories

Routing configuration

Aspect Finding
Controller registration Not visible in source; performed inside the opaque base.ConfigureServices call†
Endpoint mapping Inside opaque base.Configure (not visible in source); the package documentation lists UseEndpoints(MapControllers)†
Route template style Literal v1 path segment: v1/Connections and v1/Admin plus the action name, each a class-level [Route] template with a controller-name token
Versioning None. No versioning package or [ApiVersion] attribute exists; v1 is a fixed path segment
Controller folder layout DBConnectionAPI/DBConnectionAPI/Controllers/ (two controllers)

Base controller

Both controllers derive from ControllerBase and carry [ApiController]. Neither derives from a local or SAIF base class, so no inherited behavior is added beyond the framework defaults. [ApiController] enables automatic 400 responses for invalid model state; whether the opaque base suppresses that behavior is not visible in source.**

Controller Base [ApiController] Inherited behavior
ConnectionsController ControllerBase Yes —
AdminController ControllerBase Yes —

Composition root

Field Value
Project DBConnectionAPI
File DBConnectionAPI/DBConnectionAPI/Startup.cs
Entry method Startup.ConfigureServices(IServiceCollection)
Invoked from UseStartup<Startup>() in DBConnectionAPI/DBConnectionAPI/Program.cs
Base-class registrations base.ConfigureServices(services) — CoreAPIStartup (SAIF.NetCore.ServiceExtensions 10.2026.26267.1), not visible in source
Additional registration files None

The registration evidence is ConfigureServices(IServiceCollection), AddSingleton<IConnectionManager, ConnectionManager>(), AddNhibernateServices<Startup>() and AddSwaggerGen(options), all in Startup.cs. No IServiceCollection extension class, builder.Services, AddHttpClient, AddDbContext, ConfigureOptions<T>, AddHostedService<T> or AddPingable* registration exists elsewhere in the project. Program.cs reaches Startup through UseStartup<Startup>(), which confirms it is the root the running service uses.

The Startup constructor calls EnableSecureEnvironmentClient<Startup>(). ConfigureServices calls base.ConfigureServices(services) first, so opaque package registrations precede the local ones. EnableNewtonsoftJsonSerializer and DisableAuthServices are not set.

Service type Implementation Lifetime Registered in Resolved by Purpose
IConnectionManager ConnectionManager Singleton (holds a process-wide connection cache guarded by a lock) DBConnectionAPI/DBConnectionAPI/Startup.cs ConnectionsController, AdminController Connection-string composition, validation and caching
IUnitOfWorkFactory and UnitOfWorkAccessor Registered by AddNhibernateServices<Startup>() Singleton and scoped respectively† DBConnectionAPI/DBConnectionAPI/Startup.cs ConnectionManager Opens units of work for connectivity probes
Swagger generator services AddSwaggerGen(options) Framework-managed DBConnectionAPI/DBConnectionAPI/Startup.cs Swagger middleware OpenAPI document v1
IEnvironmentClient, ISystemHashService, ISaifLogService, IIdentityServiceAccessor, IDBConnectionClient — — registered by SAIF.NetCore.ServiceExtensions (not visible in source) ConnectionManager, AdminController, ConnectionsController Environment settings, secure-setting hashing, logging and identity; IDBConnectionClient is registered by the base† but this API does not resolve it

Options binding

The service binds no options through the options pattern. No Configure<T>, AddOptions<T>, IConfigureOptions<T> or IConfiguration usage exists in source. Settings reach ConnectionManager through IEnvironmentClient calls, documented on the configuration page.

Options type Binding Configuration source Consumer
UnitOfWorkOptions (SAIF.NetCore.NHibernate) Inline object initializer per probe, not registered Composed connection string ConnectionManager.TestOracleConnection, ConnectionManager.TestSqlConnection
SwaggerGenOptions AddSwaggerGen lambda Constants and AppContext.BaseDirectory Swagger generator

Error handling

Mechanism Registered in Scope Behavior
Typed ConnectionManagerException : HttpStatusCodeException handled by package middleware DynamicErrorHandler† Thrown in DBConnectionAPI/DBConnectionAPI/Services/ConnectionManager.cs; handler registered inside the opaque base Three Connections endpoints Missing secure setting yields 404; Oracle TNS alias errors yield 400; every other probe failure yields 500. The exception message is returned; the exact envelope is written by the package†
Local try/catch in AdminController.GetConnectionInfo DBConnectionAPI/DBConnectionAPI/Controllers/AdminController.cs Per-action (three Admin endpoints) A failed credential split is swallowed; the action returns 200 with an Error entry in the dictionary
[ApiController] automatic model-state 400 Framework All actions ValidationProblemDetails; no validation rule exists that would trigger it for string parameters*
Retry-internal try/catch DBConnectionAPI/DBConnectionAPI/Services/ConnectionManager.cs Probe loop Logs each failure through ISaifLogService, retries or fails fast, then rethrows a mapped ConnectionManagerException

No UseExceptionHandler, AddProblemDetails, IExceptionHandler, exception filter or global filter exists in source. When an exception other than HttpStatusCodeException escapes (for example a credential value without a pipe separator), the resulting response is produced by opaque package middleware and its status is not visible in source.** Messages on 400 and 500 responses expose the cache key parts, the secure-setting key name, the Environment API track name and, for some failures, the raw provider message, so exception detail crosses the service boundary.

Serialization

Aspect Finding
Serializer Decided inside the opaque base; EnableNewtonsoftJsonSerializer is not set, so System.Text.Json is the framework default*
Configured in No AddJsonOptions or AddNewtonsoftJson call in source
Converters and settings Framework defaults; Connections actions return string, Admin actions return Dictionary<string,string>

Design constraints

  • The connection cache is a process-lifetime dictionary inside a singleton and is never evicted, so credential rotation takes effect only after the process restarts.
  • Responses carry credential material by design: connection strings from the Connections endpoints, and raw credentials plus plaintext password from the Admin endpoints.
  • The API resolves no connection for its own use; it composes strings for callers and probes only Oracle and SQL Server. PostgreSQL strings are not probed.
  • Authentication, authorization middleware, exception handling and endpoint mapping run inside the opaque base.Configure call, so their order is not visible in source.

Integration points

System Type Purpose
SAIF Environment API Downstream API (through IEnvironmentClient) Connection templates and secure credentials in group dbconnectionapi†
Security API Downstream API (through SecurityApiAuthorize) Resource authorization for DBConnAPIRetrieveResource†
Oracle and SQL Server databases named by the caller Database Read-only connectivity probes

Note: Statements marked with † are derived from dependency library documentation via the Legends CLI. Statements marked with * were inferred from code structure or contextual evidence. Statements marked with ** could not be confirmed; treat as unknown until verified.

Sources

  • DBConnectionAPI/DBConnectionAPI/Program.cs
  • DBConnectionAPI/DBConnectionAPI/Startup.cs
  • DBConnectionAPI/DBConnectionAPI/DBConnectionAPI.csproj
  • DBConnectionAPI/DBConnectionAPI/Controllers/ConnectionsController.cs
  • DBConnectionAPI/DBConnectionAPI/Controllers/AdminController.cs
  • DBConnectionAPI/DBConnectionAPI/Services/IConnectionManager.cs
  • DBConnectionAPI/DBConnectionAPI/Services/ConnectionManager.cs
  • DBConnectionAPI/DBConnectionAPI/Exceptions/ConnectionManagerException.cs
  • DBConnectionAPI/DBConnectionAPI/EnvironmentKeys.cs