Skip to main content

Dynamic Flink CEP: JSON Rule Format

This page defines the JSON format for expressing Complex Event Processing (CEP) rules used by Dynamic Flink CEP. Use it to author, store, and update CEP patterns without changing Java code.

Audience

  • Risk control platform developers who integrate or encapsulate CEP rules.
  • Risk strategy authors who understand CEP concepts but prefer to write rules in JSON rather than Java.

Overview

A CEP pattern is modeled as a graph:

  • A node describes a pattern that matches specific events.
  • An edge describes the event selection strategy that moves from one node to the next.
  • Graphs can be nested, so a graph may act as a node in a larger graph.

The sections below specify the JSON objects used to describe nodes, quantifiers, conditions, edges, and composite graphs.

Node

A Node represents a complete pattern.

FieldDescriptionTypeRequiredNotes
namePattern nameSTRINGYesMust be unique within the graph.
typeNode typeENUM(STRING)YesATOMIC (no children) or COMPOSITE (has children).
quantifierPattern matching behaviourOBJECTYesSee Quantifier section.
conditionFilter for eventsOBJECTNoSee Condition section.

Quantifier

A Quantifier defines how frequently and in what manner a pattern should match.

FieldDescriptionTypeRequiredNotes
consumingStrategyEvent selectionENUM(STRING)YesSTRICT, SKIP_TILL_NEXT, SKIP_TILL_ANY. See the Contiguity section.
timesBounded repetitionOBJECTNoSee Times object.
propertiesAdditional matching propertiesARRAY<ENUM(STRING)>YesSee Quantifier properties.
untilConditionEarly stop for looping patternsOBJECTNoAllowed only with LOOPING. See the Condition section.

Times object

A Times object specifies lower/upper bounds and an optional inner window.

"times": {
"from": 3,
"to": 3,
"windowTime": {
"unit": "MINUTES",
"size": 12
}
}
  • from, to: INTEGER values.

  • windowTime: may be null, or an object with:

    • unit: DAYS | HOURS | MINUTES | SECONDS | MILLISECONDS
    • size: numeric (INTEGER or LONG).

Note: When no inner window is required, set "windowTime": null.

Condition

A Condition filters events for a node.

FieldDescriptionTypeRequiredNotes
typeCondition typeENUM(STRING)YesCLASS
...Custom, serializable fieldsvariesNoAllowed for extensibility.

CLASS condition

Use a custom Java class to evaluate the condition.

FieldDescriptionTypeRequired
typeMust be CLASSSTRINGYes
classNameFully qualified class nameSTRINGYes

Example

{
"type": "CLASS",
"className": "ververica.cep.demo.StartCondition"
}

CLASS with custom parameters

Use when you need to update parameters dynamically without recompiling code.

FieldDescriptionTypeRequired
typeMust be CLASSSTRINGYes
classNameFully qualified class nameSTRINGYes
argsCustom parametersARRAY<STRING>Yes

Example

{
"type": "CLASS",
"className": "ververica.cep.demo.CustomMiddleCondition",
"args": ["A", "B", "C"]
}

AVIATOR condition

Evaluate an Aviator expression that you can update at runtime.

FieldDescriptionTypeRequired
typeMust be AVIATORSTRINGYes
expressionExpression stringSTRINGYes

Example

{
"type": "AVIATOR", # Aviator is lightweight scripting language that compiles to the Java bytecode.
"expression": "price > 10"
}

GROOVY condition

Evaluate a Groovy expression that you can update at runtime.

FieldDescriptionTypeRequired
typeMust be GROOVYSTRINGYes
expressionExpression stringSTRINGYes

Example

{
"type": "GROOVY", # Groovy is a flexible and an extensible Java-like language that compiles to the Java bytecode.
"expression": "price > 5.0 && name.contains(\"mid\")"
}

Edge

An Edge connects two nodes and defines the event selection strategy between them.

FieldDescriptionTypeRequired
sourceName of the source patternSTRINGYes
targetName of the target patternSTRINGYes
typeContiguity strategyENUM(STRING)Yes

Valid values for type: STRICT, SKIP_TILL_NEXT, SKIP_TILL_ANY, NOT_FOLLOW, NOT_NEXT. See the Contiguity section.

GraphNode (extends Node)

A GraphNode is a composite pattern sequence. Each item in nodes is an independent Node; each item in edges specifies how to transition between them.

Additional fields on top of Node:

FieldDescriptionTypeRequiredNotes
nameComposite pattern nameSTRINGYesMust be unique.
typeMust be COMPOSITEENUM(STRING)Yes
versionJSON spec versionINTEGERYesDefault: 1.
nodesChild patternsARRAY<Node>YesMust be non-empty.
edgesConnections between child patternsARRAY<Edge>YesMay be empty.
windowTime window policyOBJECTNoSee Graph window.
afterMatchSkipStrategySkip strategy after a full matchOBJECTYesSee AfterMatchSkipStrategy.
quantifierComposite pattern matching behaviourOBJECTYesSee Quantifier.

Graph window

