## 4 CEP Model: Transforming IoT Events to Meaningful Business Domain Events
Raw input data are consumed from the topics and then processed (aggregated, enriched) or otherwise transformed and forwarded into new topics for further consumption or follow-up processing. Such processing pipelines create (conceptual) directed acyclic graphs (DAGs) of real-time data flows based on individual topics. An **event stream** (henceforth stream), in turn, is an essential abstraction of CEP: it represents an unbounded, continuously updating data set representing a flow with chunks of information. Events that are part of the same stream are neither necessarily ordered nor of the same kind. Instead, they are information chunks with semantics and relationships (including total or partial ordering, in some cases). Technically, an event stream is an ordered, replayable, and fault-tolerant sequence of immutable data records, where a data record is defined as a key-value pair. An **event stream processing application** (henceforth application) is a dynamically defined computational logic through one or more event stream processor topologies, where an **event stream processor topology** (henceforth topology) is a graph (DAG) of event stream processors (graph nodes) that are connected by event streams (graph edges). An **event stream processor** (henceforth processor) is a node in the topology. It represents a processing step to transform data in streams by receiving one input record at a time from its upstream processors in the topology, applying its operation to this, and may subsequently produce one or more output records for its downstream processors. There are two special kinds of processors:  
A **source processor** does not have any upstream processors. It produces an input stream to its topology from one or multiple topics by consuming records from these topics and forwarding them to its downstream processors. A **sink processor** does not have downstream processors. It sends any received records from its upstream processors to a specified topic. Each processor reflects a transformation, i.e., processing. Some of the most well-known transformations are _map_, _filter_, _group_, _join_, and others, such as those presented in the Apache Kafka Streams Developer Guide [44]. The above transformations are primitive and are usually encountered as they are with expected behavior, input, and output. However, a transformation can be complex. It can have a state and communicate with a database or external system. For example, a complex transformation is a time-windowed average value calculation considering filtered values based on some condition. Another example of a complex transformation is detecting an anomaly in a data flow or performed by some other component, e.g., an external machine learning system. An application may have one or more topologies. A topology may have one or more sub-topologies. A sub-topology may have one or more processors. Collectively, they constitute a set of processing rules describing how incoming streams of events must be processed to produce new streams as outputs in a timely manner. Technically, there are two ways to define the topology: (i) the DSL, which provides the most common transformation operations such as map, filter, join, and aggregation and (ii) the low-level processor contract, which allows developers to define and implement custom processor as well as to interact with state stores. Other technical details, such as data interchange, serialization, deserialization, batch processing, topics, processing guarantees, and others, are then presented in Section 5,which follows, while an exemplification of the overall architecture is presented through some scenarios.