apama-analytics-builder-block-sdk

Basic blocks

Blocks are written in EPL as event definitions, with actions. A block must at a minimum have the following (we will assume blocks will have at least one input or output):

(Typically, types from another package would have a corresponding using statement so that they can be referred to by their short name).

For most blocks, the $process action is where the main processing of the block will take place, based on the input values provided.

Thus, a very simple block implementation could be:

package apamax.sampleblock;
using apama.analyticsbuilder.BlockBase;
using apama.analyticsbuilder.Activation;

/**
 * @$blockCategory Calculations
 */
event Offset {
    BlockBase $base;
    action $process(Activation $activation, float $input_value) {
        $setOutput_output($activation, $input_value + 100.0 );
    }
    action<Activation, float> $setOutput_output;
}

Hints:

This block simply adds 100 to every input value. The $process action has parameters for the inputs, and the output is sent by calling the $setOutput_output action field. The framework takes care of creating an instance of the block when it is required for a model, initializing the $base and $setOutput_output fields and calling the $process action when the block receives input.

The type signature of the $process action is not fixed. If a block has more inputs, it can include more $input_-prefixed parameters. The types of the $input_ parameters indicate the types of the inputs (see also dynamic types). The framework inspects the type of the $process action (and indeed, whether the block even has one) and will call it accordingly. As we will see later, there are other parameters that can be included in a $process signature. The framework uses a form of “Dependency injection” when creating the block and calling the $process action (and others). This means that blocks only need to mention the parameters they require, not the full set of features provided by the Analytics Builder framework.

The existence of a $process action denotes that the block has inputs, and the identifiers of the block’s inputs are the parameter names starting with $input_ with the prefix removed. Thus, the above block has an input with an identifier value (and of type float). The existence of a $setOutput_output denotes that the block has an output with an identifier output (and of type float). A more complex block could have multiple inputs (extra parameters to the $process action), or more outputs - more $setOutput_-prefixed action type fields.

Inputs and outputs can be one of the following types:

Refer to a later chapter for the any and Value types.

If a block has multiple inputs, it may be that only some are connected, or only some inputs have received values when the block is first called. If basic types such as float or string are used, then the $input parameters will be provided with their default value when $process is called. It is recommended that any blocks with more than one input use optional<type> as the type of the $input parameters; the block can then distinguish between an input where a value has been provided or not. For example, the $process action of the Difference block only generates an output if both inputs have received a value (do not treat 0 as not having received a value - 0 may be a valid actual input value):

action $process(Activation $activation, optional<float> $input_value1, optional<float> $input_value2) {
    ifpresent $input_value1, $input_value2{
        float result :=  $input_value1-$input_value2;
        $setOutput_absoluteDifference($activation, result.abs());
        $setOutput_signedDifference($activation, result);
    }
}

Where a block has multiple inputs, the framework will normally provide the latest value on each input to the $process action. Blocks do not need to cache the latest value. The exception to this rule are inputs of the pulse type, which are automatically reset to false values.

Blocks can also call methods on the $base field, which can provide contextual information about the model the block is within, including:

< Prev: Using Software AG Designer Contents Next: Naming and documenting blocks >