Summary: The notify event container uses the space inheritance support for notifications, using a GigaSpaces unified event session API.
OverviewThe notify event container uses the space inheritance support for notifications using a GigaSpaces unified event session API. If a notification occurs, the data event listener is invoked with the event. A notify event operation is mainly used when simulating Topic semantics. Here is a simple example of a notify event container configuration:
Annotation
<!-- Enable scan for OpenSpaces and Spring components --> <context:component-scan base-package="com.mycompany"/> <!-- Enable support for @Notify annotation --> <os-events:annotation-support /> <os-core:space id="space" url="/./space" /> <os-core:giga-space id="gigaSpace" space="space"/> @EventDriven @Notify public class SimpleListener { @EventTemplate Data unprocessedData() { Data template = new Data(); template.setProcessed(false); return template; } @SpaceDataEvent public Data eventListener(Data event) { //process Data here } } Namespace <os-core:space id="space" url="/./space" /> <os-core:giga-space id="gigaSpace" space="space"/> <bean id="simpleListener" class="SimpleListener" /> <os-events:notify-container id="eventContainer" giga-space="gigaSpace"> <os-core:template> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </os-core:template> <os-events:listener> <os-events:annotation-adapter> <os-events:delegate ref="simpleListener"/> </os-events:annotation-adapter> </os-events:listener> </os-events:notify-container> Plain XML <bean id="space" class="org.openspaces.core.space.UrlSpaceFactoryBean"> <property name="url" value="/./space" /> </bean> <bean id="gigaSpace" class="org.openspaces.core.GigaSpaceFactoryBean"> <property name="space" ref="space" /> </bean> <bean id="simpleListener" class="SimpleListener" /> <bean id="eventContainer" class="org.openspaces.events.notify.SimpleNotifyEventListenerContainer"> <property name="gigaSpace" ref="gigaSpace" /> <property name="template"> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </property> <property name="eventListener"> <bean class="org.openspaces.events.adapter.AnnotationEventListenerAdapter"> <property name="delegate" ref="simpleListener" /> </bean> </property> </bean> Code GigaSpace gigaSpace = // either create the GigaSpace or get it by injection SimpleNotifyEventListenerContainer notifyEventListenerContainer = new SimpleNotifyContainerConfigurer(gigaSpace) .template(new Data(false)) .eventListenerAnnotation(new Object() { @SpaceDataEvent public void eventHappened() { eventCalled.set(true); } }).notifyContainer(); // when needed dispose of the notification container notifyEventListenerContainer.destroy(); The above example registers with the space for write notifications using the provided template (a Data object with its processed flag set to false). If a notification occurs, the SimpleListener is invoked. Registration for notifications is performed on the configured GigaSpace bean. (In this case, if working in a clustered topology, the notification is performed directly on the cluster member.) Primary/BackupBy default, the notify event container registers for notifications only when the relevant space it is working against is in primary mode. When the space is in backup mode, no registration occurs. If the space moves from backup mode to primary mode, the container registers for notifications, and if it moved to backup mode, the registrations are canceled.
Template DefinitionWhen performing receive operations, a template is defined, creating a virtualized subset of data in the space, matching it. GigaSpaces supports templates based on the actual domain model (with null values denoting wildcards), which are shown in the examples. GigaSpaces allows the use of SQLQuery in order to query the space, which can be easily used with the event container as the template. Here is an example of how it can be defined:
Annotation
@EventDriven @Notify public class SimpleListener { @EventTemplate SQLQuery<Data> unprocessedData() { SQLQuery<Data> template = new SQLQuery<Data>(Data.class, "processed = true"); return template; } @SpaceDataEvent public Data eventListener(Data event) { //process Data here } } Namespace <os-events:notify-container id="eventContainer" giga-space="gigaSpace"> <os-core:sql-query where="processed = true" class="org.openspaces.example.data.common.Data"/> <os-events:listener> <os-events:annotation-adapter> <os-events:delegate ref="simpleListener"/> </os-events:annotation-adapter> </os-events:listener> </os-events:notify-container> Plain XML <bean id="eventContainer" class="org.openspaces.events.notify.SimpleNotifyEventListenerContainer"> <property name="gigaSpace" ref="gigaSpace" /> <property name="template"> <bean class="com.j_spaces.core.client.SQLQuery"> <constructor index="0" value="org.openspaces.example.data.common.Data" /> <constructor index="0" value="processed = true" /> </bean> </property> <property name="eventListener"> <bean class="org.openspaces.events.adapter.AnnotationEventListenerAdapter"> <property name="delegate" ref="simpleListener" /> </bean> </property> </bean> Transaction SupportThe notify container can be configured with transaction support, so the event action can be performed under a transaction. Exceptions thrown by the event listener cause the operations performed within the listener to be rolled back automatically.
Transaction support can be configured as follows:
Annotation
<!-- Enable scan for OpenSpaces and Spring components --> <context:component-scan base-package="com.mycompany"/> <!-- Enable support for @Polling annotation --> <os-events:annotation-support /> <os-core:space id="space" url="/./space" /> <os-core:local-tx-manager id="transactionManager" space="space"/> <os-core:giga-space id="gigaSpace" space="space" tx-manager="transactionManager"/> @EventDriven @Notify @TransactionalEvent public class SimpleListener { @EventTemplate Data unprocessedData() { Data template = new Data(); template.setProcessed(false); return template; } @SpaceDataEvent public Data eventListener(Data event) { //process Data here } } Namespace <os-core:space id="space" url="/./space" /> <os-core:local-tx-manager id="transactionManager" space="space"/> <os-core:giga-space id="gigaSpace" space="space" tx-manager="transactionManager"/> <bean id="simpleListener" class="SimpleListener" /> <os-events:notify-container id="eventContainer" giga-space="gigaSpace"> <os-events:tx-support tx-manager="transactionManager"/> <os-core:template> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </os-core:template> <os-events:listener> <os-events:annotation-adapter> <os-events:delegate ref="simpleListener"/> </os-events:annotation-adapter> </os-events:listener> </os-events:notify-container> Plain XML <bean id="space" class="org.openspaces.core.space.UrlSpaceFactoryBean"> <property name="url" value="/./space" /> </bean> <bean id="transactionManager" class="org.openspaces.core.transaction.manager.LocalJiniTransactionManager"> <property name="space" ref="space" /> </bean> <bean id="gigaSpace" class="org.openspaces.core.GigaSpaceFactoryBean"> <property name="space" ref="space" /> <property name="transactionManager" ref="transactionManager" /> </bean> <bean id="simpleListener" class="SimpleListener" /> <bean id="eventContainer" class="org.openspaces.events.notify.SimpleNotifyEventListenerContainer"> <property name="transactionManager" ref="transactionManager" /> <property name="gigaSpace" ref="gigaSpace" /> <property name="template"> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </property> <property name="eventListener"> <bean class="org.openspaces.events.adapter.AnnotationEventListenerAdapter"> <property name="delegate" ref="simpleListener" /> </bean> </property> </bean> Masking NotificationsThe notify container allows you to mask which operations performed against the space, should cause notifications. By default (if none is defined), notifications are sent for write operations. The operations are: write (an entry matching the template has been written to the space), update (an entry matching the template has been updated in the Space), take (an entry matching the template has been taken from the Space), lease expiration (an entry matching the template lease has been expired), unmatched (an entry matching the template no longer matches the template), and all. Here is an example of the notify container configured to trigger notifications for both write and update operations:
Annotation
@EventDriven @Notify @NotifyType(write = true, update = true) public class SimpleListener { @EventTemplate Data unprocessedData() { Data template = new Data(); template.setProcessed(false); return template; } @SpaceDataEvent public Data eventListener(Data event) { //process Data here } } Namespace <os-events:notify-container id="eventContainer" giga-space="gigaSpace"> <os-events:notify write="true" update="true"/> <os-core:template> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </os-core:template> <os-events:listener> <os-events:annotation-adapter> <os-events:delegate ref="simpleListener"/> </os-events:annotation-adapter> </os-events:listener> </os-events:notify-container> Plain XML <bean id="eventContainer" class="org.openspaces.events.notify.SimpleNotifyEventListenerContainer"> <property name="gigaSpace" ref="gigaSpace" /> <property name="notifyWrite" value="true" /> <property name="notifyUpdate" value="true" /> <property name="template"> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </property> <property name="eventListener"> <bean class="org.openspaces.events.adapter.AnnotationEventListenerAdapter"> <property name="delegate" ref="simpleListener" /> </bean> </property> </bean> Communication Protocol TypeThe notify container, through the use of the unified event session API, can control how notifications are triggered from the space to the listener, in terms of communication protocol. The following communication protocols are available:
Here is a sample configuration of the notify container that uses the MULTIPLEX communication protocol type:
Annotation
@EventDriven @Notify(commType = NotifyComType.MULTIPLEX) public class SimpleListener { @EventTemplate Data unprocessedData() { Data template = new Data(); template.setProcessed(false); return template; } @SpaceDataEvent public Data eventListener(Data event) { //process Data here } } Namespace <os-events:notify-container id="eventContainer" giga-space="gigaSpace" com-type="MULTIPLEX"> <os-core:template> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </os-core:template> <os-events:listener> <os-events:annotation-adapter> <os-events:delegate ref="simpleListener"/> </os-events:annotation-adapter> </os-events:listener> </os-events:notify-container> Plain XML <bean id="eventContainer" class="org.openspaces.events.notify.SimpleNotifyEventListenerContainer"> <property name="gigaSpace" ref="gigaSpace" /> <property name="comTypeName" value="MULTIPLEX" /> <property name="template"> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </property> <property name="eventListener"> <bean class="org.openspaces.events.adapter.AnnotationEventListenerAdapter"> <property name="delegate" ref="simpleListener" /> </bean> </property> </bean> The JavaSpaces Multicast Notifications section*** explains how to configure and enable multicast notifications support inside the space schema. The multicast worker itself can be easily enabled in the space configuration:
Namespace
<os-core:space id="space" url="/./space"> <os-core:properties> <props> <prop key="space-config.workers.MulticastNotifyWorker.enabled">true</prop> </props> </os-core:properties> </os-core:space> Plain XML <bean id="space" class="org.openspaces.core.space.UrlSpaceFactoryBean"> <property name="url" value="/./space" /> <property name="properties"> <props> <prop key="space-config.workers.MulticastNotifyWorker.enabled">true</prop> </props> </property> </bean> Batch EventsOpenSpaces, through the unified event API, allows batching of notifications. Batching causes the space to accumulate the notifications, and once a certain amount of time has passed or a certain size is reached, causes the events to be raised to the client. Batching is very useful when working with a remote space, since it reduces the network roundtrip operations. Below is an example of batching, where if the number of notifications has passed 10, or the time passed is 5 seconds (since the last batch was sent), a batch of notifications is sent to the client:
Annotation
@EventDriven @Notify @NotifyBatch(size = 10, time = 5000) public class SimpleListener { @EventTemplate Data unprocessedData() { Data template = new Data(); template.setProcessed(false); return template; } @SpaceDataEvent public Data eventListener(Data event) { //process Data here } } Namespace <os-events:notify-container id="eventContainer" giga-space="gigaSpace"> <os-events:batch size="10" time="5000"/> <os-core:template> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </os-core:template> <os-events:listener> <os-events:annotation-adapter> <os-events:delegate ref="simpleListener"/> </os-events:annotation-adapter> </os-events:listener> </os-events:notify-container> Plain XML <bean id="eventContainer" class="org.openspaces.events.notify.SimpleNotifyEventListenerContainer"> <property name="gigaSpace" ref="gigaSpace" /> <property name="batchSize" value="10" /> <property name="batchTime" value="5000" /> <property name="template"> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </property> <property name="eventListener"> <bean class="org.openspaces.events.adapter.AnnotationEventListenerAdapter"> <property name="delegate" ref="simpleListener" /> </bean> </property> </bean> Pass Array as isWhen batching is enabled an array of Entries is received from the notification. By default, the notify container serializes the execution of the array into invocation of the event listener for each element in the array. If you want the event to operate on the whole array (receive the array as a parameter), the pass-array-as-is configuration attribute should be set to true. FIFO EventsThe notify event container can register for events or notifications and have the events delivered in a FIFO order.
Here is an example of how FIFO events can be configured with the notify container:
Annotation
@EventDriven @Notify(fifo = true) public class SimpleListener { @EventTemplate Data unprocessedData() { Data template = new Data(); template.setProcessed(false); return template; } @SpaceDataEvent public Data eventListener(Data event) { //process Data here } } Namespace <os-events:notify-container id="eventContainer" giga-space="gigaSpace" fifo="true"> <os-core:template> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </os-core:template> <os-events:listener> <os-events:annotation-adapter> <os-events:delegate ref="simpleListener"/> </os-events:annotation-adapter> </os-events:listener> </os-events:notify-container> Plain XML <bean id="eventContainer" class="org.openspaces.events.notify.SimpleNotifyEventListenerContainer"> <property name="gigaSpace" ref="gigaSpace" /> <property name="fifo" value="true" /> <property name="template"> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </property> <property name="eventListener"> <bean class="org.openspaces.events.adapter.AnnotationEventListenerAdapter"> <property name="delegate" ref="simpleListener" /> </bean> </property> </bean> Take on NotifyThe notify event container can be configured to automatically perform a take on the notification data event. It can also be further configured to filter out events if the take operation returned null. (This usually happens when several clients receive this event, and only one succeeds with the take.) Here is how the notify container can be configured:
Annotation
@EventDriven @Notify(performTakeOnNotify = true, ignoreEventOnNullTake = true) public class SimpleListener { @EventTemplate Data unprocessedData() { Data template = new Data(); template.setProcessed(false); return template; } @SpaceDataEvent public Data eventListener(Data event) { //process Data here } } Namespace <os-events:notify-container id="eventContainer" giga-space="gigaSpace" perform-take-on-notify="true" ignore-event-on-null-take="true"> <os-core:template> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </os-core:template> <os-events:listener> <os-events:annotation-adapter> <os-events:delegate ref="simpleListener"/> </os-events:annotation-adapter> </os-events:listener> </os-events:notify-container> Plain XML <bean id="eventContainer" class="org.openspaces.events.notify.SimpleNotifyEventListenerContainer"> <property name="gigaSpace" ref="gigaSpace" /> <property name="performTakeOnNotify" value="true" /> <property name="ignoreEventOnNullTake" value="true" /> <property name="template"> <bean class="org.openspaces.example.data.common.Data"> <property name="processed" value="false"/> </bean> </property> <property name="eventListener"> <bean class="org.openspaces.events.adapter.AnnotationEventListenerAdapter"> <property name="delegate" ref="simpleListener" /> </bean> </property> </bean> RemoteEvent and EntryArrivedRemoteEventWhen registering for notifications, using the unified event session API (or using plain notify registration), the following interface needs to be implemented: public interface RemoteEventListener extends java.rmi.Remote, java.util.EventListener { void notify(net.jini.core.event.RemoteEvent event) throws net.jini.core.event.UnknownEventException, java.rmi.RemoteException; } GigaSpaces extends this interface by providing the EntryArrivedRemoteEvent, which holds additional information regarding the event that occurred. The notify container, by default, uses the EntryArrivedRemoteEvent in order to extract the actual data event represented by the event, and passes it as the first parameter. If access to the EntryArrivedRemoteEvent is still needed, it is passed as the last parameter to the space data event listener. Here is an example of how it can be used: public class SimpleListener implements SpaceDataEventListener { public void onEvent(Object data, GigaSpace gigaSpace, TransactionStatus txStatus, Object source) { EntryArrivedRemoteEvent entryArrivedRemoteEvent = (EntryArrivedRemoteEvent) source; // ... } } When using the different listener adapters, such as the annotation adapter, it can be accessed in the following manner (since adapters use reflection, there is no need to cast to EntryArrivedRemoteEvent): public class SimpleListener { @SpaceDataEvent public void myEventHandler(Trade data, GigaSpace gigaSpace, TransactionStatus txStatus, EntryArrivedRemoteEvent entryArrivedRemoteEvent) { // process event } } Default Values of Notify Container Configuration ParametersThe default values for all of the notify container configuration parameters, such as perform-take-on-notify, ignore-event-on-null-take and others can be found in the JavaDoc (and sources) of the class org.openspaces.events.notify.SimpleNotifyEventListenerContainer and its super class, namely org.openspaces.events.notify.AbstractNotifyEventListenerContainer. ***Link required |
![]() |
GigaSpaces.com - Legal Notice - 3rd Party Licenses - Site Map - API Docs - Forum - Downloads - Blog - White Papers - Contact Tech Writing - Gen. by Atlassian Confluence |