Overview
With the Apama Event Processing Language, it is possible to utilize functions, called “actions”. Every monitor will have at least one action - the “onload” action. This section covers the already built-in actions ready to use.
See also the Apama EPL reference for actions on built-in types.
Querying Cumulocity data
To interact with your historical data, you can use one of the following request-response event pairs to lookup resources.
Example: To lookup for Alarms, you can send a FindAlarm request event with appropriate query parameters to FindAlarm.CHANNEL channel, in response you can expect 0 or more FindAlarmResponse events (depending on the number of resources that match the lookup request) and a FindAlarmResponseAck event on the FindAlarmResponse.CHANNEL channel. Similar functionality is also provided for lookup of ManagedObjects, Events, Measurements and Operations.
To lookup | Request-Response Events | Example |
---|---|---|
ManagedObject | FindManagedObject FindManagedObjectResponse FindManagedObjectResponseAck |
Example |
Alarm | FindAlarm FindAlarmResponse FindAlarmResponseAck |
Example |
Event | FindEvent FindEventResponse FindEventResponseAck |
Example |
Measurement | FindMeasurement FindMeasurementResponse FindMeasurementResponseAck |
Example |
Operation | FindOperation FindOperationResponse FindOperationResponseAck |
Example |
Invoking HTTP services
To interact with HTTP services using REST and JSON, create an HttpTransport instance using one of the factory methods:
- HttpTransport.getOrCreate(string host, integer port) returns HttpTransport
- HttpTransport.getOrCreateWithConfiguration(string host, integer port, dictionary <string, string> configurations) returns HttpTransport (the keys in the configurations dictionary are the constants on HttpTransport with CONFIG_ prefix)
On the HttpTransport object, call one of the create methods, passing a path and payload as needed, to produce a Request object.
On the Request object, you may set cookies, headers or query parameters as needed, and can then invoke the request with the execute(action<Response> callback). Supply the name of an action in your monitor for the callback, and it will be invoked with the Response when the request has completed (or timed out).
In the callback, the Response object is supplied with statusCode and payload. Fields on the payload are accessible via the AnyExtractor object it is supplied in - see access fragments below.
Refer to the ApamaDoc for further details.
Utility functions
Access fragments
You can access fragments via the params dictionary of most events. AnyExtractor object can be constructed to help you extract data from any objects containing multiple sub-fragments and access:
-
action getInteger(string path) returns integer
-
action getFloat(string path) returns float
-
action getString(string path) returns string
-
action getBoolean(string path) returns boolean
-
action getSequence(string path) returns sequence<any>
-
action getDictionary(string path) returns dictionary<any, any>
You can use a JSON path to navigate in the object structure. Example:
string s := AnyExtractor(measurement.params["fragment"]).getString("sub.fragment.object");
Example “fragment” : “c8y_TemperatureMeasurement”. Example “sub.fragment.object” : “c8y_TemperatureMeasurement.T.Unit”.
Casting “any” values
Alternatively, use a cast to convert an any
to a particular type:
string s := <string> measurement.params["strfragment"];
Note that a cast operation will throw if the object is of a different type.
currentTime and the TimeFormatter
The read-only variable currentTime can be used to obtain the current server time. Apama deals with time using seconds since the Unix Epoc (1 Jan 1970 UTC). You can easily transform it to a human-readable form using the TimeFormat object.
Example:
send Event("", "c8y_HighTemperatureEvent", measurement.source, currentTime, "High temperature started at "+TimeFormat.format(currentTime, "yyyy.MM.dd G 'at' HH:mm:ss"), new dictionary<string,any>) to Event.CHANNEL;
inMaintenanceMode
The Util.inMaintenanceMode() function is a fast way to check if the device is currently in maintenance mode. It takes a ManagedObject as a parameter and returns a boolean which is true if the device is in maintenance mode.
Example:
using com.apama.cumulocity.Measurement;
using com.apama.cumulocity.Event;
using com.apama.cumulocity.FindManagedObject;
using com.apama.cumulocity.FindManagedObjectResponse;
using com.apama.cumulocity.FindManagedObjectResponseAck;
using com.apama.cumulocity.Util;
monitor ExampleMonitor {
action onload() {
monitor.subscribe(FindManagedObjectResponse.CHANNEL);
on all Measurement() as m {
integer reqId := integer.getUnique();
send FindManagedObject(reqId, m.source, new dictionary<string,string>) to FindManagedObject.CHANNEL;
on FindManagedObjectResponse(reqId = reqId, id = m.source) as d and not FindManagedObjectResponseAck(reqId = reqId) {
if not Util.inMaintenanceMode(d.managedObject) {
send Event("", "c8y_Event", m.source, currentTime, "Received measurement from active device", new dictionary<string,any>) to Event.CHANNEL;
}
}
}
}
}
replacePlaceholders
To build strings, you can use concatenation as follows:
string s:= "An event with the text " + evt.text + " has been created.";
If the texts get longer and have more values that are dynamically set from the data, you can use the Util.replacePlaceholders() function. In your text string, you mark the placeholders with the field name from the event and surround it by #{}. The second parameter to replacePlaceholders can be any event type.
myMailText := Util.replacePlaceholders("The device #{source} with the serial number #{c8y_Hardware.serialNumber} created an event with the text #{text} at #{time}. The device is located at #{c8y_Address.street} in #{c8y_Address.city}.", evt);