Event Stream Module
![]() | Activity events manipulation API |
Type | JAR |
Category | |
Developed by | Unknown |
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.
Note that since XWiki 9.6RC1, you can also 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 "parameters" (14.2+ API renamed to "custom")
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
14.2+
If the new 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
Before 12.6 by default all the events are stored in the XWiki relational database. Since 12.6 a new Solr based store is now the default location where events are stored and from which they are retrieved. A migrator is available since 12.6.1 in the Distribution Wizard and in the Wiki Adminsitration to copy events from the old store to the new one.
The legacy store 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 (XWiki 12.5+)
// 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 (XWiki 12.5+)
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
Since XWiki 9.6RC1, 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
- 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')]).
: 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 :
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:## The "xreturn" binding is supported since 9.11.2, which mean older xwiki versions won't send this event
#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, or if you don't want to depend to a recent version of XWiki and still support XWiki versions older than 9.11.2, you should used this Custom Event mechanism. Old XWiki versions will only ignore this XObject.
Events sent by the Event Stream
Since XWiki 9.6RC1, 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