Home Contact

 A Generic Framework for Context-Aware Applications.

About

Context-aware applications adapt their behavior based on adapation policies and according to information about their environment and their execution. The gathering of such information, "Monitoring", is made from sources such as user inputs and sensors. Building large scale context-aware application is challenging because of two difficulties: first, the number of data sources makes it hard to maintain a proper organisation, second, because the gigantic number of data produced makes it hard to extract meaningfull information.

WildCAT is a generic framework for context-aware applications. It helps coping with these issues by providing user with easy access to sensors through a hierarchical organization, and by providing user a power SQL-like language to express conditions upon which to trigger adaptation code.

Hierarchical Data Source Organization

Hierarchy

WildCAT let developers organize data sources inside a Context. A WildCAT context is an oriented tree structure with two types of nodes:

  • Attributes nodes that hold some value. attributes nodes are always leaf nodes, and every attributes has a unique parent node. There exists 3 types of attributes:
    • Basic attributes holds static values. Their values does not evolve unless programmaticaly modifed.
    • Active attributes (sensors)
    • Synthetic attributes are the results of expressions on other attributes
  • Resources nodes that can have zero or more children assuming every child name is unique. A resource may have more than one parent. There are two types of resources:
    • Basic resources.
    • Symbolic links are special resource that alters path resolution by pointing to another resource.

The example hierarchy presents three ressources (blue circles) and five attributes (red squares). Every WildCAT Context has a unique entrypoint: the ROOT ressource. Moreover a Context must never contain a cycle.

When manipulating a WildCAT context, developers reference ressources and attributes by their path from the ROOT ressource. WildCAT paths are a conveniant way for users to denotes ressources and attributes.

Exception made from the ROOT node, a node may be resolved through multiple paths: in our example, both paths "self://consts/maths" and "self://maths" denotes the same resource and the bottom left attribute may be resolved by "self://#pi", "self://maths#pi" or "self://consts/maths#pi".

Paths ending with "#name" denotes attributes. The context name "self" is a reserved name that is an equivalent of "localhost" in networking".

Modes of operation

WildCAT proposes two modes to inspect the content of a Context: PULL & PUSH.

PULL mode

In PULL mode, developers programmatically get and set attributes. The Context interface provides the get and set operations. This mode is described in the tutorial the pull mode. One can also consults the Java documentation for the Context Interface.

PUSH mode

In PUSH mode, developers register listener on queries expressed over the event generated in the Context. The Context interface provides operations to create queries and to register listeners on queries. To perform query processing, WildCAT relies on the Esper Complex Event Processing Engine. Queries are described in a dedicated language that extends the SQL paradigm with sliding windows and other features. While this dedicated language is briefly discussed in WildCAT documentations pages, those willing to fully exploit the EQL (Event Query Language) should refere to the Esper documentation and tutorials. On many aspects the Esper project is a must see.

WildCAT event model

WildCAT permits developers to inspect the content of a Context by registering queries on the event generated by the hierarchy. In WildCAT every events implements the WEvent interface. It allows to determine for every event, the node in the hierarchy which emitted the event (see: JavaDocs for String WEvent::getSource()).

There are two kinds of event emitted by a WildCAT context. Firstly, events emitted by Ressources: they instanciate the WHierarchyEvent Class and informs about the operation performed on the structure of the hierarchy. For example, such an event may indicate the addition of a attribute named "fs" to the resource "self://proc". Secondly, events emitted by Attributes instanciate the WAttributeEvent class and indicates the modification of that attribute and holds its new value.

WHierarchyEvents

WHierarchyEvents

reports on the operations performed on the hierarchy. They contains three attributes:

  • the path of the ressource that emitted the event.
  • the type of operation performed. There are 6 different types: corresponding to the addition/removal of a ressource/attribute/softlink.
  • the subject of the operation. Its correspond to the name of the resource/attribute/softlink added or removed.
Example

Let's see an example. The creation of the hierarchy presented in the image beside would have generate 4 events. First a WHierarchyEvent emitted by the ROOT node to indicate the creation of the ressource "const". Then, the newly created ressource would have emitted a WHierarchyEvent reporting the creation of the ressource "strings". Then, the latter ressource would have emitter a WHierarchyEvent for the creation of the attribute "hello". Finally, the attribute "self://consts/strings#hello" would have emitted a WAttributeEvent containing its inital value.

WAttributeEvents

WAttributeEvents are events emitted by attributes when their value changed. They indicate the path of the attribute emitting the event, and holds the new value of the attribute. As indicated before, attributes values are Plain Old Java Object. When following JavaBean namming conventions attributes value may be instrospected, i.e. given an attribute value Object has a "getName()" method, "name" can be accessed as an attribute of the Event. This introspection mecanism allows to write complex queries.

