Schedule a UC4 job¶
This operation starts a named UC4/Automic job. On the first call for a given UC4Client instance it also performs lazy, one-time initialization of the injected IHttpJsonClient with caller-identity information.
| Field | Value |
|---|---|
| Operation ID | OP-UC4-02 |
| Trigger | Consumer calls await client.ScheduleJob(appname, jobname) |
| Inputs | appname — the calling application's ID, sent as the Application-ID header. jobname — the UC4 job name, appended to the configured route. |
| Outputs | Task<IHttpRequestResult>, the raw HTTP result; the caller must inspect IsSuccessful, StatusCode, and ErrorMessage. |
| Primary components | UC4Client.ScheduleJob, UC4Client.Init |
| Entry point | src/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/Services/UC4Client.cs |
Steps¶
- If
IsConfiguredisfalse, runInit(appname); otherwise skip to step 3 (BR-UC4-06, BR-UC4-07). - Not thread-safe (no lock); concurrent first calls may both run
Init*. Init: call_httpJsonClient.SetClientInfo(ServiceUrl, ClientName, Environment.MachineName, appName), then setIsConfigured = true(BR-UC4-03, BR-UC4-04, BR-UC4-05).- Delegates to
SAIF.NetCore.HttpClients'sHttpJsonClient.SetClientInfo(baseUrl, userName, machineName, applicationId): constructsClientInfo(machineName, applicationId, userName)(throwsArgumentNullExceptionif any argument is null) and sets_baseUri = new Uri(baseUrl). - On failure: a null
appnamethrowsArgumentNullExceptionfromClientInfo; an empty or malformedServiceUrlthrowsUriFormatException. In both casesIsConfiguredstaysfalse, so the next call retriesInit.
Origin: Step 2 is implemented in
Initialize client(SAIF.NetCore.HttpClients) and executed on behalf of this operation. 3. POST to$"{ScheduleJobEndpoint}{jobname}"with an empty JSON object ({}), with no job parameters (BR-UC4-03, BR-UC4-08, BR-UC4-09). - Delegates toHttpJsonClient.PostAsync(urlPart, body)→ExecuteAsync(urlPart, Method.POST, body, retries: 3): -ValidateInitialization, which throwsClientNotInitializedExceptionif_clientInfoor_baseUriis null. -CreateClient, which sets the base URI and assignsclient.Authenticator = _authenticator— the authenticator already held by the injectedIHttpJsonClientinstance, not a value UC4 itself sets or clears — plus the serializer and the timeout override (none for UC4). UC4 never callsSetNtlmAuthentication/SetBasicAuthenticationor setsBearerToken, so the authenticator is whatever the host configured on the injected client:nullif the host configured none, or a working authenticator (demonstrably capable of carrying credentials) if it did. -CreateRequest, which adds the JSON body and the headersClient-Name= machine name,Application-ID= appname, andClient-User="SAIF.NetCore.Clients.UC4", plusAuthorizationonly ifBearerTokenis set (never set by UC4), plus any customHeaders, which are then cleared. - Runs the request synchronously insideTask.Run; if the status is inRetryOnStatusCodes(default 401, 502, 503), sleepsRetryDelayInMs(default 1000 ms) and retries, up to 3 retries. These are standardHttpJsonClientdefaults, changeable by a host that callsSetOptions, even though UC4 itself never callsSetOptionsand never overrides them. - BuildsHttpRequestResult(populates headers, and on failure populatesErrorMessagefromerrormessage/exceptionmessage/messageJSON tokens or the raw content), stores it inRequestResult, and returns it.Origin: The sub-steps above are implemented in
HttpJsonClient(SAIF.NetCore.HttpClients) — see Execute request — and executed on behalf of this operation. - On failure: non-success HTTP status codes are not thrown; they are returned inIHttpRequestResult(IsSuccessful = false). Network failures surface asErrorExceptionorErrorMessageon the result*. 4. Return theIHttpRequestResultto the caller unchanged (BR-UC4-09). - No interpretation of the response body; the UC4 run ID or any response payload is left for the caller to read withGetResult<T>()orContent.
Process flow¶
flowchart TD
Start([Caller invokes ScheduleJob]) --> D1{IsConfigured?}
D1 -->|No| Init["Init: SetClientInfo"]
D1 -->|Yes| Post
Init --> InitOk{Init succeeded?}
InitOk -->|No| ErrInit([ArgumentNullException / UriFormatException])
InitOk -->|Yes| Post["POST empty JSON object {} to route+jobname"]
Post --> Retry{Status in 401/502/503<br>and retries remaining?}
Retry -->|Yes| Post
Retry -->|No| Result([Return IHttpRequestResult to caller])
Failure and edge-case behavior¶
- A null
appnameon the first call:ArgumentNullExceptionfromClientInfo;IsConfiguredremainsfalse, so the next call retriesInit. - An externally-set
IsConfigured = truebefore the first call:Initis skipped and the POST fails withClientNotInitializedExceptionunless the injected client was configured elsewhere. - A 502/503 response after the UC4 API has already accepted the job: the automatic retry can submit a duplicate job if the UC4 Core API's schedule endpoint is not idempotent, which is unknown**.
- Any non-success response: returned as
IHttpRequestResult.IsSuccessful = false, never thrown.
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/Services/UC4Client.cssrc/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/HttpJsonClient/HttpJsonClient.cs— declaresSetClientInfo,PostAsync/ExecuteAsync,ValidateInitialization,CreateClient, andCreateRequest, the delegated behavior described in steps 2–3.src/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/ClientInfo.cs— declares the constructor that throwsArgumentNullExceptionfor a nullappname.src/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/HttpClientOptions.cs— declares theRetryOnStatusCodes/RetryDelayInMsdefaults applied in step 3.