This page captures business rules enforced by this library.
BR-DBC-01 Configuration keys source the service URL and endpoint segments¶
Field
Value
Statement
The service URL and the three endpoint path segments come from configuration section DBConnectionClient (keys ServiceUrl, SqlConnectionEndpoint, PostgreSqlConnectionEndpoint, OracleConnectionEndpoint).
Trigger
Construction
Enforcement
ConnectionClient.Setup reads all four keys through IEnvironmentClient.GetSettingValue; keys are declared in ConnectionClientKeys.
Outcome
Values are stored in protected properties (ServiceUrl, SqlEndpoint, PostgreSqlEndpoint, OracleEndpoint) used by every subsequent request.
BR-DBC-03 NTLM authentication, defaulting to process identity¶
Field
Value
Statement
Calls to the DBConnectionAPI authenticate with NTLM — current process identity by default, replaced by explicit service-account credentials when SetupClientCredentials is called.
PostgreSQL server/host is not managed by the API: lookup uses only instance and user, and the returned template's {SERVER} placeholder is replaced by the caller-supplied server.
Trigger
GetPostgreSqlServerConnection
Enforcement
ConnectionClient.GetPostgreSqlServerConnection omits server from the cache key and URL path, then substitutes {SERVER} in the retrieved template.
Outcome
The host is injected client-side; the template is cached host-independent, so different hosts sharing instance and user reuse one fetch.
BR-DBC-06 Successful retrievals are cached for instance lifetime; failures are not¶
Field
Value
Statement
A successfully retrieved connection string is cached for the life of the instance and never refreshed; failed retrievals are not cached; cache access is serialized.
Trigger
Any Get*Connection call
Enforcement
ConnectionClient.GetCachedConnectionString adds to the cache only after a successful retrieval, under lock(_connections).
Outcome
One fetch per key per instance; refreshing a cached value requires replacing the ConnectionClient instance — restarting the usual singleton-hosted process is the typical way to do this. Rotating the outbound service-account credential (dbconnectionclient:connectionservicecreds) does not by itself clear the cache, because that credential only affects the NTLM identity presented on the next uncached request.*
At most MaxRetrieveAttempts (default 4) of this client's own outer attempts are made, with backoff 2s → 3s → 5s between transient failures (maximum ~10 s of outer waiting). This is not an end-to-end bound: with the standard registered IHttpJsonClient transport, each outer attempt can itself make up to four inner HTTP requests with up to three additional 1-second inner sleeps, so total attempts, waiting, and elapsed time can exceed these outer figures. See Retrieve with retry.
Trigger
Transient failure
Enforcement
ConnectionClient.RetrieveConnectionString loops up to MaxRetrieveAttempts, using _defaultRetrieveBackoffDelays.
Outcome
Retry, then throw the last transient DBClientException with an "(attempt n/N)" annotation.
HTTP 401, 404, and 403 are permanent for this client's own outer loop: the request fails immediately without an outer retry, even if ErrorException is set. This outer fail-fast behavior does not guarantee that the server received only one authentication attempt — with the standard registered IHttpJsonClient transport, a 401 is also one of its default inner-retry status codes, so the same credentials can already have been re-presented up to three additional times before this outer check ever observes the result.
Trigger
Non-success response
Enforcement
ConnectionClient.RetrieveConnectionString checks these statuses before the transient-failure test.
Outcome
DBClientException is thrown ("denied access" / "not found" with service message / "access denied").
BR-DBC-11 Other failures and empty bodies fail immediately¶
Field
Value
Statement
Any other non-success status (for example, 500 without an exception) and a successful-but-empty body fail immediately.
Trigger
Response
Enforcement
ConnectionClient.RetrieveConnectionString throws without retry for these cases.
Outcome
DBClientException is thrown ("Failed to retrieve database connection string: {connectionName} (attempt {attempt}/{MaxRetrieveAttempts})", with ". Service Error Message: {ErrorMessage}" appended when present, for the non-success case; "Database connection string is null: {connectionName} (attempt {attempt}/{MaxRetrieveAttempts})" for the empty-body case).
Note: Statements marked with * were inferred from code structure, naming
conventions, or contextual evidence where direct confirmation was not available
in source artifacts.