Function Blocks(4.0)
APL code is divided into different function blocks that serve as execution entry-points that are applicable to the various workflow states.
initialize
The initialize function block is executed once for each invocation of the workflow and enables you to assign, for example, an argument with an initial value.
Note!
Avoid reading MIM parameters from within initialize
. The order by which agents are initialized is undefined and MIM parameters are therefore not necessarily set during the initialize phase.
The udrRoute function cannot be used in the initialize
block.
beginBatch and endBatch
Note!
beginBatch and endBatch are applicable for batch workflows only.Â
The beginBatch
and endBatch
function blocks are executed at the beginning and end of each batch respectively. Rules are that the beginBatch block is called when a batch collection agent emits a Begin Batch call. This occurs either at file start, or when a hintEndBatch
call is received from any agent capable of utilizing APL code. See hintEndBatch in Workflow Functions(4.0) for more information.
The endBatch
block is called every time a batch collection agent emits an End Batch. This occurs either at file end, or when a hintEndBatch
call is received from any agent capable of utilizing APL code.
Note!
The udrRoute
function cannot be used in the beginBatch
and endBatch
blocks.Â
consume
The consume
function block is executed for each UDR or bytearray passing the agent. Within a consume
block, validation, modification and routing can be performed. Each UDR or bytearray is referred to by the special input variable.
Built-in Variables
Variable | Description | Example |
---|---|---|
input | Read-only variable containing the current UDR. Only available in the consume function block. | input.ANumber = 1234567; udrRoute(input); |
When handling several types of UDRs in the same Analysis agent, the APL code must first determine what type is currently handled, then cast it to the correct type. For an example, see Data Types(4.0).
drain
Note!
Drain is applicable for batch workflows only.
The drain function block is executed right before an endBatch
block, and is treated as a final consume
block. For instance, if a batch containing ten UDRs is processed by the agent, consume will be executed ten times before the drain
function block is called. This is useful, for instance when collecting statistical data for a batch which is to be routed as a new UDR. The advantage with drain is that all consume
features (except for the input built-in variable) are accessible, as opposed to the endBatch
function block.
Example - How to use drain
int UDRCounter; int file_count; consume { UDRCounter=UDRCounter+1; udrRoute(input); } drain { myFolder.myUFDLFile.myTrailerFormat myTrailer; myTrailer=udrCreate(myFolder.myUFDLFile.myTrailerFormat); myTrailer.closingdate=dateCreateNow(); myTrailer.numberOfUDRs=UDRCounter; myTrailer.sourceFileName=(string)mimGet("Disk_1", "Source Filename"); udrRoute(myTrailer); } endBatch{ file_count = file_count + 1; debug( "Number of UDRs in file:" + UDR_count ); }
cancelBatch
Note!
cancelBatch
is applicable for batch workflows only.
The cancelBatch
function block is executed if a Cancel Batch is emitted anywhere in the workflow. Note that End Batch and Cancel Batch are mutually exclusive - only one per batch can be executed.
If the cancelBatch
function block is called and the Cancel Batch behavior is set to Abort Immediately the workflow will immediately abort without the cancelBatch
function block being called. The block is only called when the preferences are set to Abort After or Never Abort. For further information about the Abort related configurations, see Workflow Properties(3.0) in the Desktop user's guide.
commit
Note!
commit
is applicable for batch workflows only.
The commit
function block is executed for each batch when the transaction is successful. In a commit
block, actions that concern transaction safety can be performed. The transaction is referred to by the special TransactionDetails
UDR that contains the transaction id.
The udrRoute
function cannot be used in the commit
block.
Built-in Variables
Variable | Description | Example |
---|---|---|
transaction | This is a read-only variable containing the current transaction. The variable is available in the commit and rollback function blocks. | debug("commit of txn " + transaction.id); |
rollback
Note!
Rollback
is applicable for batch workflows only.
The rollback function block is executed for each batch when a transaction fails. In a rollback block, actions that concern transaction safety can be performed. The transaction is referred to by the special TransactionDetails UDR that contains the transaction id.
Note!
 If a transaction fails during commit, it will try to commit again, and will not be sent to the rollback
block.
The udrRoute
function cannot be used in the rollback
block.
deinitialize
The deinitialize
function block is executed right before the workflow stops.
If the deinitialize
block is used in a real-time workflow it could be used to clean and close resources, for instance external connections.
exceptionHandling
The exceptionHandling
function block enables you to divert exceptions from the workflow's main processing course to a separate course, where exceptions are processed according to your needs.
exceptionHandling in Batch Workflows
For example: When a workflow occasionally aborts due to an exception in the APL code, use exceptionHandling to cancel the batch.
Example - Using exceptionHandling to cancel a batch
consume { int a = 1; int b = 0; debug("The following row will generate an exception"); float c = a/b; } exceptionHandling { debug("Type: "+ exception.type); debug("Message: " + exception.message); debug("Stacktrace: " + exception.stackTrace); cancelBatch("Exception caught", exception); }
Note!
The exceptionHandling
function block for batch workflows is a legacy statement that is retained for backward compatibility. It is recommended that you use try-catch, throw and finally statements instead. These are described in the next section.Â
Exception Handling in Batch and Real-Time Workflows
The try-catch
, throw
and finally
statements can be used to handle exceptions in batch and real-time.
You use a try-catch
block if the statements within the try block might throw an exception. try-catch
blocks can be nested. The try
block is followed by a catch
block, which specifies the type of exception that it handles. You can route any UDR with udrRoute within the catch block.
If an exception is thrown, the code jumps to the catch
block, which in this case handles all Java class Exceptions. Note that the catch in this case does not catch Throwable Exceptions.
A throw block throws an exception to the catch block which handles the exception.
A finally
block is at the end of a catch block and runs a clean-up.
Note!
 The use of these Exception Handling statements only applies to APL.
For example: When an exception is thrown due to division by zero, use the try-catch
statement to catch the thrown exception. It is also possible to use the throw statement to throw the exception again. Use finally to ensure a clean-up is done.
Example - Using the try-catch statement
consume { int b = 0; try { debug("Hello: " + 100/b); } catch (ExceptionDetails exception) { debug("EXCEPTION: " + exception.message); // To throw exception caught, write 'throw exception'. throw testCreate(); // This will cause execution of the (legacy) exceptionHandling if declared (only available in batch workflows), otherwise the workflow aborts. } finally { debug("In finally clause " + b); } } ExceptionDetails testCreate() { ExceptionDetails ed = udrCreate(ExceptionDetails); ed.message = "DONE"; return ed; }
ExceptionDetails
The ExceptionDetails
UDRÂ stores the information for an exception that is caught in a catch block in batch or real-time.
Field | Description |
---|---|
| The message included in the exception |
stackTrace (string)
| The function call hierarchy from where the exception occurred |
type (string)
| Type of exception |
OriginalData (bytearray)
| This field is always empty. |
Function Blocks Example
Example - Function Blocks Example
int file_count; int UDR_count; initialize { file_count = 0; } beginBatch { UDR_count = 0; } consume { udrRoute( input ); UDR_count = UDR_count + 1; } endBatch { file_count = file_count + 1; debug( "Number of UDRs in file:" + UDR_count ); } deinitialize { debug(" Number of executed files:" + file_count ); } exceptionHandling { debug(" Exception occurred, stacktrace: " + exception.stackTrace); }