When some actions occur in the LuciadFusion application, the system will publish an event. In this tutorial, we show how you can extend the LuciadFusion platform and get notified of these events.

These types of actions can trigger events:

  • A user action, such as adding a data root or creating a service

  • Automatic actions, such as the start of a scheduled crawl job

Listening to events

The basics

The LuciadFusion platform uses the Spring events mechanism for publishing events. For general information on how this works, see the Spring reference documentation. The easiest way to get notified of events is using the Spring @EventListener annotation.

This first snippet shows how to listen for all events that are published by the LuciadFusion platform:

@EventListener
public void handleFusionEvent(ALfnEvent aEvent) {
  System.out.println("A LuciadFusion event occurred: " + aEvent);
}

By changing the type of the argument, you can narrow the handler down to more specific events:

@EventListener
public void handleSpecificEvent(TLfnProductCreatedEvent aEvent) {
  System.out.println("A new Product has been created: " + aEvent.getProduct());
}

For an overview of available event types, see Overview of LuciadFusion event types.

To ensure that these listeners are registered in the Spring application context, you must add them to a managed bean, for example by annotating the class with the @Component annotation.

@Component
public class EventHandling {
  // ...
}

(A)synchronous event handling

By default, the event listeners for all ALfnEvent objects are called asynchronously. With this approach, LuciadFusion offloads the handling of events from its worker thread pools, such as the HTTP and job thread pools, to the event handling thread pool. It has the advantage that the handling of events doesn’t block LuciadFusion’s normal operation.

Asynchronous event handling also means that event listeners must implement their own synchronization, if needed. For example, the next snippet locks on the id of an ALfnJob to prevent inconsistencies when events follow each other in rapid succession:

private Map<String, Lock> locks = Collections.synchronizedMap(new WeakHashMap<>());

public void handleJobEvent(ALfnJobEvent<?> aEvent) {
  ALfnJob job = aEvent.getJob();
  Lock l = locks.computeIfAbsent(job.getId(), id -> new ReentrantLock());
  try {
    l.lock();
    // do something ...
  } finally {
    l.unlock();
  }
}

Alternatively, you can disable asynchronous event handling by changing the configuration in your LuciadFusion profile. See Configuring LuciadFusion Studio for more information on profiles and how to change them.

The property that configures asynchronous event handling is fusion.events.async.enabled. It defaults to true.

If you disable asynchronous event handling, LuciadFusion Platform reverts to the default Spring event dispatching behavior: all event listeners run synchronously, on the same thread that the event was published on. This may slow down the handling of requests by LuciadFusion Studio or the Platform Services.

If you disabled asynchronous event handling, you can still configure specific event listeners to process events asynchronously through the Spring @Async annotation. See the Spring reference documentation for more information.

With asynchronous event handling disabled, you can define your own ApplicationEventMulticaster bean if you need more specific behavior when handling events.

Limitations

  • The events are published after all transactions on the back-end database have finished. This means that you can’t use events to interrupt or roll back changes.

  • When the LuciadFusion server shuts down, event listeners might not be executed. For instance, if a running job is interrupted after the Spring application context is no longer active, the event listeners can’t be notified.

Publishing events

When you extend the LuciadFusion platform with your own service, you may also need to publish events. The Publishing Service and Product access events section of the tutorial on adding a custom service type describes in detail how to do that.

Overview of LuciadFusion event types

The base type for all LuciadFusion events is ALfnEvent.

In the following sections, we group the LuciadFusion events according to the resource type they’re related to.

ALfnDataEvent

For all types that extend ALfnDataEvent, the affected TLfnData object is available.

The TLfnDataQueryEvent is published when a user searches for data. This class doesn’t extend ALfnDataEvent, and won’t include the result of the query.

ALfnStyleEvent

For all types that extend ALfnStyleEvent, the affected TLfnStyle object is available.

The TLfnStyleQueryEvent is published when a user searches for styles. This class doesn’t extend ALfnStyleEvent and won’t include the result of the query.

ALfnProductEvent

All events related to TLfnProduct objects extend ALfnProductEvent. They all have the affected TLfnProduct.

The TLfnProductAccessEvent is published when a user accesses a product. Its TLfnEventSourceRequest is guaranteed to have a non-empty value.

The TLfnProductQueryEvent is published when a user searches for products. This class doesn’t extend ALfnProductEvent and won’t include the result of the query.

ALfnServiceEvent

All events related to TLfnService objects extend ALfnServiceEvent. They all have the affected TLfnService object.

The TLfnServiceAccessEvent is published when a user accesses a service. Its TLfnEventSourceRequest is guaranteed to have a non-empty value.

The TLfnServiceQueryEvent is published when a user searches for services. This class doesn’t extend ALfnServiceEvent and won’t include the result of the query.

ALfnDataRootEvent

All events related to TLfnDataRoot objects extend ALfnDataRootEvent. They all have the affected TLfnDataRoot object.

ALfnJobEvent

All events related to ALfnJob objects extend ALfnJobEvent. They all have the affected ALfnJob object.

The TLfnJobScheduledEvent, TLfnJobUnscheduledEvent and TLfnJobSchedulingFailedEvent only apply to TLfnCrawlJob resources. The "scheduling failed" event means that there were no changes.

When LuciadFusion executes an ALfnJob, several ALfnJobExecutionEvent objects can be published, following this diagram:

ALfnJobExecutionEvent

The Spring @EventListener annotation allows listening for events for a specific job type:

@EventListener
public void handleCrawlJobEvent(ALfnJobEvent<TLfnCrawlJob> aEvent) {
  System.out.println("Crawl job id: " + aEvent.getJob().getId());
}