/*
* Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.map;
import com.hazelcast.config.Config;
import com.hazelcast.config.EntryListenerConfig;
import com.hazelcast.config.InMemoryFormat;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.MapPartitionLostListenerConfig;
import com.hazelcast.core.EntryAdapter;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryListener;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.HazelcastInstanceAware;
import com.hazelcast.core.IMap;
import com.hazelcast.core.MapEvent;
import com.hazelcast.map.impl.MapService;
import com.hazelcast.map.impl.event.MapPartitionEventData;
import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
import com.hazelcast.map.listener.MapPartitionLostListener;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.DataSerializable;
import com.hazelcast.query.Predicate;
import com.hazelcast.spi.EventRegistration;
import com.hazelcast.spi.EventService;
import com.hazelcast.test.AssertTask;
import com.hazelcast.test.HazelcastParallelClassRunner;
import com.hazelcast.test.HazelcastTestSupport;
import com.hazelcast.test.TestHazelcastInstanceFactory;
import com.hazelcast.test.annotation.ParallelTest;
import com.hazelcast.test.annotation.QuickTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
@SuppressWarnings("deprecation")
@RunWith(HazelcastParallelClassRunner.class)
@Category({QuickTest.class, ParallelTest.class})
public class ListenerTest extends HazelcastTestSupport {
private final AtomicInteger globalCount = new AtomicInteger();
private final AtomicInteger localCount = new AtomicInteger();
private final AtomicInteger valueCount = new AtomicInteger();
@Before
public void before() {
globalCount.set(0);
localCount.set(0);
valueCount.set(0);
}
@Test
public void testConfigListenerRegistration() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
String name = randomString();
Config config = getConfig();
MapConfig mapConfig = config.getMapConfig(name);
EntryListenerConfig entryListenerConfig = new EntryListenerConfig();
entryListenerConfig.setImplementation(new EntryAdapter() {
public void entryAdded(EntryEvent event) {
latch.countDown();
}
});
mapConfig.addEntryListenerConfig(entryListenerConfig);
HazelcastInstance instance = createHazelcastInstance(config);
IMap<Object, Object> map = instance.getMap(name);
map.put(1, 1);
assertTrue(latch.await(10, TimeUnit.SECONDS));
}
@Test
public void globalListenerTest() throws InterruptedException {
Config config = getConfig();
String name = randomString();
TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(2);
HazelcastInstance instance1 = nodeFactory.newHazelcastInstance(config);
HazelcastInstance instance2 = nodeFactory.newHazelcastInstance(config);
IMap<String, String> map1 = instance1.getMap(name);
IMap<String, String> map2 = instance2.getMap(name);
map1.addEntryListener(createEntryListener(false), false);
map1.addEntryListener(createEntryListener(false), true);
map2.addEntryListener(createEntryListener(false), true);
int k = 3;
putDummyData(map1, k);
checkCountWithExpected(k * 3, 0, k * 2);
}
@Test
public void testEntryEventGetMemberNotNull() throws Exception {
Config config = getConfig();
String name = randomString();
TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(2);
HazelcastInstance instance1 = nodeFactory.newHazelcastInstance(config);
HazelcastInstance instance2 = nodeFactory.newHazelcastInstance(config);
IMap<String, String> map1 = instance1.getMap(name);
IMap<String, String> map2 = instance2.getMap(name);
final CountDownLatch latch = new CountDownLatch(1);
map1.addEntryListener(new EntryAdapter<Object, Object>() {
@Override
public void entryAdded(EntryEvent<Object, Object> event) {
assertNotNull(event.getMember());
latch.countDown();
}
}, false);
String key = generateKeyOwnedBy(instance2);
String value = randomString();
map2.put(key, value);
instance2.getLifecycleService().shutdown();
assertOpenEventually(latch);
}
@Test
public void globalListenerRemoveTest() throws InterruptedException {
Config config = getConfig();
String name = randomString();
TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(2);
HazelcastInstance instance1 = nodeFactory.newHazelcastInstance(config);
HazelcastInstance instance2 = nodeFactory.newHazelcastInstance(config);
IMap<String, String> map1 = instance1.getMap(name);
IMap<String, String> map2 = instance2.getMap(name);
String id1 = map1.addEntryListener(createEntryListener(false), false);
String id2 = map1.addEntryListener(createEntryListener(false), true);
String id3 = map2.addEntryListener(createEntryListener(false), true);
int k = 3;
map1.removeEntryListener(id1);
map1.removeEntryListener(id2);
map1.removeEntryListener(id3);
putDummyData(map2, k);
checkCountWithExpected(0, 0, 0);
}
@Test
public void localListenerTest() throws InterruptedException {
Config config = getConfig();
String name = randomString();
TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(2);
HazelcastInstance instance1 = nodeFactory.newHazelcastInstance(config);
HazelcastInstance instance2 = nodeFactory.newHazelcastInstance(config);
IMap<String, String> map1 = instance1.getMap(name);
IMap<String, String> map2 = instance2.getMap(name);
map1.addLocalEntryListener(createEntryListener(true));
map2.addLocalEntryListener(createEntryListener(true));
int k = 4;
putDummyData(map1, k);
checkCountWithExpected(0, k, k);
}
/**
* Test for issue 584 and 756
*/
@Test
public void globalAndLocalListenerTest() throws InterruptedException {
Config config = getConfig();
String name = randomString();
TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(2);
HazelcastInstance instance1 = nodeFactory.newHazelcastInstance(config);
HazelcastInstance instance2 = nodeFactory.newHazelcastInstance(config);
IMap<String, String> map1 = instance1.getMap(name);
IMap<String, String> map2 = instance2.getMap(name);
map1.addLocalEntryListener(createEntryListener(true));
map2.addLocalEntryListener(createEntryListener(true));
map1.addEntryListener(createEntryListener(false), false);
map2.addEntryListener(createEntryListener(false), false);
map2.addEntryListener(createEntryListener(false), true);
int k = 1;
putDummyData(map2, k);
checkCountWithExpected(k * 3, k, k * 2);
}
/**
* Test for issue 584 and 756
*/
@Test
public void globalAndLocalListenerTest2() throws InterruptedException {
Config config = getConfig();
String name = randomString();
TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(2);
HazelcastInstance instance1 = nodeFactory.newHazelcastInstance(config);
HazelcastInstance instance2 = nodeFactory.newHazelcastInstance(config);
IMap<String, String> map1 = instance1.getMap(name);
IMap<String, String> map2 = instance2.getMap(name);
// changed listener order
map1.addEntryListener(createEntryListener(false), false);
map1.addLocalEntryListener(createEntryListener(true));
map2.addEntryListener(createEntryListener(false), true);
map2.addLocalEntryListener(createEntryListener(true));
map2.addEntryListener(createEntryListener(false), false);
int k = 3;
putDummyData(map1, k);
checkCountWithExpected(k * 3, k, k * 2);
}
private static void putDummyData(IMap<String, String> map, int size) {
for (int i = 0; i < size; i++) {
map.put("foo" + i, "bar");
}
}
private void checkCountWithExpected(final int expectedGlobal, final int expectedLocal, final int expectedValue) {
assertTrueEventually(new AssertTask() {
@Override
public void run() {
assertEquals(expectedLocal, localCount.get());
assertEquals(expectedGlobal, globalCount.get());
assertEquals(expectedValue, valueCount.get());
}
});
}
/**
* Test that replace(key, oldValue, newValue) generates entryUpdated events, not entryAdded.
*/
@Test
public void replaceFiresUpdatedEvent() throws InterruptedException {
final AtomicInteger entryUpdatedEventCount = new AtomicInteger(0);
HazelcastInstance node = createHazelcastInstance(getConfig());
IMap<Integer, Integer> map = node.getMap(randomMapName());
map.put(1, 1);
map.addEntryListener(new EntryAdapter<Integer, Integer>() {
@Override
public void entryUpdated(EntryEvent<Integer, Integer> event) {
entryUpdatedEventCount.incrementAndGet();
}
}, true);
map.replace(1, 1, 2);
assertTrueEventually(new AssertTask() {
@Override
public void run() {
assertEquals(1, entryUpdatedEventCount.get());
}
});
}
/**
* test for issue 589
*/
@Test
public void setFiresAlwaysAddEvent() throws InterruptedException {
HazelcastInstance instance = createHazelcastInstance(getConfig());
IMap<Object, Object> map = instance.getMap(randomString());
final CountDownLatch updateLatch = new CountDownLatch(1);
final CountDownLatch addLatch = new CountDownLatch(1);
map.addEntryListener(new EntryAdapter<Object, Object>() {
@Override
public void entryAdded(EntryEvent<Object, Object> event) {
addLatch.countDown();
}
@Override
public void entryUpdated(EntryEvent<Object, Object> event) {
updateLatch.countDown();
}
}, false);
map.set(1, 1);
map.set(1, 2);
assertTrue(addLatch.await(5, TimeUnit.SECONDS));
assertTrue(updateLatch.await(5, TimeUnit.SECONDS));
}
@Test
public void testLocalEntryListener_singleInstance_with_MatchingPredicate() throws Exception {
HazelcastInstance instance = createHazelcastInstance(getConfig());
IMap<String, String> map = instance.getMap(randomString());
boolean includeValue = false;
map.addLocalEntryListener(createEntryListener(false), matchingPredicate(), includeValue);
int count = 1000;
for (int i = 0; i < count; i++) {
map.put("key" + i, "value" + i);
}
checkCountWithExpected(count, 0, 0);
}
@Test
public void testLocalEntryListener_singleInstance_with_NonMatchingPredicate() throws Exception {
HazelcastInstance instance = createHazelcastInstance(getConfig());
IMap<String, String> map = instance.getMap(randomString());
boolean includeValue = false;
map.addLocalEntryListener(createEntryListener(false), nonMatchingPredicate(), includeValue);
int count = 1000;
for (int i = 0; i < count; i++) {
map.put("key" + i, "value" + i);
}
checkCountWithExpected(0, 0, 0);
}
@Test
public void testLocalEntryListener_multipleInstance_with_MatchingPredicate() throws Exception {
int instanceCount = 3;
TestHazelcastInstanceFactory instanceFactory = createHazelcastInstanceFactory(instanceCount);
HazelcastInstance instance = instanceFactory.newInstances(getConfig())[0];
IMap<String, String> map = instance.getMap(randomString());
boolean includeValue = false;
map.addLocalEntryListener(createEntryListener(false), matchingPredicate(), includeValue);
int count = 1000;
for (int i = 0; i < count; i++) {
map.put("key" + i, "value" + i);
}
final int eventPerPartitionMin = count / instanceCount - count / 10;
final int eventPerPartitionMax = count / instanceCount + count / 10;
assertTrueEventually(new AssertTask() {
@Override
public void run() {
assertTrue(globalCount.get() > eventPerPartitionMin && globalCount.get() < eventPerPartitionMax);
}
});
}
@Test
public void testLocalEntryListener_multipleInstance_with_MatchingPredicate_and_Key() throws Exception {
HazelcastInstance instance = createHazelcastInstance(getConfig());
IMap<String, String> map = instance.getMap(randomString());
boolean includeValue = false;
map.addLocalEntryListener(createEntryListener(false), matchingPredicate(), "key500", includeValue);
int count = 1000;
for (int i = 0; i < count; i++) {
map.put("key" + i, "value" + i);
}
assertTrueEventually(new AssertTask() {
@Override
public void run() {
assertTrue(globalCount.get() == 1);
}
});
}
@Test
public void testEntryListenerEvent_withMapReplaceFail() throws Exception {
HazelcastInstance instance = createHazelcastInstance(getConfig());
final IMap<Integer, Object> map = instance.getMap(randomString());
final CounterEntryListener listener = new CounterEntryListener();
map.addEntryListener(listener, true);
final int putTotal = 1000;
final int oldVal = 1;
for (int i = 0; i < putTotal; i++) {
map.put(i, oldVal);
}
final int replaceTotal = 1000;
final int newVal = 2;
for (int i = 0; i < replaceTotal; i++) {
map.replace(i, "WrongValue", newVal);
}
assertTrueEventually(new AssertTask() {
@Override
public void run() {
for (int i = 0; i < replaceTotal; i++) {
assertEquals(oldVal, map.get(i));
}
assertEquals(putTotal, listener.addCount.get());
assertEquals(0, listener.updateCount.get());
}
});
}
/**
* test for issue 3198
*/
@Test
public void testEntryListenerEvent_getValueWhenEntryRemoved() {
HazelcastInstance instance = createHazelcastInstance(getConfig());
IMap<String, String> map = instance.getMap(randomString());
final AtomicReference<String> valueRef = new AtomicReference<String>();
final AtomicReference<String> oldValueRef = new AtomicReference<String>();
final CountDownLatch latch = new CountDownLatch(1);
map.addEntryListener(new EntryAdapter<String, String>() {
public void entryRemoved(EntryEvent<String, String> event) {
valueRef.set(event.getValue());
oldValueRef.set(event.getOldValue());
latch.countDown();
}
}, true);
map.put("key", "value");
map.remove("key");
assertOpenEventually(latch);
assertNull(valueRef.get());
assertEquals("value", oldValueRef.get());
}
@Test
public void testEntryListenerEvent_getValueWhenEntryEvicted() {
HazelcastInstance instance = createHazelcastInstance(getConfig());
IMap<String, String> map = instance.getMap(randomString());
final Object[] value = new Object[1];
final Object[] oldValue = new Object[1];
final CountDownLatch latch = new CountDownLatch(1);
map.addEntryListener(new EntryAdapter<String, String>() {
public void entryEvicted(EntryEvent<String, String> event) {
value[0] = event.getValue();
oldValue[0] = event.getOldValue();
latch.countDown();
}
}, true);
map.put("key", "value", 1, TimeUnit.SECONDS);
assertOpenEventually(latch);
assertNull(value[0]);
assertEquals("value", oldValue[0]);
}
@Test
public void testEntryListenerEvent_withMapReplaceSuccess() throws Exception {
HazelcastInstance instance = createHazelcastInstance(getConfig());
final IMap<Integer, Object> map = instance.getMap(randomString());
final CounterEntryListener listener = new CounterEntryListener();
map.addEntryListener(listener, true);
final int putTotal = 1000;
final int oldVal = 1;
for (int i = 0; i < putTotal; i++) {
map.put(i, oldVal);
}
final int replaceTotal = 1000;
final int newVal = 2;
for (int i = 0; i < replaceTotal; i++) {
map.replace(i, oldVal, newVal);
}
assertTrueEventually(new AssertTask() {
@Override
public void run() {
for (int i = 0; i < replaceTotal; i++) {
assertEquals(newVal, map.get(i));
}
assertEquals(putTotal, listener.addCount.get());
assertEquals(replaceTotal, listener.updateCount.get());
}
});
}
/**
* test for issue 4037
*/
@Test
public void testEntryEvent_includesOldValue_afterRemoveIfSameOperation() {
HazelcastInstance instance = createHazelcastInstance(getConfig());
IMap<String, String> map = instance.getMap(randomString());
final CountDownLatch latch = new CountDownLatch(1);
final String key = "key";
final String value = "value";
final ConcurrentMap<String, String> resultHolder = new ConcurrentHashMap<String, String>(1);
map.addEntryListener(new EntryAdapter<String, String>() {
public void entryRemoved(EntryEvent<String, String> event) {
final String oldValue = event.getOldValue();
resultHolder.put(key, oldValue);
latch.countDown();
}
}, true);
map.put(key, value);
map.remove(key, value);
assertOpenEventually(latch);
final String oldValueFromEntryEvent = resultHolder.get(key);
assertEquals(value, oldValueFromEntryEvent);
}
@Test
public void testMapPartitionLostListener_registeredViaImplementationInConfigObject() {
final String name = randomString();
Config config = getConfig();
MapConfig mapConfig = config.getMapConfig(name);
MapPartitionLostListener listener = mock(MapPartitionLostListener.class);
mapConfig.addMapPartitionLostListenerConfig(new MapPartitionLostListenerConfig(listener));
mapConfig.setBackupCount(0);
HazelcastInstance instance = createHazelcastInstance(config);
instance.getMap(name);
final EventService eventService = getNode(instance).getNodeEngine().getEventService();
assertTrueEventually(new AssertTask() {
@Override
public void run()
throws Exception {
final Collection<EventRegistration> registrations = eventService.getRegistrations(MapService.SERVICE_NAME, name);
assertFalse(registrations.isEmpty());
}
});
}
@Test
public void testPutAll_whenExistsEntryListenerWithIncludeValueSetToTrue_thenFireEventWithValue() throws InterruptedException {
int key = 1;
String initialValue = "foo";
String newValue = "bar";
HazelcastInstance instance = createHazelcastInstance(getConfig());
IMap<Integer, String> map = instance.getMap(randomMapName());
map.put(key, initialValue);
UpdateListenerRecordingOldValue<Integer, String> listener = new UpdateListenerRecordingOldValue<Integer, String>();
map.addEntryListener(listener, true);
Map<Integer, String> newMap = createMapWithEntry(key, newValue);
map.putAll(newMap);
String oldValue = listener.waitForOldValue();
assertEquals(initialValue, oldValue);
}
@Test
public void hazelcastAwareEntryListener_whenConfiguredViaClassName_thenInjectHazelcastInstance() throws InterruptedException {
EntryListenerConfig listenerConfig = new EntryListenerConfig("com.hazelcast.map.ListenerTest$PingPongListener", false, true);
hazelcastAwareEntryListener_injectHazelcastInstance(listenerConfig);
}
@Test
public void hazelcastAwareEntryListener_whenConfiguredByProvidingInstance_thenInjectHazelcastInstance() throws InterruptedException {
EntryListenerConfig listenerConfig = new EntryListenerConfig(new PingPongListener(), false, true);
hazelcastAwareEntryListener_injectHazelcastInstance(listenerConfig);
}
@Test
public void test_ListenerShouldNotCauseDeserialization_withIncludeValueFalse() throws InterruptedException {
String name = randomString();
String key = randomString();
Config config = getConfig();
config.getMapConfig(name).setInMemoryFormat(InMemoryFormat.OBJECT);
HazelcastInstance instance = createHazelcastInstance(config);
IMap<Object, Object> map = instance.getMap(name);
EntryAddedLatch latch = new EntryAddedLatch(1);
map.addEntryListener(latch, false);
map.executeOnKey(key, new AbstractEntryProcessor<Object, Object>() {
@Override
public Object process(Map.Entry<Object, Object> entry) {
entry.setValue(new SerializeCheckerObject());
return null;
}
});
assertOpenEventually(latch, 10);
SerializeCheckerObject.assertNotSerialized();
}
private static class EntryAddedLatch extends CountDownLatch implements EntryAddedListener {
EntryAddedLatch(int count) {
super(count);
}
@Override
public void entryAdded(EntryEvent event) {
countDown();
}
}
private static class SerializeCheckerObject implements DataSerializable {
static volatile boolean serialized = false;
static volatile boolean deserialized = false;
@Override
public void writeData(ObjectDataOutput out) throws IOException {
serialized = true;
}
@Override
public void readData(ObjectDataInput in) throws IOException {
deserialized = true;
}
static void assertNotSerialized() {
assertFalse(serialized);
assertFalse(deserialized);
}
}
@Test
public void test_mapPartitionEventData_toString() {
assertNotNull(new MapPartitionEventData().toString());
}
@Test
public void updates_with_putTransient_triggers_entryUpdatedListener() throws Exception {
HazelcastInstance hz = createHazelcastInstance(getConfig());
IMap<String, String> map = hz.getMap("updates_with_putTransient_triggers_entryUpdatedListener");
final CountDownLatch updateEventCounterLatch = new CountDownLatch(1);
map.addEntryListener(new EntryUpdatedListener<String, String>() {
@Override
public void entryUpdated(EntryEvent<String, String> event) {
updateEventCounterLatch.countDown();
}
}, true);
map.putTransient("hello", "world", 0, TimeUnit.SECONDS);
map.putTransient("hello", "another world", 0, TimeUnit.SECONDS);
assertOpenEventually(updateEventCounterLatch);
}
private <K, V> Map<K, V> createMapWithEntry(K key, V newValue) {
Map<K, V> map = new HashMap<K, V>();
map.put(key, newValue);
return map;
}
private Predicate<String, String> matchingPredicate() {
return new Predicate<String, String>() {
@Override
public boolean apply(Map.Entry<String, String> mapEntry) {
return true;
}
};
}
private Predicate<String, String> nonMatchingPredicate() {
return new Predicate<String, String>() {
@Override
public boolean apply(Map.Entry<String, String> mapEntry) {
return false;
}
};
}
private class UpdateListenerRecordingOldValue<K, V> implements EntryUpdatedListener<K, V> {
private volatile V oldValue;
private final CountDownLatch latch = new CountDownLatch(1);
V waitForOldValue() throws InterruptedException {
latch.await();
return oldValue;
}
@Override
public void entryUpdated(EntryEvent<K, V> event) {
oldValue = event.getOldValue();
latch.countDown();
}
}
private EntryListener<String, String> createEntryListener(final boolean isLocal) {
return new EntryAdapter<String, String>() {
private final boolean local = isLocal;
public void entryAdded(EntryEvent<String, String> event) {
if (local) {
localCount.incrementAndGet();
} else {
globalCount.incrementAndGet();
}
if (event.getValue() != null) {
valueCount.incrementAndGet();
}
}
};
}
private void hazelcastAwareEntryListener_injectHazelcastInstance(EntryListenerConfig listenerConfig) {
String pingMapName = randomMapName();
Config config = getConfig();
config.getMapConfig(pingMapName).getEntryListenerConfigs().add(listenerConfig);
HazelcastInstance instance = createHazelcastInstance(config);
IMap<Integer, String> pingMap = instance.getMap(pingMapName);
String pongMapName = randomMapName();
pingMap.put(0, pongMapName);
IMap<Integer, String> outputMap = instance.getMap(pongMapName);
assertSizeEventually(1, outputMap);
}
public static class PingPongListener implements EntryListener<Integer, String>, HazelcastInstanceAware {
private HazelcastInstance instance;
@Override
public void setHazelcastInstance(HazelcastInstance instance) {
this.instance = instance;
}
@Override
public void entryAdded(EntryEvent<Integer, String> event) {
String outputMapName = event.getValue();
IMap<Integer, String> outputMap = instance.getMap(outputMapName);
outputMap.putAsync(0, "pong");
}
@Override
public void entryEvicted(EntryEvent<Integer, String> event) {
}
@Override
public void entryRemoved(EntryEvent<Integer, String> event) {
}
@Override
public void entryUpdated(EntryEvent<Integer, String> event) {
}
@Override
public void mapCleared(MapEvent event) {
}
@Override
public void mapEvicted(MapEvent event) {
}
}
public class CounterEntryListener implements EntryListener<Object, Object> {
final AtomicLong addCount = new AtomicLong();
final AtomicLong removeCount = new AtomicLong();
final AtomicLong updateCount = new AtomicLong();
final AtomicLong evictCount = new AtomicLong();
public CounterEntryListener() {
}
@Override
public void entryAdded(EntryEvent<Object, Object> objectObjectEntryEvent) {
addCount.incrementAndGet();
}
@Override
public void entryRemoved(EntryEvent<Object, Object> objectObjectEntryEvent) {
removeCount.incrementAndGet();
}
@Override
public void entryUpdated(EntryEvent<Object, Object> objectObjectEntryEvent) {
updateCount.incrementAndGet();
}
@Override
public void entryEvicted(EntryEvent<Object, Object> objectObjectEntryEvent) {
evictCount.incrementAndGet();
}
@Override
public void mapEvicted(MapEvent event) {
}
@Override
public void mapCleared(MapEvent event) {
}
@Override
public String toString() {
return "EntryCounter{" +
"addCount=" + addCount +
", removeCount=" + removeCount +
", updateCount=" + updateCount +
", evictCount=" + evictCount +
'}';
}
}
}