Monday 27 November 2017

Event System

Framework provided by Service Layer to send and receive events
 

Events: A source publishes an event while any interested party will register a listener that is able to receive these events and then perform logic.
 

Events are published using an event service.
Listeners are registered with the event service and can then react to the events. 


Hybris event system is based on the Spring event system.
Events can either be published locally or across cluster nodes. 


Event Service

  • Add a Spring resource to your class:
@Resource
private EventService eventService;
  • Register event listeners via the registerEventListener() method:
final TestListener listener = new TestListener();
eventService.registerEventListener(listener);
  • Publish events via the publishEvent() method:
TestEvent event = new TestEvent(source);
eventService.publishEvent(event);

Event Listeners
  • Extend from the abstract class: AbstractEventListener
  • Implement the method onEvent(). In this method, check for the type of event and then run your logic.
public class TestListener extends AbstractEventListener {
   @Override
   protected void onEvent(final AbstractEvent event) {
      if (event instanceof MyEvent) {
          // Your logic here
      }
      if (event instanceof MyOtherEvent) {
          // Your logic here
      }
   }
}

Java Generics Allowed if Listening for One Type of Events
public class TestListener extends AbstractEventListener<AfterItemCreationEvent> {
   @Override
   protected void onEvent(final AfterItemCreationEvent event) {
          // Your logic here
   }
}
  • No need to check for type of event, as it listens only a single event

By default, event publishing is synchronous i.e.; the current thread is locked until all listeners have reacted to an event.
On a Hybris Cluster, events on the same node are processed synchronously, but asynchronous on other cluster nodes.
To make event processing asynchronous, implement ClusterAwareEvent interface.
 

Registering Event Listeners
There are two ways to register an event listener:
  • Register the listener via the eventService (Configure the listeners at runtime):
@Resource
EventService eventService;
...
final TestListener listener = new TestListener();
eventService.registerEventListener(listener);
  • Register the listener as Spring bean (Configure the listeners at compile time)
The event system will scan the application context and automatically register all event listeners. 
<bean id="testListener" class="my.package.TestListener" >
        <property name="modelService" bean="modelService" />    
</bean>

Publishing Events
  • Extend from the abstract class: AbstractEvent
  • Contains a source object that denotes the origin of the event.
public class TestEvent extends AbstractEvent implements ClusterAwareEvent {
  Object source;
  public TestEvent(Serializable source) {
    super(source);
    this.source=source;
  }
}
To publish an event:
source = //any java object which might be interesting
TestEvent event = new TestEvent(source);
eventService.publishEvent(event);

Cluster-Aware Events
  • To send events to all nodes in a cluster, you need to implement ClusterAwareEvent interface.
  • Then implement the method publish(int sourceNodeId, int targetNodeId) in a way to return true if the sourceNodeId and targetNodeId matches the respective conditions.

Transaction Aware Events
  • To publish event only at the end of a transaction, you need to implement TransactionAwareEvent interface
  • getId() method return a unique ID
  • All events returning the same ID will only be published once at the end of the transaction if publishOnCommitOnly returns true.

Asynchronous Events
  • To configure the event publishing as asynchronous, we need to set java.util.concurrent.Executor for PlatformClusterEventSender instance.
myExtension/resources/[myExtension]-spring.xml
<bean id="platformClusterEventSender" class="de.hybris.platform.servicelayer.event.impl.PlatformClusterEventSender">
    <property name="serializationService" ref="serializationService"/>
    <property name="tenant" ref="tenantFactory"/>
    <property name="executor">
        <bean class="java.util.concurrent.Executors" factory-method="newCachedThreadPool"/>
    </property>
</bean>

No comments:

Post a Comment