www.espertech.comDocumentation

Chapter 1. Getting Started

1.1. Introduction to Complex Event Processing
1.2. Introduction to the Architecture
1.3. Introduction to EPL
1.4. Compiler Getting-Started
1.4.1. Compiler - Step One: Setting up the Compiler Classpath
1.4.2. Compiler - Step Two: Provide Information on Input Events
1.4.3. Compiler - Step Three: Compiling EPL
1.5. Runtime Getting-Started
1.5.1. Runtime - Step One: Setting up the Runtime Classpath
1.5.2. Runtime - Step Two: Obtain Runtime
1.5.3. Runtime - Step Three: Deploy EPL Compiled Module and Attach a Callback
1.5.4. Runtime - Step Four: Send Events
1.6. Required 3rd Party Libraries
1.6.1. Common Required 3rd Party Libraries
1.6.2. Compiler - Required 3rd Party Libraries
1.6.3. Runtime - Required 3rd Party Libraries

The Esper compiler and runtime have been developed to address the requirements of applications that analyze and react to events. Some typical examples of applications are:

What these applications have in common is the requirement to process events (or messages) in real-time or near real-time. This is sometimes referred to as complex event processing (CEP) and event series analysis. Key considerations for these types of applications are throughput, latency and the complexity of the logic required.

The EPL compiler and runtime were designed to make it easier to build and extend CEP applications.

More information on CEP can be found at FAQ.

Esper is a language, a language compiler and a runtime environment.

The Esper language is the Event Processing Language (EPL). It is a declarative, data-oriented language for dealing with high frequency time-based event data. EPL is compliant to the SQL-92 standard and extended for analyzing series of events and in respect to time.

The Esper compiler compiles EPL source code into Java Virtual Machine (JVM) bytecode so that the resulting executable code runs on a JVM within the Esper runtime environment.

The Esper runtime runs on top of a JVM. You can run byte code produced by the Esper compiler using the Esper runtime.

The Esper architecture is similar to that of other programming languages that are compiled to JVM bytecode, such as Scala, Clojure and Kotlin for example. Esper EPL however is not an imperative (procedural) programming language.

The Esper language is the Event Processing Language (EPL) designed for Complex Event Processing and Streaming Analytics.

EPL is organized into modules. Modules are compiled into byte code by the compiler. We use the term module for an EPL source code unit.

A module consists of statements. Statements are the declarative code for performing event and time analysis. Most statements are in the form of "select ... from ...". We use the term statement for each unit of declarative code that makes up a module.

Your application receives output from statements via callback or by iterating current results of a statement.

A statement can declare an EPL-object such as listed below:

Use access modifiers such as private, protected and public to control access to EPL-objects.

A module can optionally have a module name. The module name has a similar use as the package name or namespace name in a programming language. A module name is used to organize EPL objects and to avoid name conflicts.

When deploying a compiled module the runtime assigns a deployment id to the deployment. The deployment id uniquely identifies a given deployment of a compiled module. A compiled module can be parameterized and deployed multiple times.

A statement always has a statement name. The statement name identifies a statement within a deployed module and is unique within a deployment. The combination of deployment id and statement name uniquely identifies a statement within a runtime.

EPL is type-safe in that EPL does not allow performing an operation on an object that is invalid for that object.

Your application can obtain a compiler calling the getCompiler static method of the EPCompilerProvider class:

EPCompiler compiler = EPCompilerProvider.getCompiler();

The step-by-step provides a Configuration object to the compiler that adds the predefined person event:

Configuration configuration = new Configuration();
configuration.getCommon().addEventType(PersonEvent.class);

The sample module for this getting-started section simply has one statement that selects the name and the age of each arriving person event. It specifies a statement name using the @name annotation and assigns a name my-statement to the statement.

@name('my-statement') select name, age from PersonEvent

Compile a module by using the compile method passing the configuration as part of the compiler arguments:

CompilerArguments args = new CompilerArguments(configuration);
			
EPCompiled epCompiled;
try {
  epCompiled = compiler.compile("@name('my-statement') select name, age from PersonEvent", args);
}
catch (EPCompileException ex) {
  // handle exception here
  throw new RuntimeException(ex);
}

Upon compiling this module, the compiler verifies that PersonEvent exists since it is listed in the from-clause. The compiler also verifies that the name and age properties are available for the PersonEvent since they are listed in the select-clause. The compiler generates byte code for extracting property values and producing output events. The compiler builds internal data structures for later use by filter indexes to ensure that when a PersonEvent comes in it will be processed fast.

More information on the compile API can be found at Chapter 15, Compiler Reference and the JavaDoc.