Two window semantics are supported:

  • FIRST_AND_LAST: Maximum time between the start and end of a full composite match.
  • PREVIOUS_AND_CURRENT: Maximum time between adjacent child pattern matches.

Example

"window": {
"type": "FIRST_AND_LAST",
"time": {
"unit": "DAYS",
"size": 1
}
}
  • unit: DAYS | HOURS | MINUTES | SECONDS | MILLISECONDS
  • size: numeric (INTEGER or LONG).

AfterMatchSkipStrategy

Controls which partial matches are kept or discarded after a match is emitted.

FieldDescriptionTypeRequiredNotes
typeStrategy typeENUM(STRING)YesOne of the values below.
patternNamePattern name used by some strategiesSTRINGNoRequired by SKIP_TO_FIRST / SKIP_TO_LAST.

Valid type values

  • NO_SKIP — return every successful match (default).
  • SKIP_TO_NEXT — discard partial matches that start with the same event.
  • SKIP_PAST_LAST_EVENT — discard partial matches that start between the beginning and end of the emitted match.
  • SKIP_TO_FIRST — discard partial matches that start between the beginning of the match and the first occurrence of patternName.
  • SKIP_TO_LAST — discard partial matches that start between the beginning of the match and the last occurrence of patternName.

Event Selection

ValueDescription
STRICTStrict contiguity. No unmatched events may appear between matched events.
SKIP_TILL_NEXTRelaxed contiguity. Ignore unmatched events between matches.
SKIP_TILL_ANYNon-deterministic relaxed contiguity. Allows additional matches for the same event.
NOT_NEXTThe event immediately after a given event must not be a specified event.
NOT_FOLLOWA specified event must not appear later in the sequence.

Quantifier properties

ValueDescription
SINGLEThe pattern occurs exactly once.
LOOPINGThe pattern may occur multiple times (similar to * or + in regex).
TIMESThe pattern must occur a specified number of times.
GREEDYPrefer the maximum number of matches.
OPTIONALThe pattern is optional.

Examples

Example 1 — Common pattern

Goal (10‑minute window during a promotion):

  1. User obtains venue coupons (StartCondition) once — optional.
  2. User adds items to cart (MiddleCondition) at least 3 times.
  3. User does not complete payment (EndCondition).

Equivalent Java

Pattern<Event, Event> pattern =
Pattern.<Event>begin("start")
.where(new StartCondition())
.optional()
.followedBy("middle")
.where(new MiddleCondition())
.timesOrMore(3)
.notFollowedBy("end")
.where(new EndCondition())
.within(Time.minutes(10));

JSON

{
"name": "end",
"quantifier": {
"consumingStrategy": "SKIP_TILL_NEXT",
"properties": ["SINGLE"],
"times": null,
"untilCondition": null
},
"condition": null,
"nodes": [
{
"name": "end",
"quantifier": {
"consumingStrategy": "SKIP_TILL_NEXT",
"properties": ["SINGLE"],
"times": null,
"untilCondition": null
},
"condition": {
"className": "ververica.cep.demo.condition.EndCondition",
"type": "CLASS"
},
"type": "ATOMIC"
},
{
"name": "middle",
"quantifier": {
"consumingStrategy": "SKIP_TILL_NEXT",
"properties": ["LOOPING"],
"times": {"from": 3, "to": 3, "windowTime": null},
"untilCondition": null
},
"condition": {
"className": "ververica.cep.demo.condition.MiddleCondition",
"type": "CLASS"
},
"type": "ATOMIC"
},
{
"name": "start",
"quantifier": {
"consumingStrategy": "SKIP_TILL_NEXT",
"properties": ["SINGLE", "OPTIONAL"],
"times": null,
"untilCondition": null
},
"condition": {
"className": "ververica.cep.demo.condition.StartCondition",
"type": "CLASS"
},
"type": "ATOMIC"
}
],
"edges": [
{"source": "middle", "target": "end", "type": "NOT_FOLLOW"},
{"source": "start", "target": "middle", "type": "SKIP_TILL_NEXT"}
],
"window": {
"type": "FIRST_AND_LAST",
"time": {"unit": "MINUTES", "size": 10}
},
"afterMatchSkipStrategy": {"type": "NO_SKIP", "patternName": null},
"type": "COMPOSITE",
"version": 1
}

Example 2 — Condition with custom parameters

You can tailor marketing actions to customer classes without recompiling. Define a class-based condition and adjust its args list at runtime.

Initial condition

{
"type": "CLASS",
"className": "org.apache.flink.cep.pattern.conditions.CustomMiddleCondition",
"args": ["A", "B"]
}

Updated condition

{
"type": "CLASS",
"className": "org.apache.flink.cep.pattern.conditions.CustomMiddleCondition",
"args": ["A", "B", "C"]
}

Notes

  • Aviator and Groovy are third‑party technologies.
  • Use LOOPING with untilCondition to stop repetitions early when needed.
  • Prefer afterMatchSkipStrategy over post‑processing filters to control overlap and throughput explicitly.