Event Stream API
API for Event Stream events |
Type | JAR |
Category | API |
Developed by | |
Rating | |
License | GNU Lesser General Public License 2.1 |
Bundled With | XWiki Standard |
Table of contents
Description
The Event stream module offers APIs to manipulate activity events. An activity event is a recorded event that occurred at some point in the wiki.
You can define custom events inside wiki pages through the EventClass XObject.
Events
Events are identified by:
- an identifier unique for each event
- a group identifier used for all the events caused during the same action
- the exact date and time when the event occurred
- an importance which allows to order events in the same group, or in the same stream
Events contain:
- a title
- a body
- and a map of custom properties
Events are categorized into:
- the application that created them, like blog, user statuses, or the general wiki
- an eventual sub-stream inside the application, for example a space for wiki events, or a certain group for user statuses
- the particular type of event, like adding a comment, updating an attachment, setting a new user status
Events target:
- the wiki,
- the space,
- and the document affected by the event
- and an eventual entity inside the document, for example an individual attachment for attachment events, or an individual object for comment events.
Events can store some more information about the context in which they occur:
- the user that caused the event
- the version of the target document at the time that the event occurred
- the display title of the target document at the time that the event occurred
- the requested URL that caused the event
If the Solr-based event store is enabled (the default), events can also store a map of custom properties.
The default implementation support the following types for the properties values:
- String
- Double
- Float
- Long
- Integer
- Boolean
- Date
- byte[]
- Iterable or array of the previously listed types in input (converted to List)
Stores
A Solr-based store is the default location where events are stored and from which they are retrieved.
The legacy store (database one) is currently still populated with the events and used as fallback for deprecated APIs which are not yet fully supported by the new event store API and/or Solr implementation (a good example being the HQL based search API which will most probably never be supported by the new store).
Code Samples
Java
Adding an event to the event store
// Some imports we will need :
import org.xwiki.eventstream.Event;
import org.xwiki.eventstream.EventFactory;
import org.xwiki.eventstream.EventStore;
// [...]
// Some requirements to add events :
@Inject
private EventFactory eventFactory;
@Inject
private EventStore eventStore;
// [...]
// Adding an event to the stream :
Event event = this.eventFactory.createEvent();
event.setDocument(someDocument.getDocumentReference());
event.setApplication("yowler"); // (It's like twitter, but only for cats)
event.setType("yowl");
Map<String, String> params = new HashMap<String, String>();
params.put("yowled", "meoooow !");
event.setParameters(params);
// All write operation of the store are asynchonous and return a CompletableFuture
CompletableFuture<Event> future = this.eventStore.saveEvent(event);
// Wait for the event to be stored
future.get();
Note that directly adding an event to the store is generally a bad practice and the best practice is to sent an event implementing org.xwiki.eventstream.RecordableEvent in the ObservationManager.
Retrieving events from the store
import org.xwiki.eventstream.query.SimpleEventQuery;
import org.xwiki.eventstream.query.SortableEventQuery.SortClause.Order;
SimpleEventQuery query = new SimpleEventQuery();
// Only return events for which the application is "yowler"
query.eq(Event.FIELD_APPLICATION, "yowler");
// Since 13.9 it's possible to manipulate custom event parameters
query.parameter().eq("mycustomperameter", "myvalue");
// Since 14.2 the custom parameters are deprecated and replaced with more generic custom properties with support for various other types than String
query.custom().eq("mycustomnumber", 42);
// Search for events in which the custom list property "mycustomlist" has one of its elements equal to "element1"
query.custom(List.class).eq("mycustomlist", "element1");
// Since 14.4RC1 it's possible to search for text contained in a field
query.contains(Event.FIELD_DOCUMENTTITLE, "Hello");
// Filter out all events triggered by superadmin
query.not().eq(Event.FIELD_USER, "xwiki:XWiki.superadmin");
// Sort events by date in descending order
query.addSort(Event.FIELD_DATE, Order.DESC);
// Limit the number of result to return
query.setLimit(15);
EventSearchResult result = this.eventStore.search(query)
result.stream().forEach((event) -> {
// Do anything with those events
});
Define custom events in wiki pages
The EventClass XObject allows anyone with the admin rights on the current wiki to define a custom event. In order to demonstrate how a custom event definition can be useful, we will use one event defined in the Blog application that should be triggered when a blog post is published, and "translate" it into its equivalent XObject definition.
First of all, we have to create an XObject of type EventClass in any wiki page (a hidden page with restricted access rights is still preferred). This XObject has several parameters :
- Application: The name of the application related to the event;
- Event Type: The type (name) of the event;
- Event Icon: The name of the icon associated to the event;
- Event description: A short description of the event that can be displayed to the user;
- Listen to …: A list of events that can be used to trigger this custom event. Only one event in this list is needed to trigger the custom event.
- Object Type: A list of XObject types that should be linked to the document that is the source of the event, note that you can leave this field blank in case where one of the triggering events defined in the Listen to … field doesn’t have a particular document attached to it;
- Validation Template: In this template, you can define specific conditions in order to allow (or not) the triggering of the custom event :
- The template comes with two additional context variables :
- event: the event, which is an instance of one of the classes defined in the Listen to … field;
- source: the source of the event;
In order to validate the triggering of the custom event, the template should affect the value "true" to the variable "xreturn". Example: #set ($xreturn = true);
- If the Validation Template field is left blank, the template rendering will be ignored.
- The template comes with two additional context variables :
- Target: In this template, you can define a list of users to which the event will be sent. Other users will not see this event.
- The template comes with two additional context variables :
- event: the event, which is an instance of one of the classes defined in the Listen to … field;
- source: the source of the event;
In order to generate the target list, the template should affect a list of user id (serialized references of the users) to the variable "xreturn". Examples: #set ($xreturn = ['xwiki:XWiki.UserA', 'xwiki:XWiki.UserB']) or #set ($xreturn = [$services.model.serialize($event.user, 'default')]).
- The template comes with two additional context variables :
Here is one example of an XObject that copy the same comportment of the BlogPostPublishedEvent in the Blog application :
Once your XObject is defined … everything is done! The event is now registered. If you use the notifications application provided by default with XWiki Platform, every user should now see the custom event in their notification center, and should be able to subscribe to it :
Example of an event (notification) sent to a particular user only if the wiki handle the TargetableEvents
- field: Validation Expression:#set ($xreturn = true)
- field: Target:## Example: send the event to the creator of the document only
#set ($document = $xwiki.getDocument($event.document))
#set ($xreturn = [$services.model.serialize($document.creatorReference, 'default')])
When to use Untyped Event instead of creating your own RecordableEvent
If you are a Java developer, you may prefer to create your own class that implement the RecordableEvent interface (as explained in Tutorial: How to send notifications).
But if you don't want to add a Java module in your extension you should used this Custom Event mechanism. Old XWiki versions will only ignore this XObject.
Events sent by the Event Stream
The Event Stream can send two new events :
- EventStreamAddedEvent: Used when a new event is inserted in the Event Stream.
- EventStreamDeletedEvent: Used when a new event is removed from the Event Stream.
Links
You can find out more checking out this module source code :
https://github.com/xwiki/xwiki-platform/tree/master/xwiki-platform-core/xwiki-platform-eventstream
Prerequisites & Installation Instructions
We recommend using the Extension Manager to install this extension (Make sure that the text "Installable with the Extension Manager" is displayed at the top right location on this page to know if this extension can be installed with the Extension Manager).
You can also use the manual method which involves dropping the JAR file and all its dependencies into the WEB-INF/lib folder and restarting XWiki.
Dependencies
Dependencies for this extension (org.xwiki.platform:xwiki-platform-eventstream-api 16.8.0):
- org.xwiki.commons:xwiki-commons-component-api 16.8.0
- org.xwiki.platform:xwiki-platform-query-manager 16.8.0
- org.xwiki.platform:xwiki-platform-model-api 16.8.0
- org.xwiki.platform:xwiki-platform-localization-api 16.8.0
- org.xwiki.platform:xwiki-platform-wiki-api 16.8.0
- org.xwiki.platform:xwiki-platform-template-api 16.8.0
- org.xwiki.platform:xwiki-platform-bridge 16.8.0
- org.xwiki.platform:xwiki-platform-observation-remote 16.8.0