orbit-code-ai 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,117 @@
1
+ # Error Handling
2
+
3
+ Central error handling is provided by `ErrorHandler.subflow` + `ErrorHandler.esql`. Every flow MUST wire its exception terminal to the error handler.
4
+
5
+ ---
6
+
7
+ ## ErrorHandler.subflow
8
+
9
+ **Purpose**: Catches all exceptions, builds a standardized error response, logs it, and routes to dead-letter or returns a business error.
10
+
11
+ **Internal flow**:
12
+ ```
13
+ Exception caught
14
+
15
+ ErrorHandler.esql (build error structure)
16
+
17
+ ErrorHandler_IsExceptionCaught.esql (filter: already handled?)
18
+
19
+ LogError subflow (audit the error)
20
+
21
+ [Route based on adapter type]
22
+ ├── MQ_Dead_Output_Node (async flows)
23
+ └── MWBusinessErrorResponse (sync/HTTP flows)
24
+ ```
25
+
26
+ **ESQL modules**:
27
+ | Module | Purpose |
28
+ |---|---|
29
+ | `ErrorHandler.esql` | Main: 43KB — builds error structure, maps error codes per backend |
30
+ | `ErrorPoint.esql` | Create error message structure from exception |
31
+ | `ErrorHandler_IsExceptionCaught.esql` | Filter: prevent double-handling |
32
+ | `ErrorHandler_SetExceptionCaught.esql` | Mark exception as handled |
33
+ | `ErrorHandler_IsFileSchemaValidationOccured.esql` | Detect file schema validation errors |
34
+ | `ErrorHandler_PrepareFileDataForAudit.esql` | Prepare file error data for audit |
35
+ | `ESBBusinessErrorResponse.esql` | Build ESB-standard business error response |
36
+
37
+ ---
38
+
39
+ ## MWBusinessErrorResponse.subflow
40
+
41
+ **Purpose**: Returns a structured business error response to the caller (used in sync/HTTP flows).
42
+
43
+ **When to use**: REST/HTTP flows where the caller expects a JSON error response.
44
+
45
+ **Response structure**:
46
+ ```xml
47
+ <ResponseStatus>
48
+ <Code>XXXXXXXX</Code>
49
+ <Status>Error</Status>
50
+ <EnglishMsg>Human readable message</EnglishMsg>
51
+ </ResponseStatus>
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Error Codes by Backend System
57
+
58
+ Defined as constants in `CommonUtils.esql`:
59
+
60
+ | Constant | Value | Backend |
61
+ |---|---|---|
62
+ | `ESB_SUCCESS_RESPONSE_CODE` | `'00000000'` | All |
63
+ | `ESB_RUNTIME_TECHNICAL_ERROR_CODE` | `'99999999'` | All (generic) |
64
+ | `ESB_MIDDLEWARE_DATABASE_ERROR_RESPONSE_CODE` | `'E0199998'` | DB errors |
65
+
66
+ Additional backend-specific codes exist for:
67
+ - **T24**: Core banking errors
68
+ - **NIWS**: National Information and Workflow System
69
+ - **ODM**: Operational Decision Manager
70
+ - **Unifonic**: SMS/notification service
71
+ - **MLSD**: Ministry of Labor and Social Development
72
+ - **ICBS**: Core banking system
73
+
74
+ Read `ErrorHandler.esql` directly for the full mapping if you need specific codes.
75
+
76
+ ---
77
+
78
+ ## Wiring the Error Handler in a New Flow
79
+
80
+ Every node that can fail must connect its **failure/exception terminal** to `ErrorHandler`:
81
+
82
+ ```
83
+ [Any Node]
84
+ │ failure terminal
85
+
86
+ ErrorHandler.subflow
87
+
88
+ ├──[MQ flow]──→ MQ_Dead_Output_Node
89
+ └──[HTTP flow]─→ MWBusinessErrorResponse
90
+ ```
91
+
92
+ **ESQL DECLARE for ErrorHandler behavior**:
93
+ ```esql
94
+ -- Set which backend adapter this flow uses (controls error code mapping)
95
+ DECLARE IsT24Adapter EXTERNAL BOOLEAN FALSE;
96
+ DECLARE IsODMWSAdapter EXTERNAL BOOLEAN FALSE;
97
+ DECLARE IsFrontEndJSONAdapter EXTERNAL BOOLEAN FALSE;
98
+ DECLARE IsNIWSAdapter EXTERNAL BOOLEAN FALSE;
99
+ DECLARE IsUniFonicAdapter EXTERNAL BOOLEAN FALSE;
100
+ DECLARE IsMLSDAdapter EXTERNAL BOOLEAN FALSE;
101
+ DECLARE IsICBSAdapter EXTERNAL BOOLEAN FALSE;
102
+ ```
103
+
104
+ Set the appropriate flag to `TRUE` at the node level to get correct error codes for that backend.
105
+
106
+ ---
107
+
108
+ ## ErrorPoint Usage
109
+
110
+ Use `ErrorPoint.esql` when you need to manually create an error structure (e.g., business validation failure before calling a backend):
111
+
112
+ ```esql
113
+ -- Set error details on the Environment before routing to ErrorHandler
114
+ SET Environment.ErrorDetails.Code = 'XXXXXXXX';
115
+ SET Environment.ErrorDetails.EnglishMsg = 'Validation failed: ...';
116
+ -- Then propagate to ErrorHandler via failure terminal
117
+ ```
@@ -0,0 +1,134 @@
1
+ # HTTP Adapters & Internal Service Caller
2
+
3
+ Used for outbound HTTP calls (to backends or internal services) and for chaining ACE flows together.
4
+
5
+ ---
6
+
7
+ ## HTTPRequestAdapter.subflow
8
+
9
+ **Purpose**: Makes an outbound HTTP or SOAP call to an external backend system.
10
+
11
+ **Supported backends**: T24, NIWS, ODM, Unifonic, MLSD, ICBS, and any REST/SOAP service.
12
+
13
+ **ESQL helpers**:
14
+ | Module | Purpose |
15
+ |---|---|
16
+ | `HTTPResponseAdapter_CheckCallType.esql` | Determine INTERNAL vs EXTERNAL call |
17
+ | `InternalHTTPRequestAdapter_Remove_MQRFH2.esql` | Strip MQRFH2 headers before HTTP call |
18
+
19
+ **ESQL DECLARE flags** (set at node level):
20
+ ```esql
21
+ DECLARE IsT24Adapter EXTERNAL BOOLEAN FALSE;
22
+ DECLARE IsODMWSAdapter EXTERNAL BOOLEAN FALSE;
23
+ DECLARE IsFrontEndJSONAdapter EXTERNAL BOOLEAN FALSE;
24
+ DECLARE IsNIWSAdapter EXTERNAL BOOLEAN FALSE;
25
+ DECLARE IsUniFonicAdapter EXTERNAL BOOLEAN FALSE;
26
+ DECLARE IsMLSDAdapter EXTERNAL BOOLEAN FALSE;
27
+ DECLARE IsICBSAdapter EXTERNAL BOOLEAN FALSE;
28
+ ```
29
+
30
+ Set exactly ONE of these to `TRUE` to get correct request formatting and error code mapping for that backend.
31
+
32
+ **URL/endpoint**: Set in `Environment.Destination.HTTP.RequestURL` before calling this subflow, or configure in `BankIdForRoutingService` properties group.
33
+
34
+ ---
35
+
36
+ ## HTTPResponseAdapter.subflow
37
+
38
+ **Purpose**: Processes the HTTP response from a backend call, normalizes it to the standard ESB response structure.
39
+
40
+ **ESQL helper**: `HTTPResponseAdapter_CheckCallType.esql`
41
+ - Routes differently based on whether it was an `INTERNAL` or `EXTERNAL` call
42
+
43
+ **Always pair with** `HTTPRequestAdapter` — use both or neither.
44
+
45
+ ---
46
+
47
+ ## InternalServiceCaller.subflow
48
+
49
+ **Purpose**: Calls another ACE message flow in the same broker (service-to-service chaining without going through HTTP).
50
+
51
+ **ESQL modules**:
52
+ | Module | Purpose |
53
+ |---|---|
54
+ | `InternalServiceCaller_Compute.esql` | Build the internal call message |
55
+ | `InternalServiceCaller_Filter.esql` | Route based on call success/failure |
56
+
57
+ **Configuration** (from `Variables` group in Properties):
58
+ ```xml
59
+ <group name="Variables">
60
+ <property name="callCorrIDOffset" value="1" />
61
+ </group>
62
+ ```
63
+
64
+ `callCorrIDOffset`: Offset added to correlation ID to uniquely identify this leg of the flow chain.
65
+
66
+ **When to use**: When this flow needs to call another ESB service internally, without the overhead of an HTTP round-trip.
67
+
68
+ ---
69
+
70
+ ## HTTPInternalCaller.subflow
71
+
72
+ **Purpose**: Calls an internal ACE service via HTTP (when the service is exposed as a REST endpoint).
73
+
74
+ **When to use**: Internal HTTP calls where the target flow is REST-exposed. Prefer `InternalServiceCaller` for non-HTTP internal calls.
75
+
76
+ **ESQL module**: `Internal_HTTP_CheckMessageDomain.esql` — checks if the message domain is correct for internal HTTP.
77
+
78
+ ---
79
+
80
+ ## InternalHTTPRequestAdapter.subflow
81
+
82
+ **Purpose**: Variant of `HTTPRequestAdapter` optimized for internal (within-broker) HTTP calls.
83
+
84
+ **ESQL helper**: `InternalHTTPRequestAdapter_Remove_MQRFH2.esql` — strips MQ headers that shouldn't be forwarded over HTTP.
85
+
86
+ ---
87
+
88
+ ## Call Type Reference
89
+
90
+ | Scenario | Subflow to Use |
91
+ |---|---|
92
+ | Call T24 / NIWS / ODM / external backend | `HTTPRequestAdapter` + `HTTPResponseAdapter` |
93
+ | Chain to another ACE flow (non-HTTP) | `InternalServiceCaller` |
94
+ | Chain to another ACE REST flow | `HTTPInternalCaller` |
95
+ | Internal HTTP (broker-to-broker) | `InternalHTTPRequestAdapter` |
96
+
97
+ ---
98
+
99
+ ## Wiring Pattern (External Backend Call)
100
+
101
+ ```
102
+ [Your flow logic]
103
+
104
+ HTTPRequestAdapter ← set IsT24Adapter=TRUE (or relevant flag)
105
+
106
+ HTTPResponseAdapter ← normalizes response
107
+
108
+ [Continue flow / LogOutgoingAudit / Output Adapter]
109
+
110
+ Error path:
111
+ HTTPRequestAdapter (failure) → ErrorHandler
112
+ HTTPResponseAdapter (failure) → ErrorHandler
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Setting the Target URL
118
+
119
+ Via Properties `BankIdForRoutingService` group (multi-value):
120
+ ```xml
121
+ <group name="BankIdForRoutingService">
122
+ <property name="qiwa">
123
+ <value>T24</value> <!-- bank/system ID -->
124
+ <value>SCALNT01</value> <!-- service name -->
125
+ <value>http://host:port/service/endpoint</value> <!-- URL -->
126
+ </property>
127
+ </group>
128
+ ```
129
+
130
+ Access in ESQL:
131
+ ```esql
132
+ DECLARE targetUrl CHARACTER;
133
+ SET targetUrl = Environment.Properties.{AppLabel}.{flowName}.BankIdForRoutingService.qiwa[3];
134
+ ```
@@ -0,0 +1,101 @@
1
+ # Input Adapters
2
+
3
+ All input adapters live in `Qiwa/Framework/Lib/`. Use them as the entry point of every message flow.
4
+
5
+ ---
6
+
7
+ ## MQ_Input_Node.subflow
8
+
9
+ **Purpose**: MQ asynchronous input. Reads from a queue, loads properties, optionally audits, validates, and supports retry/rollback.
10
+
11
+ **Internal wiring** (what it does inside):
12
+ 1. Reads message from MQ queue
13
+ 2. Calls `PropertyReader` to load flow config into `Environment.Properties`
14
+ 3. Checks `IsPropertiesEnabled` → `IsAuditEnabled` → `IsRetryEnabled` → `IsRollBackEnabled` → `IsSchemaValidationNeeded`
15
+ 4. Prepares audit message via `MQ_Input_Node_PrepareAuditMessage.esql`
16
+ 5. Routes to `LogAudit` subflow
17
+
18
+ **ESQL helper modules used**:
19
+ | Module | Purpose |
20
+ |---|---|
21
+ | `MQ_Input_Node_IsAuditEnabled.esql` | Filter: check if audit is on |
22
+ | `MQ_Input_Node_IsPropertiesEnabled.esql` | Filter: check if properties loaded |
23
+ | `MQ_Input_Node_IsRetryEnabled.esql` | Filter: check if retry is on |
24
+ | `MQ_Input_Node_IsRollBackEnabled.esql` | Filter: check if rollback is on |
25
+ | `MQ_Input_Node_PrepareAuditMessage.esql` | Compute: build audit payload |
26
+
27
+ **Configuration flags** (set in Properties XML under `Logging` group):
28
+ ```
29
+ AuditEnabled TRUE/FALSE
30
+ LogEnabled TRUE/FALSE
31
+ RetryEnabled TRUE/FALSE (also under Retry group)
32
+ ValidationEnabled TRUE/FALSE (under SchemaValidation group)
33
+ ```
34
+
35
+ **ESQL DECLARE for this node**:
36
+ ```esql
37
+ DECLARE IsAuditEnabled EXTERNAL BOOLEAN FALSE;
38
+ DECLARE IsRetryEnabled EXTERNAL BOOLEAN FALSE;
39
+ DECLARE IsRollBackEnabled EXTERNAL BOOLEAN FALSE;
40
+ ```
41
+
42
+ **When to use**: Any flow that reads from an IBM MQ queue asynchronously.
43
+
44
+ ---
45
+
46
+ ## File_Input_Node.subflow
47
+
48
+ **Purpose**: Reads files from the file system. Supports audit, schema validation, and property loading.
49
+
50
+ **ESQL helper modules used**:
51
+ | Module | Purpose |
52
+ |---|---|
53
+ | `File_Input_Node_IsAuditEnabled.esql` | Filter: audit check |
54
+ | `File_Input_Node_IsPropertiesEnabled.esql` | Filter: properties check |
55
+ | `File_Input_Node_IsSchemaValidationNeeded.esql` | Filter: validate file schema |
56
+ | `File_Input_Node_PrepareAuditMessage.esql` | Compute: build audit payload |
57
+
58
+ **Configuration flags**:
59
+ ```
60
+ AuditEnabled TRUE/FALSE
61
+ LogEnabled TRUE/FALSE
62
+ ValidationEnabled TRUE/FALSE
63
+ ```
64
+
65
+ **When to use**: Any flow triggered by a file drop (batch processing, file-based integration).
66
+
67
+ ---
68
+
69
+ ## Rest_Input_Node.subflow
70
+
71
+ **Purpose**: HTTP REST input. Accepts JSON requests, loads properties, supports audit.
72
+
73
+ **When to use**: Any flow exposed as a REST endpoint.
74
+
75
+ **Notes**:
76
+ - JSON body is parsed into `XMLNSC` domain internally
77
+ - Standard `Header` structure must be present in the request
78
+
79
+ ---
80
+
81
+ ## Common Pattern Across All Input Adapters
82
+
83
+ Every input adapter follows this sequence:
84
+ ```
85
+ [Input Node]
86
+
87
+ PropertyReader ← load XML config into Environment tree
88
+
89
+ AuditPoint (incoming) ← log request if AuditEnabled=TRUE
90
+
91
+ [Your flow logic]
92
+
93
+ AuditPoint (outgoing) ← log response if AuditEnabled=TRUE
94
+
95
+ [Output Adapter]
96
+ ```
97
+
98
+ Error path from any point:
99
+ ```
100
+ [Any Node] → ErrorHandler → LogError → MQ_Dead_Output_Node / MWBusinessErrorResponse
101
+ ```
@@ -0,0 +1,124 @@
1
+ # Output Adapters
2
+
3
+ All output adapters live in `Qiwa/Framework/Lib/`. Use them as the exit point of every message flow.
4
+
5
+ ---
6
+
7
+ ## MQ_Output_Node.subflow
8
+
9
+ **Purpose**: Standard MQ output. Writes message to a target queue.
10
+
11
+ **ESQL module**: `MQ_Output_Node.esql`
12
+ - Copies message headers (`CopyMessageHeaders`)
13
+ - Sets MQ destination queue from `Environment.Destination.MQ.DestinationData.queueName`
14
+
15
+ **When to use**: Standard async MQ output for any request or response message.
16
+
17
+ ---
18
+
19
+ ## MQ_Dead_Output_Node.subflow
20
+
21
+ **Purpose**: Routes failed/unprocessable messages to a backout/dead-letter queue.
22
+
23
+ **ESQL module**: `MQ_OutputNode_IsDeadFlow.esql`
24
+
25
+ **When to use**: Always wire this as the terminal node on the error path of every MQ flow.
26
+
27
+ **Queue naming**: `<ORIGINAL_QUEUE_NAME>.BACKOUT`
28
+
29
+ ---
30
+
31
+ ## MQ_Dynamic_Output_Node.subflow
32
+
33
+ **Purpose**: Selects the target queue at runtime (from message content or environment).
34
+
35
+ **When to use**: Flows where the destination queue varies per message (e.g., routing based on `ServiceCode`).
36
+
37
+ **How it works**: Reads queue name from `Environment.Destination.MQ.DestinationData.queueName` — set this dynamically in your compute ESQL before calling this subflow.
38
+
39
+ ---
40
+
41
+ ## MQ_ReplyToQ_Node.subflow
42
+
43
+ **Purpose**: Sends response back to the `ReplyToQ` specified in the incoming MQ message header.
44
+
45
+ **When to use**: Synchronous request/reply MQ patterns where the caller specifies a reply-to queue.
46
+
47
+ **How it works**: Uses `InputRoot.MQMD.ReplyToQ` automatically.
48
+
49
+ ---
50
+
51
+ ## File_Output_Node.subflow
52
+
53
+ **Purpose**: Writes output to the file system.
54
+
55
+ **ESQL helper modules**:
56
+ | Module | Purpose |
57
+ |---|---|
58
+ | `File_Output_Node_PrepareData.esql` | Format data for file output |
59
+ | `File_Output_Node_PrepareAuditData.esql` | Prepare audit record for file operations |
60
+
61
+ **When to use**: File-based output (batch export, file drop for downstream systems).
62
+
63
+ ---
64
+
65
+ ## HTTPRequestAdapter.subflow
66
+
67
+ **Purpose**: Makes outbound HTTP/SOAP calls to backend services.
68
+
69
+ **ESQL helper**: `HTTPResponseAdapter_CheckCallType.esql`
70
+ - Determines `INTERNAL` vs `EXTERNAL` call type
71
+
72
+ **When to use**: Any flow that calls an external REST or SOAP service (T24, NIWS, ODM, Unifonic, MLSD, etc.).
73
+
74
+ **Call types**:
75
+ - `INTERNAL`: service-to-service within ACE
76
+ - `EXTERNAL`: calls to backend systems outside ACE
77
+
78
+ ---
79
+
80
+ ## HTTPResponseAdapter.subflow
81
+
82
+ **Purpose**: Handles and normalizes HTTP responses from backend calls.
83
+
84
+ **ESQL helper**: `HTTPResponseAdapter_CheckCallType.esql`
85
+
86
+ **When to use**: Always paired with `HTTPRequestAdapter`. Handles both success and fault responses.
87
+
88
+ ---
89
+
90
+ ## FileCopy.subflow
91
+
92
+ **Purpose**: Copies a file from one location to another within a flow.
93
+
94
+ **When to use**: File routing/archival scenarios.
95
+
96
+ ---
97
+
98
+ ## Output Adapter Selection Guide
99
+
100
+ | Scenario | Use |
101
+ |---|---|
102
+ | Async MQ send | `MQ_Output_Node` |
103
+ | Failed message / error terminal | `MQ_Dead_Output_Node` |
104
+ | Queue chosen at runtime | `MQ_Dynamic_Output_Node` |
105
+ | Sync MQ reply | `MQ_ReplyToQ_Node` |
106
+ | Write to file system | `File_Output_Node` |
107
+ | Call backend HTTP/SOAP service | `HTTPRequestAdapter` + `HTTPResponseAdapter` |
108
+ | Copy file | `FileCopy` |
109
+
110
+ ---
111
+
112
+ ## ESQL Copy Utilities (used in all adapters)
113
+
114
+ Every output adapter uses these standard procedures from `copy_Compute.esql`:
115
+
116
+ ```esql
117
+ -- Copy all MQ and transport headers
118
+ CALL CopyMessageHeaders();
119
+
120
+ -- Copy entire message tree
121
+ CALL CopyEntireMessage();
122
+ ```
123
+
124
+ Always call `CopyMessageHeaders()` before modifying output to preserve MQ metadata (MQMD, MQRFH2).
@@ -0,0 +1,100 @@
1
+ # Property Reader
2
+
3
+ `PropertyReader.subflow` loads external XML configuration into the `Environment.Properties` tree at runtime. It MUST be the first subflow called in every message flow.
4
+
5
+ ---
6
+
7
+ ## Components
8
+
9
+ | Component | Type | Purpose |
10
+ |---|---|---|
11
+ | `PropertyReader.subflow` | subflow | Load XML config file into Environment tree |
12
+ | `PropertyReader_LoadProperties.esql` | esql | Parse properties XML and build Environment tree |
13
+
14
+ ---
15
+
16
+ ## How It Works
17
+
18
+ 1. Reads the XML properties file (e.g., `ACCOUNT-PROPERTIES.xml`)
19
+ 2. Parses the hierarchical group structure
20
+ 3. Builds the `Environment.Properties` tree matching the XML hierarchy
21
+ 4. Substitutes runtime variables: `${broker.name}`, `${execution.group}`, `${flow.name}`, etc.
22
+
23
+ ---
24
+
25
+ ## Accessing Properties in ESQL
26
+
27
+ Properties are accessed via the path:
28
+ ```
29
+ Environment.Properties.{ApplicationLabel}.{FlowName}.{Group}.{PropertyName}
30
+ ```
31
+
32
+ Examples:
33
+ ```esql
34
+ -- Check if audit is enabled
35
+ Environment.Properties.BS_Account.GetAccountDetails.Logging.AuditEnabled
36
+
37
+ -- Get retry max count
38
+ Environment.Properties.BS_Account.GetAccountDetails.Retry.maxRetryCount
39
+
40
+ -- Get a routing service URL
41
+ Environment.Properties.BS_Account.GetAccountDetails.BankIdForRoutingService.qiwa[1]
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Properties File Structure
47
+
48
+ See `config/properties-template.md` for the full XML template.
49
+
50
+ **Key groups** available for every flow:
51
+
52
+ | Group | Properties |
53
+ |---|---|
54
+ | `Logging` | `LogEnabled`, `AuditEnabled`, `MaskingEnabled`, `key1-key10`, `value1-value10`, `maskingIn`, `maskingOut` |
55
+ | `Retry` | `RetryEnabled`, `maxRetryCount`, `minWaitDurationSec` |
56
+ | `Variables` | `callCorrIDOffset` |
57
+ | `SchemaValidation` | `ValidationEnabled` |
58
+ | `Priority` | `Priority` (MQ message priority 0-9) |
59
+ | `BankIdForRoutingService` | Multi-value: bank ID, routing service name, URL |
60
+
61
+ ---
62
+
63
+ ## Runtime Variable Substitution
64
+
65
+ These tokens in property values are replaced at runtime:
66
+
67
+ | Token | Replaced With |
68
+ |---|---|
69
+ | `${broker.name}` | ACE broker/integration node name |
70
+ | `${execution.group}` | Execution group / integration server name |
71
+ | `${flow.name}` | Message flow name |
72
+ | `${application.name}` | Application name |
73
+
74
+ ---
75
+
76
+ ## ESQL Node Properties for PropertyReader
77
+
78
+ ```esql
79
+ -- Required EXTERNAL declarations in the module using PropertyReader
80
+ DECLARE ApplicationLabel EXTERNAL CHARACTER '';
81
+ DECLARE PropertiesFileName EXTERNAL CHARACTER '';
82
+ ```
83
+
84
+ Set `ApplicationLabel` and `PropertiesFileName` at the node level in the flow:
85
+ - `ApplicationLabel`: e.g., `BS_Account`
86
+ - `PropertiesFileName`: e.g., `ACCOUNT-PROPERTIES.xml`
87
+
88
+ ---
89
+
90
+ ## Wiring
91
+
92
+ ```
93
+ [Input Node]
94
+
95
+ PropertyReader ← ALWAYS first
96
+
97
+ [rest of flow]
98
+ ```
99
+
100
+ Never call `AuditPoint`, `RetryPoint`, or any other framework component before `PropertyReader` — they all depend on `Environment.Properties` being populated.
@@ -0,0 +1,107 @@
1
+ # Retry Mechanism
2
+
3
+ The framework provides configurable retry for MQ-based flows using `RetryPoint.subflow`.
4
+
5
+ ---
6
+
7
+ ## Components
8
+
9
+ | Component | Type | Purpose |
10
+ |---|---|---|
11
+ | `RetryPoint.subflow` | subflow | Re-queue message after failure with delay |
12
+ | `SetRetryProperties.esql` | esql | Set retry tracking headers on MQRFH2 |
13
+
14
+ ---
15
+
16
+ ## How It Works
17
+
18
+ 1. On failure, message is caught by `ErrorHandler`
19
+ 2. `ErrorHandler` checks `RetryEnabled` from Properties
20
+ 3. If enabled, routes to `RetryPoint`
21
+ 4. `SetRetryProperties.esql` increments retry count in `MQRFH2.usr.retry`
22
+ 5. Message is re-queued to `MQRFH2.usr.sourceQueue` after `minWaitDurationSec`
23
+ 6. When `maxRetryCount` is reached → route to `MQ_Dead_Output_Node`
24
+
25
+ ---
26
+
27
+ ## Configuration (Properties XML)
28
+
29
+ Under the `Retry` group for each flow:
30
+
31
+ ```xml
32
+ <group name="Retry">
33
+ <property name="RetryEnabled" value="TRUE" />
34
+ <property name="maxRetryCount" value="5" />
35
+ <property name="minWaitDurationSec" value="60" />
36
+ </group>
37
+ ```
38
+
39
+ | Property | Default | Description |
40
+ |---|---|---|
41
+ | `RetryEnabled` | `FALSE` | Enable/disable retry |
42
+ | `maxRetryCount` | `5` | Max attempts before dead-lettering |
43
+ | `minWaitDurationSec` | `60` | Seconds to wait before re-queue |
44
+
45
+ ---
46
+
47
+ ## MQRFH2 Headers Used
48
+
49
+ | Header | Purpose |
50
+ |---|---|
51
+ | `MQRFH2.usr.retry` | Current retry attempt count |
52
+ | `MQRFH2.usr.sourceQueue` | Original queue to re-queue to |
53
+
54
+ ---
55
+
56
+ ## ESQL for Retry Check
57
+
58
+ ```esql
59
+ -- Check current retry count
60
+ DECLARE retryCount INT;
61
+ SET retryCount = InputRoot.MQRFH2.usr.retry;
62
+
63
+ -- Get max from properties
64
+ DECLARE maxRetry INT;
65
+ SET maxRetry = Environment.Properties.{AppLabel}.{flowName}.Retry.maxRetryCount;
66
+
67
+ IF retryCount >= maxRetry THEN
68
+ -- route to dead letter
69
+ ELSE
70
+ -- increment and re-queue
71
+ SET OutputRoot.MQRFH2.usr.retry = retryCount + 1;
72
+ END IF;
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Wiring in a Flow
78
+
79
+ Retry is an alternative path to dead-letter on the error route:
80
+
81
+ ```
82
+ [Failure]
83
+
84
+ ErrorHandler
85
+
86
+ [RetryEnabled=TRUE AND retryCount < maxRetryCount]
87
+
88
+ RetryPoint ← re-queue with delay
89
+
90
+ [RetryEnabled=FALSE OR retryCount >= maxRetryCount]
91
+
92
+ MQ_Dead_Output_Node ← permanent failure
93
+ ```
94
+
95
+ ---
96
+
97
+ ## When to Enable Retry
98
+
99
+ Enable retry for:
100
+ - Backend service temporarily unavailable
101
+ - Database connectivity issues
102
+ - Transient network failures
103
+
104
+ Do NOT enable retry for:
105
+ - Business validation failures (bad input data won't get better)
106
+ - Schema validation failures
107
+ - Security/authorization errors