Writting queries

Queries allows developers to express conditions upon which to trigger an action (written as a Java Method). A Query listener implements the interface (net.esper.client.UpdateListener(EventBean[], EventBean[])). Queries are written in EQL (Event Query Language) a dedicated language part of the Esper CEP engine.

Let's consider a hierarchy with an attribute at "self://proc/cpu#info". Assuming the values of that attribute instanciate the following Class:

public class CPUInfo {
    long load;
    String model;

    public getLoad() {return this.load;}
    public getModel() {return this.model;}
    public getInfo() {return this.computeInfo();}

    public toString() {...}
}

The following query:

select * from WAttributeEvent(source="self://proc/cpu#info")

would be trigger on every WAttributeEvent emitted by attribute "self://proc/cpu#info". The actual content of the event passed to the Java handler would be the wrapping WAttributeEvent. Considering the following query:

select value from WAttributeEvent(source="self://proc/cpu#info")

this time, the content passed to the query is an instance of "CPUInfo". Finally, query:

select value.load from WAttributeEvent(source="self://proc/cpu#info")

would return only the "Long" value returned by method "getLoad" of class "CPUInfo".

Esper Event Query Language is very similar with the SQL Language. While SQL queries works on Database Tables. EQL works on sliding windows of Event. For example, the following query:

select avg(value.load) from WAttributeEvent(source="self://proc/cpu#info").win:length(5s)

is triggered on every WAttributeEvent emitted by attribute "self://proc/cpu#info" and "returns" the average value of the attribute "load" over every such events in the last five second.

Esper EQL provides with many interresting features among which: sliding windows, join, WHERE, GROUP BY, HAVING AND SORT CLAUSE, output limitations. The purpose of this documentation is not to describes those. Indeed, the Esper has high quality documentation describing the EQL language. Once again, I insist on how great that project is :)

Going further

In addition to the hierarchical organization of data source and PUSH/PULL operations, WildCAT allows for mixing PUSH and PULL and to connect distributed contexts.

The following example introduce a more complex usage of WildCAT's contexts. Again, basic resources are represented by blue circles and red squares marks basic attributes. In addition, red triangles indicates special "query" attributes, and yellow polygons represent symbolic links. Finally groups of nodes bordered in blue represent another WildCAT instance (possibly on a remote host).

Hierarchy

Special "query" attributes

WildCAT provides means to create attributes that holds the result of query. These special attribute called "query" attributes, are associated with a query. Query attributes can be used as normal attributes, i.e. their content can be accessed in PULL mode, it returns the last result of the query; and one can reference them in PUSH mode as part of a query. The tutorial covering the PUSH mode explain the creation and usage of such attributes.

Create sensor from passive data source

There are two kinds of sensors: passive sensors are attribute for which a getter retrieve a static value or a value changing in between calls; active sensors on the other hand whom value change dynamically and generate events notifying of those changes.

Passive sensors are often easier to implement. Thus, WildCAT provides means to simulate an active sensor based on a passive. The Context interface allows to register a periodic trigger to fabricate an event from an attribute. That trigger will fetch an attribute value on user-defined period and emit an WAttributeEvents. The creation of such periodic triggers is described in the PUSH mode tutorial

Connecting remote Contexts

WildCAT permits to connect remotes context using JMS and RMI technology. While one can directly inspect a remote context using the PULL api with an explicit remote path, WildCAT also permits the creation of symbolic links across contexts. PULL request over symbolic links are carried through RMI, while PUSH notification are done over JMS. The tutorial covering the PULL mode describes the creation of symbolic links and the remote context tutorial describes the setting up of distributed contexts.

Sensors

WildCAT is shipped with a set of commonly used sensors. While the purpose of the WildCAT project is not to build a sensor library, we provide to all the sensors we develop. WildCAT already contains the following one:

  • Java related
    • JavaRuntimeSensor provides information relative to the current JVM (processor, memory, etc)
    • SystemPropertiesSensor provides a wrapper for Java System Properties
    • MBeanCMDSensor allows for gathering of any JMX related information
  • System related (Linux-only)
    • KernelVersionSensor provides system kernel version
    • DateTimeSensor provides system current time
    • CPUSensor provides information (model, version, etc) of the CPU
    • CPULoadSensor provides instant CPU load

WildCAT sensors library is not restrictive. Indeed, WildCAT architecture allows the easy creation of sensors. A tutorial is devoted to describe the creation of usage of sensors. Copy- Pasting from existing sensors is the fasttest way to implement your own sensors.