Fork me on GitHub

Observation

Jackrabbit Oak as part of JCR implementation provides support for observing content changes via EventListener. Event listeners are notified asynchronously, and see events after they occur and the transaction is committed. EventListener can provide a filtering criteria for the type of events they are interested.

Event processing consume system resources hence its important that EventListener can tell Oak precisely which type of event changes they are interested in. The filtering criteria can be specified in following way

OakEventFilter

@since Oak 1.6

To make use of new filtering capability use following approach

import org.apache.jackrabbit.api.observation.JackrabbitEvent;
import org.apache.jackrabbit.api.observation.JackrabbitEventFilter;
import org.apache.jackrabbit.api.observation.JackrabbitObservationManager;
import org.apache.jackrabbit.oak.jcr.observation.filter.FilterFactory;
import org.apache.jackrabbit.oak.jcr.observation.filter.OakEventFilter;

Session session = ...
EventListener listener = ...

ObservationManager om = session.getWorkspace().getObservationManager();

//Cast to JackrabbitObservationManager
JackrabbitObservationManager jrom = (JackrabbitObservationManager) om;

//Construct a JackrabbitEventFilter
JackrabbitEventFilter jrFilter = new JackrabbitEventFilter();

//Wrap it as OakEventFilter
OakEventFilter oakFilter = FilterFactory.wrap(jrFilter);

oakFilter.withIncludeSubtreeOnRemove();
//Set other filtering criteria

jrom.addEventListener(listener, oakFilter);

Refer to OakEventFilter javadocs for more details on what filtering criteria are supported

Benefits of Filter approach

In Jackrabbit Oak JCR EventListener are implemented as Oak Observer which are backed by an in memory queue. Upon any save call done at JCR layer NodeStore in Oak pushes repository root node in this queue which is later used to compute diff from older root and then generate the JCR Events.

For events to work properly it needs to be ensure that this in memory queue does not get filled up. Having a precise filter helps Oak in prefiltering changes before they are added to queue. For e.g. if filter stats that its only interested in changes under ‘/content’ then Oak can check if changes under that path have happened for given change, if not then such a change is not queued.

Observation queue overflow