Loading…
Loading…
Replay, reprocess, and manually resolve failed or expired asynchronous API executions. Includes details on previewing changes and forcing completion or
The Asynchronous Execution Replay Service provides administrative functions to manage the lifecycle of individual asynchronous API transaction records. It is designed for operators to diagnose and resolve executions that have entered a failed, expired, or otherwise non-terminal state.
This service allows an operator to:
completed or failed state when automatic processing is not possible or desired.waiting_callback state, giving it a new expiry window to receive a callback.The service operates on s2r_async_execution records identified by their unique id. It interacts with the operation's configured response mappings and transformation rules to process SOAP payloads into final JSON results.
The service provides several distinct functions for manipulating an asynchronous execution record. The core logic for re-evaluation is centralized in a replay evaluation process.
When an operator initiates a replay or reprocess action, the service performs the following steps:
Load Execution: It fetches the target s2r_async_execution record from the database using its asyncExecutionId.
Evaluate Replay: It uses the SOAP callback payload associated with the execution (either the one stored previously or one provided in the request) to simulate the callback processing.
flowchart TD
subgraph Replay Evaluation
A[Load Mappings and Rules] --> B{Parse SOAP Payload};
B -- Success --> C[Apply Response Transformations];
B -- SOAP Fault --> D[Create 'fault' Outcome];
B -- Parse Error --> E[Create 'parse_error' Outcome];
C --> F[Compare with Stored Result];
F --> G[Create 'completed' Outcome];
end
Start(Start Replay/Reprocess) --> L[Load Async Execution Record];
L --> P{Has Callback Payload?};
P -- Yes --> A;
P -- No --> X1[Throw Exception];
subgraph Final Outcome
D --> Z;
E --> Z;
G --> Z;
end
Z --> Y{Persist Changes?};
Y -- Yes --> U[Update Database Record];
Y -- No (Preview) --> R[Build Response];
U --> R;
R --> Stop(End);OperationMappingRecord and transformation RuleSet for the operation.parse_error outcome.fault outcome.PayloadTransformService to produce the final JSON result. This generates a completed outcome. The new result is compared to the previously stored result to determine if anything has changed.Persistence (Reprocessing only): For reprocess actions, the outcome of the evaluation is persisted. The s2r_async_execution record is updated:
completed, the status is set to completed and the new JSON result is stored in callback_response_payload.fault, the status is set to failed, the fault details are stored in callback_response_payload, and failure_message is updated.parse_error, the status is set to failed and failure_message is updated with the parsing error.Response: A detailed JSON object is returned, describing the original state, the replay outcome, the new state (if persisted), and any generated errors or messages.
For completeManually and failManually, the service bypasses the replay evaluation. It directly executes a SQL UPDATE statement on the s2r_async_execution record to set the status to completed or failed and records the provided JSON result or failure message.
The reopenAwaitingCallback function resets a non-completed execution. It updates the record's status to waiting_callback, clears all previous callback and result data, and calculates a new expires_at timestamp. The new expiry window is determined by the duration between the original created_at and expires_at timestamps. If that cannot be calculated, it uses the system setting default_retention_days.
WARNING
An execution that is already in a completed state cannot be reopened. Attempting to do so will result in an IllegalStateException.
The AsyncExecutionReplayService exposes the following methods for administrative clients.
Previews the reprocessing of the stored callback for an async execution without persisting any changes.
| Parameter | Type | Required | Description |
|---|---|---|---|
asyncExecutionId | UUID | Yes | The unique identifier of the async execution. |
Returns: A Map<String, Object> containing the replay analysis. The persisted field will be absent. See Response Body Structure for details.
Reprocesses the stored callback for an async execution using the current mappings and rules, then persists the result.
| Parameter | Type | Required | Description |
|---|---|---|---|
asyncExecutionId | UUID | Yes | The unique identifier of the async execution. |
Returns: A Map<String, Object> containing the replay analysis and final state. The persisted field will be true. See Response Body Structure for details.
Previews the reprocessing of an async execution using a provided SOAP payload, without persisting any changes.
| Parameter | Type | Required | Description |
|---|---|---|---|
asyncExecutionId | UUID | Yes | The unique identifier of the async execution. |
callbackSoapPayload | String | Yes | The full XML SOAP payload to use for the replay. |
Returns: A Map<String, Object> containing the replay analysis. The persisted field will be absent. See Response Body Structure for details.
Reprocesses an async execution using a provided SOAP payload and persists the result. The provided payload will be stored in the record.
| Parameter | Type | Required | Description |
|---|---|---|---|
asyncExecutionId | UUID | Yes | The unique identifier of the async execution. |
callbackSoapPayload | String | Yes | The full XML SOAP payload to use for the replay. |
Returns: A Map<String, Object> containing the replay analysis and final state. The persisted field will be true. See Response Body Structure for details.
Forces an async execution into the completed state with a provided JSON result.
| Parameter | Type | Required | Description |
|---|---|---|---|
asyncExecutionId | UUID | Yes | The unique identifier of the async execution. |
resultJson | String | Yes | A valid JSON string to store as the callback_response_payload. |
Returns: A Map<String, Object> confirming the manual resolution. See Manual Resolution Response Structure for details.
Forces an async execution into the failed state with a provided reason.
| Parameter | Type | Required | Description |
|---|---|---|---|
asyncExecutionId | UUID | Yes | The unique identifier of the async execution. |
failureReason | String | Yes | A text message to store as the failure_message. |
Returns: A Map<String, Object> confirming the manual resolution. See Manual Resolution Response Structure for details.
Resets a failed or expired async execution to the waiting_callback state, clearing previous callback data and setting a new expiry date.
| Parameter | Type | Required | Description |
|---|---|---|---|
asyncExecutionId | UUID | Yes | The unique identifier of the async execution. |
Returns: A Map<String, Object> confirming the execution has been reopened. See Reopen Response Structure for details.
Methods like replayPreview and reprocessStoredCallback return a map with the following structure. The exact fields depend on the replayStatus.
{
"id": "...",
"correlationId": "...",
"environment": "...",
"serviceKey": "...",
"operationKey": "...",
"executionStatus": "completed",
"mappingVersion": 1,
"callbackReceivedAt": "...",
"completedAt": "...",
"expiresAt": "...",
"failureMessage": null,
"storedResult": { "key": "value" },
"generatedAt": "...",
"replayStatus": "completed",
"storedResultChanged": false,
"persisted": true, // Only if reprocessed
"storedResultBefore": { "key": "value" }, // Only if reprocessed
"replayResult": { "key": "value" }, // If replayStatus is 'completed'
"replayFaultPayload": { "fault": "details" }, // If replayStatus is 'fault'
"replayError": "Error details...", // If replayStatus is 'parse_error'
"replayMessage": "Replay result matches the stored callback result."
}
The completeManually and failManually methods return a map with the following structure.
{
"id": "...",
"correlationId": "...",
"environment": "...",
"serviceKey": "...",
"operationKey": "...",
"executionStatus": "completed",
"callbackReceivedAt": "...",
"completedAt": "...",
"expiresAt": "...",
"failureMessage": null,
"storedResult": { "final": "result" },
"resolutionStatus": "completed",
"resolutionMessage": "Async execution was completed manually with the provided JSON result.",
"generatedAt": "..."
}
The reopenAwaitingCallback method returns a map with the following structure.
{
"id": "...",
"correlationId": "...",
"environment": "...",
"serviceKey": "...",
"operationKey": "...",
"executionStatus": "waiting_callback",
"statusBefore": "failed",
"callbackReceivedAt": null,
"completedAt": null,
"expiresAt": "...", // New expiry timestamp
"storedResult": null,
"resolutionStatus": "reopened",
"resolutionMessage": "Async execution is waiting for callback again with a refreshed expiry window.",
"generatedAt": "..."
}
The service uses the following system setting.
| Name | Type | Default | Description |
|---|---|---|---|
default_retention_days | Integer | 60 | When reopening an execution with reopenAwaitingCallback, this value is used to set the new expiry window if the original window cannot be determined from the record's timestamps. The effective value used will be at least 1. |
| Condition / Error | Trigger |
|---|---|
IllegalArgumentException: async execution not found | The provided asyncExecutionId does not exist in the database or is not accessible within the caller's tenant scope. |
IllegalArgumentException: ... is required | A required parameter (callbackSoapPayload, resultJson, failureReason) was null or blank. |
IllegalArgumentException: manual result must be valid JSON | The resultJson string provided to completeManually was not valid JSON. |
IllegalStateException: no callback SOAP payload is stored for this execution | A replay or reprocess action was attempted on an execution that has no callback_soap_payload stored. Provide a payload or use a different resolution method. |
IllegalStateException: no active response mapping exists for this execution | The operation associated with the execution does not have a currently active response mapping, preventing the service from processing the SOAP payload. |
IllegalStateException: completed async executions cannot be reopened | An attempt was made to call reopenAwaitingCallback on an execution that is already in the completed status. |
IllegalStateException: async execution is already waiting for callback | An attempt was made to call reopenAwaitingCallback on an execution that is already in the waiting_callback status. |
replayStatus: 'parse_error' | The SOAP payload could not be parsed with the current operation mapping. The replayError field in the response contains details. |
replayStatus: 'fault' | The SOAP payload was parsed successfully but resolved to a SOAP Fault. The replayFaultPayload field contains the extracted fault details. |
executionStatus: 'expired' | This is a derived status. If a record's status is waiting_callback but its expires_at timestamp is in the past, it is considered expired. |