Details about EPL code that you can add
The following sections describe what Apama generates for you in Software AG Designer and where to add EPL code.
Actions that update parameters
Apama generates skeleton code for an action for each parameter you specify for the block. Each action updates the value of the parameter. These actions are named update$parameter_name, where parameter_name is the metadata name you specified for the parameter. Each action takes the parameter's specified name as an argument.
Each time the value of a block parameter changes in the scenario, the scenario calls the corresponding update action on the block. It is up to you to define appropriate EPL code in the body of this action to handle the block parameter update. It is bad practice to send updates to output feeds during a parameter update action because it can cause unexpected results in the running scenario.
If a parameter should not be editable, leave the body of its update action empty.
For example, if a block specifies a string parameter called New Parameter 1, Apama generates the following skeleton code:
action update$new_parameter_1(string new_parameter_1) {
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert handler for modifications to new parameter 1 --
//
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
If a block is based on an existing event and is an input block, the skeleton code contains additional information about the parameter. In the following example a parameter based on the event field customerName has been specified:
action update$customerName(string customerName) {
// BLOCKBUILDER - USER DEFINED ACTION
parameter_customerName := customerName ;
isSet_parameter_customerName := true;
setupNewListener();
// BLOCKBUILDER - END OF USER DEFINED ACTION
Actions that update input feeds
Apama generates skeleton code for an action for each input feed you specify for the block. Each action updates the values of the corresponding input feed's fields. These actions are named input$input_feed_name, where input_feed_name is the metadata name you specified for the input feed. Each action takes an argument for each field in the corresponding input feed.
It is up to you to define appropriate EPL code in the body of this action to handle the update to the input feed. For example, if a block specifies an input feed named Input Feed 1, Apama generates the following skeleton code:
action input$new_input_feed_1(#string string_field, float float_field)
{
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert handler for new input events on stream new input feed 1 --
//
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
Actions that perform operations
Apama generates skeleton code for an action for each operation that you specify in the block. Each action performs the operation. These actions are named operation$operation_name where operation_name is the metadata name you specified for the operation. Each action takes only an acknowledge() action variable argument.
It is up to you to define appropriate EPL code in the body of this action to handle the operation's invocation. You must call the
acknowledge() action when the operation is complete. There are constraints on how long you can hold up a call to
acknowledge(). Often, an operation updates output feeds before calling
acknowledge(). See
Timeliness of acknowledgements.
For example, if a block specifies an operation called New Operation 1, Apama generates the following skeleton code:
action operation$new_operation_1(action<> acknowledge) {
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert handler for invocations of operation new operation 1 --
//
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
Actions that update output feeds
Apama generates a sendOutput action for each output feed that you specified for the block. Each action updates the values of the corresponding output feed's fields. These actions are named sendOutput$output_feed_name where output_feed_name is the metadata name of the output feed. Each action takes an argument for each field in the corresponding output feed.
You do not need to add code for these actions. To output results from your block you should call one of these output feed actions. If your block uses an output feed new_output_feed_1 with a boolean field new_field_1 and a string field new_field_2, Apama generates the following code:
action<boolean,string> sendOutput$new_output_feed_1;
setup action
Apama generates skeleton code for the setup() action. The scenario calls the setup() action once on each block instance in a scenario definition. The scenario makes this call when you inject the scenario into the correlator. Use the setup() action to specify any initialization that is not specific to a scenario instance. Apama generates the following skeleton code:
action setup() {
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert setup code --
//
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
instancePreSpawnInit action
Apama generates skeleton code for the instancePreSpawnInit() action. The scenario calls the instancePreSpawnInit() action on each scenario instance. The scenario makes this call just before it spawns the scenario instance. The scenario passes the following values into the instancePreSpawnInit() action:
Scenario ID
Dictionary of extra data
Target context the scenario instance will run in. For a scenario that is not parallel (that is, it is a serial scenario), the target context is always the main context.
Use the instancePreSpawnInit() action to perform initialization in the main context. For example, the main context might need information about which context the scenario instance, and therefore the block instance(s) will run in. A block cannot generate output feed values inside the instancePreSpawnInit() action, but it can generate output feed values inside the instancePostSpawnInit() action.
When the scenario calls the
instancePreSpawnInit() action, it passes an
acknowledgment() action. You are responsible for ensuring that the
instancePreSpawnInit() action calls this
acknowledgment() action when it has completed this phase of initialization. To help you do this, Apama generates a call to
acknowledge() when it generates the skeleton code for the block. See
Timeliness of acknowledgements.
Apama generates the following skeleton code:
action instancePreSpawnInit (
integer blockInstanceId$,
string scenarioId$,
dictionary<string, string> userData$,
context target,
action<> acknowledge) {
self.blockInstanceId$ := blockInstanceId$;
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert pre-spawn initialisation code --
//
acknowledge();
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
If a block is based on an existing event, the skeleton code contains additional code to specify the context.
action instancePreSpawnInit(
integer blockInstanceId$,
string scenarioId$,
dictionary<string, string> userData$,
context target,
action<> acknowledge) {
self.blockInstanceId$ := blockInstanceId$;
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert pre-spawn initialisation code --
//
preSpawnContext := context.current();
acknowledge();
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
instancePostSpawnInit action
Apama generates skeleton code for the instancePostSpawnInit() action. The scenario calls the instancePostSpawnInit() action on each newly spawned scenario instance. The scenario makes this call right after it spawns the scenario instance. Part of this action is to pass the following to the scenario instance:
Scenario ID
Dictionary of extra values
Initial values of the block's parameters
Additional data for use by the automatically generated code.
When the scenario calls the
instancePostSpawnInit() action, it passes an
acknowledgment() action. You are responsible for ensuring that the
instancePostSpawnInit() action calls this
acknowledgment() action when it has completed this phase of initialization. To help you do this, Apama generates a call to
acknowledge() when it generates the skeleton code for the block. See
Timeliness of acknowledgements.
Apama generates the following skeleton code:
action instancePostSpawnInit (
integer blockInstanceId$,
string ownerId$,
string scenarioId$,
dictionary<string, string> userData$,
action<> acknowledge)
param_type param1 //one for each parameter
action<output_field_types> sendOutput$outfeed {
// one action like the above for each output feed
// one line like the following for each output feed
self.sendOutput$outfeed1 := sendOutput$outfeed1;
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert post-spawn initialisation code --
//
acknowledge();
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
If the block is an input block based on an existing event, the generated code looks like this:
action instancePostSpawnInit(
integer blockInstanceId$,
string ownerId$,
string scenarioId$,
dictionary<string, string> userData$,
action<> acknowledge,
string name,
action<string,float> sendOutput$TestEvent) {
self.sendOutput$TestEvent := sendOutput$TestEvent;
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert post-spawn initialisation code --
//
enqueue TestEventForwardRequest (context.current()) to preSpawnContext;
// Store the initial values
parameter_name := name;
acknowledge();
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
If the block is an output block based on an existing event, the generated code looks like this:
action instancePostSpawnInit(
integer blockInstanceId$,
string ownerId$,
string scenarioId$,
dictionary<string, string> userData$,
action<> acknowledge,
string name) {
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert post-spawn initialisation code --
//
if (preSpawnContext.getId() = context.current().getId()) {
serialExecution := true;
}
else {
serialExecution := false;
}
acknowledge();
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
The scenario is not in a fully created state until all blocks have acknowledged their instancePostSpawnInit() call. Also, updating of output feeds is not supported at any stage before instancePostSpawnInit() is called. If initial values for output feeds need to be generated, do this in the instancePostSpawnInit() action.
cleanup action
Apama generates skeleton code for the cleanup() action. When a block's scenario enters its end state, is deleted, or dies for some other reason, the scenario calls the block's cleanup() action. Even if there is a runtime error, the scenario calls the cleanup() action.
After the scenario calls the cleanup() action, the block should no longer try to update its output feeds. The block should act in every possible way as if it was dead. However, if there is any finalization work that you want to accomplish, you can add it to the body of the cleanup() action. Apama generates the following skeleton code:
action cleanup() {
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert finalization code --
//
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
start action
For blocks that are based on existing event definitions and are specified as input blocks, Apama generates code for a start action. Once the start operation is invoked the block calls a setupNewListener action, which creates the listener code for the event on which the block is based. If any event fields have been specified when defining the block, they are used as parameters to create filters in the listener. Apama generates the following code:
action operation$start(action<> acknowledge) {
// BLOCKBUILDER - USER DEFINED ACTION
isStarted := true;
setupNewListener();
acknowledge();
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
stop action
For blocks that are based on existing event definitions and are specified as input blocks, Apama generates code for a stop action. When the stop operation is invoked all active listeners are terminated. Apama generates the following code (where “l” is a listener defined elsewhere):
action operation$stop(action<> acknowledge) {
// BLOCKBUILDER - USER DEFINED ACTION
isStarted := false;
l.quit();
acknowledge();
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
send action
For blocks that are based on existing event definitions and are specified as output blocks, Apama generates code for a send$event action. When the send action is called, it sends the specified event on which the block is based. For example, with a specified event, testEvent (containing two fields, name and IDnum), Apama generates the following code:
action operation$send$_testEvent(action<> acknowledge) {
// BLOCKBUILDER - USER DEFINED ACTION
//
// -- insert handler for invocations of operation send_testEvent --
//
if (serialExecution) {
route testEvent(parameter_name,parameter_IDnum);
}
else {
enqueue testEvent(parameter_name,parameter_IDnum) to preSpawnContext;
}
acknowledge();
// BLOCKBUILDER - END OF USER DEFINED ACTION
}
User-defined monitors or event types
If you need to add monitors or event types to a block, define them in the specified section of the block's generated EPL code:
// BLOCKBUILDER - USER DEFINED MONITORS
//
// -- insert any additional monitors you require --
//
// BLOCKBUILDER - END OF USER DEFINED MONITORS
For more information, see
Defining Monitors.
User-defined variables
If you need to add variables to a block, define them in the specified section of the block's generated EPL code, which is the first section in the block's #block# event code:
event #block# {
// BLOCKBUILDER - USER DEFINED VARIABLES
//
// -- insert any additional variables you require --
//
// BLOCKBUILDER - END OF USER DEFINED VARIABLES
User-defined actions
In addition to the actions described above you can add any other actions that you require to implement the unique functionality of your block. Add additional actions at the end of the block definition file in the specified section:
// BLOCKBUILDER - USER DEFINED ACTIONS
//
// -- insert any additional actions required --
//
// BLOCKBUILDER - END OF USER DEFINED ACTIONS