SAIF.NetCore.Clients.UC4 architecture¶
SAIF.NetCore.Clients.UC4 is an implementation-layer library (per Architecture.md) that provides a single, thin outbound REST client for scheduling jobs against the UC4/Automic job-scheduling system's "UC4 Core API," wrapping IHttpJsonClient and IEnvironmentClient from SAIF.NetCore.ServiceContracts with no other SAIF package dependency.
Responsibilities¶
- Validate at construction time that the two required
uc4coreapienvironment settings (url,schedulejobroute) exist. - Lazily configure the injected
IHttpJsonClientwith the UC4 Core API base URL and caller-identity headers on the firstScheduleJobcall. - Issue a single outbound POST to the UC4 Core API's schedule-job route, appending the caller-supplied job name to the configured route.
- Return the raw
IHttpRequestResultto the caller unchanged, leaving success/failure interpretation and response parsing to the consumer.
Component boundaries¶
IUC4Client(namespaceSAIF.NetCore.Clients.UC4): the public contract, exposing onlyScheduleJob(string appname, string jobname).UC4Client(namespaceSAIF.NetCore.Clients.UC4.Services): the sole implementation, owning settings validation, lazy client initialization (Init), and the outbound POST.Constants(internal): owns theuc4coreapisetting-group and key names (url,schedulejobroute).- The library has no DI registration extension method; consumers register
IUC4Client/UC4Clientby hand, and no other library in this repository registers it on their behalf*.
Interaction model¶
- A consumer constructs
UC4Client(directly, or via manual DI registration) supplyingIEnvironmentClientandIHttpJsonClient; the constructor eagerly validates the twouc4coreapisettings exist and reads their values, throwingNotSupportedExceptionif either key is missing. - On the first
ScheduleJobcall,UC4Client.Initconfigures the injectedIHttpJsonClientwith the base URL and identity headers (Client-User,Client-Name,Application-ID); this configuration is fixed for the lifetime of theUC4Clientinstance and is not re-applied on later calls, even with a differentappname*. - Each
ScheduleJobcall POSTs an empty JSON object ({}), with no job parameters, to{ScheduleJobEndpoint}{jobname}throughIHttpJsonClient, which applies its own default retry policy (401/502/503, up to 3 retries) before returning the result. IEnvironmentClientandIHttpJsonClientare resolved from the DI container by the consumer; this library has no compile-time dependency on their concrete implementations (SAIF.NetCore.EnvironmentClient,SAIF.NetCore.HttpClients), which the consumer typically obtains viaSAIF.NetCore.ServiceExtensions*.
Architecture diagram¶
The following diagram shows this library's single NuGet dependency on SAIF.NetCore.ServiceContracts, the runtime services a consumer must supply, and the outbound call to the external UC4 Core API.
flowchart TD
SC["SAIF.NetCore.ServiceContracts<br>(IEnvironmentClient, IHttpJsonClient,<br>IHttpRequestResult)"]
UC4["SAIF.NetCore.Clients.UC4<br>IUC4Client / UC4Client"]
ENV["SAIF.NetCore.EnvironmentClient<br>(IEnvironmentClient impl)"]
HTTP["SAIF.NetCore.HttpClients<br>(IHttpJsonClient impl)"]
UC4API["UC4 Core API<br>(external job scheduler)"]
APP["Consuming application"]
UC4 -.->|NuGet ref| SC
APP -->|constructs / resolves| UC4
UC4 -->|DI-resolved by consumer| ENV
UC4 -->|DI-resolved by consumer| HTTP
UC4 -->|POST schedule-job route| UC4API
Sequence diagram¶
The following diagram shows the primary request sequence for scheduling a UC4 job, including the first-call lazy initialization.
sequenceDiagram
participant App as Consuming application
participant UC4Client
participant EnvironmentClient as "IEnvironmentClient"
participant HttpJsonClient as "IHttpJsonClient"
participant UC4API as "UC4 Core API"
App->>UC4Client: new UC4Client(env, httpJsonClient)
UC4Client->>EnvironmentClient: HasSetting / GetSettingValue(uc4coreapi.url, schedulejobroute)
EnvironmentClient-->>UC4Client: ServiceUrl, ScheduleJobEndpoint
App->>UC4Client: ScheduleJob(appname, jobname)
alt first call (IsConfigured == false)
UC4Client->>HttpJsonClient: SetClientInfo(ServiceUrl, ClientName, MachineName, appname)
end
UC4Client->>HttpJsonClient: PostAsync(ScheduleJobEndpoint + jobname, {})
HttpJsonClient->>UC4API: POST schedule-job route
UC4API-->>HttpJsonClient: HTTP response
HttpJsonClient-->>UC4Client: IHttpRequestResult
UC4Client-->>App: IHttpRequestResult
Design constraints¶
- The library takes no NuGet dependency on any other SAIF implementation library — only on
SAIF.NetCore.ServiceContracts— consistent with the repo-wide rule that implementation libraries depend solely on the foundation layer. IsConfiguredhas a public setter; a caller that sets ittruebefore the firstScheduleJobcall skipsInitentirely, which fails later withClientNotInitializedExceptionfromHttpJsonClientunless the injected client was configured elsewhere*.- Client identity (
appname) is fixed from the first successful call for the life of the instance; later calls with a differentappnamesilently reuse the first value (BR-UC4-06). - The schedule-job POST is retried automatically by
HttpJsonClienton 401/502/503 — standardHttpJsonClientdefaults, changeable by a host that callsSetOptions, though UC4 itself never callsSetOptions; whether a retry after an already-accepted job can result in duplicate job submissions depends on whether the UC4 Core API's schedule endpoint is idempotent, which is unknown**. - UC4 itself calls no authentication method (no NTLM, Basic, or bearer token) and does not clear or override the injected
IHttpJsonClient's authenticator;HttpJsonClient.CreateClientassignsclient.Authenticator = _authenticator, preserving whatever authenticator the host configured on that instance —nullif the host configured none, or a working authenticator (demonstrably capable of carrying credentials) if it did. Only informational, caller-asserted headers (Client-Name,Application-ID,Client-User) are added by UC4 itself. - There is no DI registration extension method shipped with this library; registration is entirely manual for every consumer.
Related documentation¶
Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.
Sources¶
src/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4.csprojsrc/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/Constants.cssrc/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/IUC4Client.cssrc/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/Services/UC4Client.cssrc/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/HttpJsonClient/HttpJsonClient.cs— declares the retry policy andCreateClient'sclient.Authenticator = _authenticatorassignment described in Design constraints.src/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/HttpClientOptions.cs— declares the defaultRetryOnStatusCodesset.- Architecture.md