This tutorial describes how to use Drools and the Gnostic service for rule based SLA Management. The tutorial is composed of the following sections:
Using this support, services can have SLAs attached to them, ensuring operational criteria is met. The dynamic service's operational behavior can be monitored to dynamically scale it's environment up & down based on declarative attributes, be relocated, or trigger specific response(s) based on observed stimulus.
The diagram below shows the architecture used to provide the support for observed system and application defined metrics. The approach is based on a sensor-effector pattern. Data is observed from applications, OS, hardware, etc ... and feed into SLA Management and Policy Enforcement.
Where the SLA Rule approach fits in is in Policy Enforcement. Rio provides a service called Gnostic, that provides a distributed point that coalesces metrics collected by services to a Complex Event Processing (CEP) engine. The CEP that the Gnostic service currently provides support for is Drools Fusion.
Why Gnostic? Gnostic comes from one of the Greek words for knowledge, or Gnosis
The CEP provides a way to add events collected from observed system and application defined metrics, and accumulate temporal knowledge that rules are then executed on. Rule execution results in actions taken based on the conditions that are met.
A rule is structured as follows:
rule "name"
when
<conditions>
then
<actions>;The rule structure above specifies that when a particular set of conditions occur, specified in the Left Hand Side (LHS), then do what is specified as a list of actions in the Right Hand Side (RHS).
An example of a rule (taken from the Hospital example) follows:
declare CalculablePatient
@role(event)
@timestamp(date)
end
rule "Patient Alert Rule"
when
$p : CalculablePatient(id == "pulse", value < 50) from entry-point "calculables-stream"
then
Patient p = $p.getPatient();
Doctor d = p.getDoctor();
d.patientAlert(p);
endIn the rule above, every patient has a pulse. There is a "pulse" watch created that monitors each patient's pulse. The CalculablePatient event contains the pulse value, and the Patient object. If the pulse drops below 50, the patient's Doctor is notified.
The LHS deals with determining if a patient's pulse drops below 50. If this condition is met, the RHS executes, notifying the Doctor.
Note that this is not a tutorial for writing Drools rules.
Please refer to available documentation for
Drools Expert and
Drools Fusion.
So why do this using a rule and not programmatically? Good question :)
The Gnostic is a service that is dynamically deployed, just like any other service you need to have running. The Gnostic is configured as part of your opstring (deployment) configuration, and you wire up the Gnostic with service feeds, that direct metrics from the service to Gnostic, where the events are added to the Gnostic's CEP as temporal data.
Once the rule executes, the RHS can perform actions on services or ask Rio to increment or decrement service instances, relocate services, deploy additional services, or act directly on your services.
Each rule has a global org.rioproject.gnostic.DeployedServiceContext set, providing context on deployed services. The DeployedServiceContext class provides the support for the RHS of the rule to interface with Rio, and/or obtain a proxy for an associated service enabling the RHS to invoke methods on specific service instances.
The example below is from the Hospital example. It shows a rule that checks if there are enough Beds in the Hospital. If the number of Beds is 0, the DeployedServiceContext is used to increment (scale), the number of available Beds.
global org.rioproject.gnostic.DeployedServiceContext context;
declare Calculable
@role(event)
@timestamp(date)
end
rule "Available Bed Rule"
when
$beds : Calculable(id == "availableBeds", value == 0) from entry-point "calculables-stream"
then
context.increment("Beds", "Hospital");
end
An extension to the Rio DSL allows the inline declaration of rules and the required attributes needed to load, create and provide the necessary inputs for the rule(s) to operate.
The syntax diagram for the rules declaration is shown here:



The rules declaration results in the creation of a Gnostic service configured with rule elements. Each rule has a:
An example follows:
rules {
rule {
resource 'DoctorRule, PatientAlert, AvailableBedRule'
ruleClassPath 'org.rioproject.examples.hospital:hospital-rule:2.0'
serviceFeed(name: "Doctors") {
watches "numPatients"
}
serviceFeed(name: "Beds") {
watches "pulse"
}
serviceFeed(name: "Admission") {
watches "availableBeds"
}
}
}
For declaring serviceFeed watch names that are to be bound to system oriented watches like JVM Memory, CPU utilization, the following constants can be used:
| Constant | Explanation |
|---|---|
| SystemWatchID.SYSTEM_CPU | A watch that observes CPU utilization for a compute resource. |
| SystemWatchID.PROC_CPU | A watch that observes CPU utilization for the process (JVM) the service is running in. |
| SystemWatchID.DISK_SPACE | A watch that observes diskspace utilization for a compute resource. |
| SystemWatchID.SYSTEM_MEMORY | A watch that observes system memory utilization for a compute resource. |
| SystemWatchID.JVM_MEMORY | A watch that observes memory utilization for the process (JVM) the service is running in. |
| SystemWatchID.JVM_PERM_GEN | A watch that observes memory the permanent generation utilization for the process (JVM) the service is running in. |