import com.hazelcast.config.Config;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.core.MapEvent;
import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.map.listener.EntryEvictedListener;
import com.hazelcast.map.listener.EntryRemovedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
import com.hazelcast.map.listener.MapClearedListener;
import com.hazelcast.map.listener.MapEvictedListener;
import com.hazelcast.query.SqlPredicate;
/**
* Registers an entry listener with a predicate to continuously query map data as it is updated.
* Since Hazelcast version 3.7, initializing your Hazelcast instance to publish natural filtering event types (setting property
* {@code hazelcast.map.entry.filtering.natural.event.types} to {@code true}) will change how
* entry listeners with predicates are notified about map entry value updates to accommodate the continuous
* querying use case. The following table compares how a listener is notified about an update to a map entry value
* under the default backwards-compatible Hazelcast behavior (when the property above is not set
* or is set to {@code false}) versus when set to {@code true}:
* <table>
* <tr>
* <th> </th>
* <th>Default</th>
* <th>hazelcast.map.entry.filtering.natural.event.types = true</th>
* </tr>
* <tr>
* <td>When old value matches predicate,<br/>new value does not match predicate</td>
* <td>No event is delivered to entry listener</td>
* <td>{@code REMOVED} event is delivered to entry listener</td>
* </tr>
* <tr>
* <td>When old value matches predicate,<br/>new value matches predicate</td>
* <td>{@code UPDATED} event is delivered to entry listener</td>
* <td>{@code UPDATED} event is delivered to entry listener</td>
* </tr>
* <tr>
* <td>When old value does not match predicate,<br/>new value does not match predicate</td>
* <td>No event is delivered to entry listener</td>
* <td>No event is delivered to entry listener</td>
* </tr>
* <tr>
* <td>When old value does not match predicate,<br/>new value matches predicate</td>
* <td>{@code UPDATED} event is delivered to entry listener</td>
* <td>{@code ADDED} event is delivered to entry listener</td>
* </tr>
* </table>
*
* Conceptually, enabling the natural filtering event types property produces events reflecting how map entries are
* added, updated or removed with regards to the space of values matching the predicate.
*
* @see com.hazelcast.map.impl.event.QueryCacheNaturalFilteringStrategy
* @see com.hazelcast.map.impl.event.DefaultEntryEventFilteringStrategy
* @see com.hazelcast.map.impl.event.MapEventPublisherImpl
*/
public class ContinuousQueryMember {
public static void main(String[] args) {
Config config = new Config();
config.setProperty("hazelcast.map.entry.filtering.natural.event.types", "true");
HazelcastInstance hz = Hazelcast.newHazelcastInstance(config);
IMap<String, String> map = hz.getMap("map");
map.addEntryListener(new MyEntryListener(),
new SqlPredicate("name=peter"), true);
System.out.println("EntryListener registered");
}
static class MyEntryListener
implements EntryAddedListener<String, String>, EntryUpdatedListener<String, String>,
EntryRemovedListener<String, String>, EntryEvictedListener<String, String>,
MapEvictedListener, MapClearedListener {
@Override
public void entryAdded(EntryEvent<String, String> event) {
System.out.println("entryAdded:" + event);
}
@Override
public void entryRemoved(EntryEvent<String, String> event) {
System.out.println("entryRemoved:" + event);
}
@Override
public void entryUpdated(EntryEvent<String, String> event) {
System.out.println("entryUpdated:" + event);
}
@Override
public void entryEvicted(EntryEvent<String, String> event) {
System.out.println("entryEvicted:" + event);
}
@Override
public void mapEvicted(MapEvent event) {
System.out.println("mapEvicted:" + event);
}
@Override
public void mapCleared(MapEvent event) {
System.out.println("mapCleared:" + event);
}
}
}