Closed LukasPoque closed 2 years ago
short summary of the current draft:
There are two different types of events, namedEvents
which are defined by the publisher and customEvents
which are defined by the subscriber and need to be accepted by the publisher.
All event messages are routed via a RabbitMQ Topic Exchange named eventExchange
. To create/modify a new queue and bind to different event topics there is an endpoint in the S3I Config REST API.
All namedEvents
are predefined events that are described in the directory entry of the publishing thing. These events are published every time they are triggered, whether a queue is bound to the specific topic or not.
A namedEvent
directory entry is a JSON object with the event topic as parent key and description
and schema
fields. The description
stores a human-readable specification of this event. The schema
contains a JSON schema that describes the content field of the emitted Event Message
.
Example for THING_ID/attributes/
, where the thing emits an event with the topic newMeasurement
:
{
"ownedBy": "USER_UUID",
"name": "Awesom Thing Name",
"type": "component",
"allEndpoints": [
"ENDPOINT_ID"
],
"events": {
"newMeasurement": {
"description": "Contains the latest measurement including computed displacement",
"schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "newMeasurement",
"description": "JSON Schema for content field of this EventMessage",
"properties": {
"force": {
"type": "number"
},
"displacement": {
"type": "array",
"items": {
"type": "number"
}
}
}
}
}
}
}
events
field of the publishers directory entryA customEvent
can be requested by another thing (subscriber) by sending a subscriptionRequest
to the publisher via the normal direct exchange.
The request contains a filter
field to specify when the event should be triggered. The RQL language is used to define the trigger condition, see here for more information on how to create complex queries. The attributePaths
array defines what data should be included in the content
field of the custom EventMessage
. The values should be addressed as JSON pointers from the base of the thing (most times the pointer starts with attributes/
).
The topic of a customEvent
is always the md5 hash of the filter
and attribute
fields.
The event is emitted from the moment when subscriptionRequest
is received until there are no queues bound to the event topic (the message returns unroutable). So it's important to bind the queue before sending the subscriptionRequest
.
Subscription Request example:
{
"identifier": "s3i:UUIDv4",
"sender": "THING_ID",
"messageType": "customEventRequest",
"filter": "le(attributes/features/ml40::Force/force, 0)",
"attributePaths": [
"attributes/features/ml40::Force/force"
]
}
Subscription Response example:
{
"identifier": "s3i:UUIDv4",
"sender": "THING_ID",
"messageType": "customEventReply",
"topic": "THING_ID.eventTopic",
"ok": true,
}
topic
and attributePaths
of the customEventRequest
messagecustomEventRequest
message via the direct exchangeThe event messages are equal for both types of events. An event message is a subclass of the S3I::B::Message
and adds additional fields:
topic
(which event is triggered) timestamp
(when does the event took place)content
(the content of the event specified in the directory entry (for namedEvents
) or specified in the eventSubscriptionRequest/attributePaths
for customEvents
) {
"identifier": "s3i:UUIDv4",
"sender": "THING_ID",
"messageType": "eventMessage",
"topic": "THING_ID.eventTopic",
"timestamp": 10000, //millisecondsSinceEpocInt
"content": {
//EVENT_CONTENT
}
}
The S3I Event System is an important feature of the S3I. It enables things/services to "observe" another thing without the cloud storage (ditto) and allows customized event messages which are not directly related to a specific value (like an emergency) and could store customized values.