Real-time triggers (Evaluator)
Overview
The Genesis Evaluator is a microservice used for triggering events.
You can configure two types of trigger:
- scheduled events (Cron rules) are run automatically at the specified dates and times
- data-driven events (Dynamic rules) are run when data in a table meets the rules you have specified
When a trigger happens, an event handler event message is sent, and its business logic is run. You must configure the required logic in the event. For example, it could update the data model, it could trigger the generation and publishing of a file, or it could trigger another event. By configuring the Evaluator and Event Handler, you can meet your exact business requirements.
Unlike most server capabilities in the Genesis Application Platform, you don't have to configure a .kts file to set up Evaluator; it is entirely driven by records in these two tables:
CRON_RULE
for time-based (scheduled) events; you specify the schedule as a Quartz Cron ExpressionDYNAMIC_RULE
for data-update-driven events; you specify which value is to be monitored in a table or view, the boolean logic for triggering the event, and the event to be triggered
Example configuration
Scheduled events
Example CRON_RULE
table entry:
NAME | CRON_EXPRESSION | DESCRIPTION | TIME_ZONE | RULE_STATUS | USER_NAME | PROCESS_NAME | MESSAGE_TYPE | RESULT_EXPRESSION |
---|---|---|---|---|---|---|---|---|
US desk position report | 0 45 6 ? * MON-FRI * | Send position report to US desk | America/New_York | ENABLED | admin | POSITION_EVENT_HANDLER | EVENT_POSITION_REPORT | (DESK == 'US') |
In this example, the EVENT_POSITION_REPORT
event will be triggered with DETAILS
parameter DESK == 'US'
at 06:45 AM (EST/EDT) each week day.
Given its name, we can expect this event to generate and distribute a report for a particular desk's positions.
Data-driven events
ID | NAME | DESCRIPTION | USER_NAME | RULE_TABLE | RULE_STATUS | RULE_EXPRESSION | PROCESS_NAME | MESSAGE_TYPE | RESULT_EXPRESSION | TABLE_OPERATION | IS_TEMPLATE | RULE_EXECUTION_STRATEGY | RULE_TYPE |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
000000000000001DRLO1 | Warn large trade | Trigger warning event on notional traded over 1,000,000 | admin | TRADE_VIEW | ENABLED | (NOTIONAL > 1000000) | EVENT_LARGE_TRADE_WARNING | (TRADE_ID = TRADE_ID) | INSERT | false | ONCE_PER_RECORD |
In this example, the EVENT_LARGE_TRADE_WARNING
will be triggered with DETAILS
parameter of TRADE_ID == <the record's trade id>
when the TRADE
table (the root table of the TRADE_VIEW
in our example data model) has a new record inserted where the NOTIONAL
is greater than 1,000,000.
Given its name, we can expect this event to trigger some business workflow for large trades with the desk.
The Genesis Evaluator's DYNAMIC_RULE
data-driven events are used to power the notifications and alert component.
Configuration options
Here, we look look more closely at the two tables and values that we can expect in their records.
CRON_RULE
Field Name | Description | Example Value | Mandatory |
---|---|---|---|
NAME | Name of the rule. This is a key, and so each entry must have a unique value | US desk position report | true |
CRON_EXPRESSION | Quartz Cron Expression defining when the rule triggers | 0 45 6 ? * MON-FRI * | true |
DESCRIPTION | Description of the rule | Send position report to US desk | true |
TIME_ZONE | The Time Zone of the cron expression. Be careful selecting time zones that don't shift with daylight savings, such as EST , which may or may not be desirable. Defaults to the system time where left blank | America/New_York | false |
RULE_STATUS | The status of the rule. If anything other than ENABLED , the rule will not listen or trigger any event. | ENABLED | true |
USER_NAME | The username that will be sent on the triggered event. User must have permission to use this event for it to be triggered successfully | admin | false |
PROCESS_NAME | The name of the process to send the resulting event | POSITION_EVENT_HANDLER | true |
MESSAGE_TYPE | The name of the event the rule should send when triggered | EVENT_POSITION_REPORT | true |
RESULT_EXPRESSION | The details to send on the event message. The syntax is that event fields should be left of the = and you can use literal values to the right. Multiple event fields are separated by && | (DESK == 'US') && (TRIGGER == 'RULE') | false |
Rules are managed via the API, which exposes CRUD operations for maintaining the table.
DYNAMIC_RULE
Field Name | Description | Example Value | Mandatory |
---|---|---|---|
ID | ID for the rule. Auto-generated where left unspecified on insert | 000000000000001DRLO1 | true |
NAME | Name of the rule | Large trade | true |
DESCRIPTION | Description of the rule | A large trade has been received | true |
USER_NAME | The username that will be sent on the triggered event. User must have permission to use this event for it to be triggered successfully | admin | false |
RULE_TABLE | The table or view the rule listens to for updates | TRADE_VIEW | true |
RULE_STATUS | The status of the rule. If anything other than ENABLED , the rule will not listen or trigger any event | ENABLED | true |
RULE_EXPRESSION | Boolean logic for trigger. The expression can reference any of the fields on the updated table or view. The expression must be wrapped in brackets | ((NOTIONAL > 1000000)) | false |
PROCESS_NAME | The name of the process to send the resulting event. As of v8, this is optional; service discovery will be used to find the process to send the event. We recommend that you leave this blank to work in all environments, including those running compact processes, or for consul environments | POSITION_EVENT_HANDLER | false |
MESSAGE_TYPE | The name of the event the rule should send when triggered | EVENT_LARGE_TRADE_WARNING | true |
RESULT_EXPRESSION | The details to send on the event message. The syntax is that event fields should be left of the = and you can use literal values or field values from the RULE_TABLE to the right. Multiple event fields are separated by && | (TRADE_ID = TRADE_ID) && (TRIGGER = 'RULE') | false |
TABLE_OPERATION | The table operations to trigger the rule on. Valid operations are INSERT , MODIFY and DELETE . You can configure more than one operation to trigger the rule; where you do this, these must be pipe-delimited. If this value is left blank, only INSERT table operations will trigger the rule | INSERT|MODIFY|DELETE | true |
IS_TEMPLATE | Relevant when using notifications and alert component where users can define rule templates to which users subscribe. Rules marked as true are templates, are never triggered (a subscription to a template creates a new dynamic rule) | false | |
RULE_EXECUTION_STRATEGY | Defines how many times the rule should trigger for a given record (record of root table where RULE_TABLE is a view). Valid values are UNLIMITED , ONCE_ONLY , ONCE_PER_RECORD . Default is UNLIMITED . This is helpful if TABLE_OPERATION must include MODIFY and the records may have many modifications to stop repeated alerts | ONCE_ONLY | false |
RULE_TYPE | Used to specify that this rule belongs to a group. For example, the notifications and alert component will set this value to NOTIFY | NOTIFY | false |
Rules are managed via the API, which exposes CRUD operations for maintaining the table. Components such as notifications and alert component include a user interface that manages dynamic rule set-up and reads application metadata to help users populate table/view selection and expressions.
Client API
Rules can be managed via the API.
In the examples below, responses are omitted for brevity; they are standard eventHandler
acks/nacks.
CRON_RULE
API
EVENT_CRON_RULE_INSERT
Insert a new Cron Rule.
All parameters, descriptions and defaults are listed under CRON_RULE
configuration options
- Websocket API
- REST API
{
"USER_NAME": "admin",
"SOURCE_REF": "001",
"MESSAGE_TYPE": "EVENT_CRON_RULE_INSERT",
"DETAILS": {
"NAME" : "US desk position report",
"CRON_EXPRESSION" : "0 45 6 ? * MON-FRI *",
"DESCRIPTION" : "Send position report to US desk",
"TIME_ZONE" : "America/New_York",
"RULE_STATUS" : "ENABLED",
"PROCESS_NAME" : "POSITION_EVENT_HANDLER",
"MESSAGE_TYPE" : "EVENT_POSITION_REPORT",
"RESULT_EXPRESSION" : "(DESK == 'US')",
}
}
POST /event-cron-rule-insert HTTP/1.1
Host: localhost:9064
Content-Type: application/json
SESSION_AUTH_TOKEN: RSOo9rm3Y2PAopTKd1aW8E8Wu4Kkg97i
SOURCE_REF: 001
{
"DETAILS": {
"NAME" : "US desk position report",
"CRON_EXPRESSION" : "0 45 6 ? * MON-FRI *",
"DESCRIPTION" : "Send position report to US desk",
"TIME_ZONE" : "America/New_York",
"RULE_STATUS" : "ENABLED",
"PROCESS_NAME" : "POSITION_EVENT_HANDLER",
"MESSAGE_TYPE" : "EVENT_POSITION_REPORT",
"RESULT_EXPRESSION" : "(DESK == 'US')",
}
}
EVENT_CRON_RULE_AMEND
Amend an existing rule.
Changing the time to 7am from example above.
All parameters, descriptions and defaults are listed under CRON_RULE
configuration options
- Websocket API
- REST API
{
"USER_NAME": "admin",
"SOURCE_REF": "002",
"MESSAGE_TYPE": "EVENT_CRON_RULE_AMEND",
"DETAILS": {
"NAME" : "US desk position report",
"CRON_EXPRESSION" : "0 45 6 ? * MON-FRI *",
"DESCRIPTION" : "Send position report to US desk",
"TIME_ZONE" : "America/New_York",
"RULE_STATUS" : "ENABLED",
"PROCESS_NAME" : "POSITION_EVENT_HANDLER",
"MESSAGE_TYPE" : "EVENT_POSITION_REPORT",
"RESULT_EXPRESSION" : "(DESK == 'US')",
}
}
POST /event-cron-rule-amend HTTP/1.1
Host: localhost:9064
Content-Type: application/json
SESSION_AUTH_TOKEN: RSOo9rm3Y2PAopTKd1aW8E8Wu4Kkg97i
SOURCE_REF: 002
{
"DETAILS": {
"NAME" : "US desk position report",
"CRON_EXPRESSION" : "0 0 7 ? * MON-FRI *",
"NAME" : "US desk position report",
"TIME_ZONE" : "America/New_York",
"RULE_STATUS" : "ENABLED",
"PROCESS_NAME" : "POSITION_EVENT_HANDLER",
"MESSAGE_TYPE" : "EVENT_POSITION_REPORT",
"RESULT_EXPRESSION" : "(DESK == 'US')",
}
}
EVENT_CRON_RULE_DELETE
Delete an existing rule.
- Websocket API
- REST API
{
"USER_NAME": "admin",
"SOURCE_REF": "003",
"MESSAGE_TYPE": "EVENT_CRON_RULE_DELETE",
"DETAILS": {
"NAME" : "US desk position report",
}
}
POST /event-cron-rule-delete HTTP/1.1
Host: localhost:9064
Content-Type: application/json
SESSION_AUTH_TOKEN: RSOo9rm3Y2PAopTKd1aW8E8Wu4Kkg97i
SOURCE_REF: 003
{
"DETAILS": {
"NAME" : "US desk position report",
}
}
EVENT_CRON_RULE_ENABLE
Enable an existing rule.
- Websocket API
- REST API
{
"USER_NAME": "admin",
"SOURCE_REF": "004",
"MESSAGE_TYPE": "EVENT_CRON_RULE_ENABLE",
"DETAILS": {
"NAME" : "US desk position report",
}
}
POST /event-cron-rule-amend HTTP/1.1
Host: localhost:9064
Content-Type: application/json
SESSION_AUTH_TOKEN: RSOo9rm3Y2PAopTKd1aW8E8Wu4Kkg97i
SOURCE_REF: 004
{
"DETAILS": {
"NAME" : "US desk position report",
}
}
EVENT_CRON_RULE_DISABLE
Disable an existing rule.
- Websocket API
- REST API
{
"USER_NAME": "admin",
"SOURCE_REF": "005",
"MESSAGE_TYPE": "EVENT_CRON_RULE_DISABLE",
"DETAILS": {
"NAME" : "US desk position report",
}
}
POST /event-cron-rule-disable HTTP/1.1
Host: localhost:9064
Content-Type: application/json
SESSION_AUTH_TOKEN: RSOo9rm3Y2PAopTKd1aW8E8Wu4Kkg97i
SOURCE_REF: 005
{
"DETAILS": {
"NAME" : "US desk position report",
}
}
DYNAMIC_RULE
API
EVENT_DYNAMIC_RULE_INSERT
Insert a new dynamic rule.
All parameters, descriptions and defaults are listed under DYNAMIC_RULE
configuration options
- Websocket API
- REST API
{
"USER_NAME": "admin",
"SOURCE_REF": "006",
"MESSAGE_TYPE": "EVENT_DYNAMIC_RULE_INSERT",
"DETAILS": {
"NAME" : "Warn large trade",
"DESCRIPTION" : "Trigger warning event on notional traded over 1,000,000",
"USER_NAME" : "admin",
"RULE_TABLE" : "TRADE_VIEW",
"RULE_STATUS" : "ENABLED",
"RULE_EXPRESSION" : "(NOTIONAL > 1000000)",
"MESSAGE_TYPE" : "EVENT_LARGE_TRADE_WARNING",
"RESULT_EXPRESSION" : "(TRADE_ID = TRADE_ID)",
"TABLE_OPERATION" : "INSERT",
"IS_TEMPLATE" : "true",
"RULE_EXECUTION_STRATEGY" : "ONCE_PER_RECORD",
}
}
POST /event-dynamic-rule-insert HTTP/1.1
Host: localhost:9064
Content-Type: application/json
SESSION_AUTH_TOKEN: RSOo9rm3Y2PAopTKd1aW8E8Wu4Kkg97i
SOURCE_REF: 006
{
"DETAILS": {
"NAME" : "Warn large trade",
"DESCRIPTION" : "Trigger warning event on notional traded over 1,000,000",
"USER_NAME" : "admin",
"RULE_TABLE" : "TRADE_VIEW",
"RULE_STATUS" : "ENABLED",
"RULE_EXPRESSION" : "(NOTIONAL > 1000000)",
"MESSAGE_TYPE" : "EVENT_LARGE_TRADE_WARNING",
"RESULT_EXPRESSION" : "(TRADE_ID = TRADE_ID)",
"TABLE_OPERATION" : "INSERT",
"IS_TEMPLATE" : "true",
"RULE_EXECUTION_STRATEGY" : "ONCE_PER_RECORD",
}
}
EVENT_DYNAMIC_RULE_AMEND
Amend an existing rule.
Changing to also trigger on modifications to the record.
All parameters, descriptions and defaults are listed under DYNAMIC_RULE
configuration options
- Websocket API
- REST API
{
"USER_NAME": "admin",
"SOURCE_REF": "007",
"MESSAGE_TYPE": "EVENT_DYNAMIC_RULE_AMEND",
"DETAILS": {
"ID" : "000000000000001DRLO1",
"NAME" : "Warn large trade",
"DESCRIPTION" : "Trigger warning event on notional traded over 1,000,000",
"USER_NAME" : "admin",
"RULE_TABLE" : "TRADE_VIEW",
"RULE_STATUS" : "ENABLED",
"RULE_EXPRESSION" : "(NOTIONAL > 1000000)",
"MESSAGE_TYPE" : "EVENT_LARGE_TRADE_WARNING",
"RESULT_EXPRESSION" : "(TRADE_ID = TRADE_ID)",
"TABLE_OPERATION" : "INSERT|MODIFY",
"IS_TEMPLATE" : "true",
"RULE_EXECUTION_STRATEGY" : "ONCE_PER_RECORD",
}
}
POST /event-dynamic-rule-amend HTTP/1.1
Host: localhost:9064
Content-Type: application/json
SESSION_AUTH_TOKEN: RSOo9rm3Y2PAopTKd1aW8E8Wu4Kkg97i
SOURCE_REF: 007
{
"DETAILS": {
"ID" : "000000000000001DRLO1",
"NAME" : "Warn large trade",
"DESCRIPTION" : "Trigger warning event on notional traded over 1,000,000",
"USER_NAME" : "admin",
"RULE_TABLE" : "TRADE_VIEW",
"RULE_STATUS" : "ENABLED",
"RULE_EXPRESSION" : "(NOTIONAL > 1000000)",
"MESSAGE_TYPE" : "EVENT_LARGE_TRADE_WARNING",
"RESULT_EXPRESSION" : "(TRADE_ID = TRADE_ID)",
"TABLE_OPERATION" : "INSERT|MODIFY",
"IS_TEMPLATE" : "true",
"RULE_EXECUTION_STRATEGY" : "ONCE_PER_RECORD",
}
}
EVENT_DYNAMIC_RULE_DELETE
Delete an existing rule.
- Websocket API
- REST API
{
"USER_NAME": "admin",
"SOURCE_REF": "008",
"MESSAGE_TYPE": "EVENT_DYNAMIC_RULE_DELETE",
"DETAILS": {
"ID" : "000000000000001DRLO1",
}
}
POST /event-dynamic-rule-delete HTTP/1.1
Host: localhost:9064
Content-Type: application/json
SESSION_AUTH_TOKEN: RSOo9rm3Y2PAopTKd1aW8E8Wu4Kkg97i
SOURCE_REF: 008
{
"DETAILS": {
"ID" : "000000000000001DRLO1",
}
}
EVENT_DYNAMIC_RULE_ENABLE
Enable an existing rule.
- Websocket API
- REST API
{
"USER_NAME": "admin",
"SOURCE_REF": "009",
"MESSAGE_TYPE": "EVENT_DYNAMIC_RULE_ENABLE",
"DETAILS": {
"ID" : "000000000000001DRLO1",
}
}
POST /event-dynamic-rule-enable HTTP/1.1
Host: localhost:9064
Content-Type: application/json
SESSION_AUTH_TOKEN: RSOo9rm3Y2PAopTKd1aW8E8Wu4Kkg97i
SOURCE_REF: 009
{
"DETAILS": {
"ID" : "000000000000001DRLO1",
}
}
EVENT_DYNAMIC_RULE_DISABLE
Disable an existing rule.
- Websocket API
- REST API
{
"USER_NAME": "admin",
"SOURCE_REF": "010",
"MESSAGE_TYPE": "EVENT_DYNAMIC_RULE_DISABLE",
"DETAILS": {
"ID" : "000000000000001DRLO1",
}
}
POST /event-dynamic-rule-disable HTTP/1.1
Host: localhost:9064
Content-Type: application/json
SESSION_AUTH_TOKEN: RSOo9rm3Y2PAopTKd1aW8E8Wu4Kkg97i
SOURCE_REF: 010
{
"DETAILS": {
"ID" : "000000000000001DRLO1",
}
}
Runtime configuration
The Evaluator process is not enabled by default. Override the genesis-processes.xml
file in your application and set <start>
to have a value of true. During your next build or genesisInstall
, the process will show up in your list of processes.
Evaluator should be left set to <primaryOnly>true</primaryOnly>
; otherwise, if deployed into a multi-node environment, events will be triggered multiple times.