package org.infinispan.server.hotrod.event; import static org.infinispan.server.hotrod.test.HotRodTestingUtil.k; import static org.infinispan.server.hotrod.test.HotRodTestingUtil.startHotRodServer; import static org.infinispan.server.hotrod.test.HotRodTestingUtil.v; import static org.infinispan.server.hotrod.test.HotRodTestingUtil.withClientListener; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collections; import java.util.Optional; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.notifications.cachelistener.event.Event; import org.infinispan.notifications.cachelistener.filter.CacheEventFilter; import org.infinispan.notifications.cachelistener.filter.CacheEventFilterFactory; import org.infinispan.server.hotrod.HotRodServer; import org.infinispan.server.hotrod.HotRodSingleNodeTest; import org.infinispan.util.KeyValuePair; import org.testng.annotations.Test; /** * @author Galder ZamarreƱo */ @Test(groups = "functional", testName = "server.hotrod.event.HotRodFilterEventsTest") public class HotRodFilterEventsTest extends HotRodSingleNodeTest { @Override protected HotRodServer createStartHotRodServer(EmbeddedCacheManager cacheManager) { HotRodServer server = startHotRodServer(cacheManager); server.addCacheEventFilterFactory("static-filter-factory", new StaticKeyValueFilterFactory(new byte[]{1, 2, 3})); server.addCacheEventFilterFactory("dynamic-filter-factory", new DynamicKeyValueFilterFactory()); return server; } public void testFilteredEvents(Method m) { EventLogListener eventListener = new EventLogListener(); byte[] acceptedKey = new byte[]{1, 2, 3}; withClientListener(client(), eventListener, Optional.of( new KeyValuePair<>("static-filter-factory", Collections.emptyList())), Optional.empty(), () -> { eventListener.expectNoEvents(Optional.empty()); byte[] key = k(m); client().remove(key); eventListener.expectNoEvents(Optional.empty()); client().put(key, 0, 0, v(m)); eventListener.expectNoEvents(Optional.empty()); client().put(acceptedKey, 0, 0, v(m)); eventListener.expectSingleEvent(cache, acceptedKey, Event.Type.CACHE_ENTRY_CREATED); client().put(acceptedKey, 0, 0, v(m, "v2-")); eventListener.expectSingleEvent(cache, acceptedKey, Event.Type.CACHE_ENTRY_MODIFIED); client().remove(key); eventListener.expectNoEvents(Optional.empty()); client().remove(acceptedKey); eventListener.expectSingleEvent(cache, acceptedKey, Event.Type.CACHE_ENTRY_REMOVED); }); } public void testParameterBasedFiltering(Method m) { EventLogListener eventListener = new EventLogListener(); byte[] acceptedKey = new byte[]{4, 5, 6}; withClientListener(client(), eventListener, Optional.of( new KeyValuePair<>("dynamic-filter-factory", Collections.singletonList(new byte[]{4, 5, 6}))), Optional.empty(), () -> { eventListener.expectNoEvents(Optional.empty()); byte[] key = k(m); client().put(key, 0, 0, v(m)); eventListener.expectNoEvents(Optional.empty()); client().put(acceptedKey, 0, 0, v(m)); eventListener.expectSingleEvent(cache, acceptedKey, Event.Type.CACHE_ENTRY_CREATED); client().put(acceptedKey, 0, 0, v(m, "v2-")); eventListener.expectSingleEvent(cache, acceptedKey, Event.Type.CACHE_ENTRY_MODIFIED); client().remove(key); eventListener.expectNoEvents(Optional.empty()); client().remove(acceptedKey); eventListener.expectSingleEvent(cache, acceptedKey, Event.Type.CACHE_ENTRY_REMOVED); }); } public void testFilteredEventsReplay(Method m) { EventLogListener eventListener = new EventLogListener(); byte[] staticAcceptedKey = new byte[]{1, 2, 3}; byte[] dynamicAcceptedKey = new byte[]{7, 8, 9}; byte[] key = k(m); client().put(key, 0, 0, v(m)); client().put(staticAcceptedKey, 0, 0, v(m)); client().put(dynamicAcceptedKey, 0, 0, v(m)); withClientListener(client(), eventListener, Optional.of( new KeyValuePair<>("static-filter-factory", Collections.emptyList())), Optional.empty(), true, true, () -> { eventListener.expectSingleEvent(cache, staticAcceptedKey, Event.Type.CACHE_ENTRY_CREATED); }); withClientListener(client(), eventListener, Optional.of( new KeyValuePair<>("dynamic-filter-factory", Collections.singletonList(new byte[]{7, 8, 9}))), Optional.empty(), true, true, () -> { eventListener.expectSingleEvent(cache, dynamicAcceptedKey, Event.Type.CACHE_ENTRY_CREATED); }); } public void testFilteredEventsNoReplay(Method m) { EventLogListener eventListener = new EventLogListener(); byte[] staticAcceptedKey = new byte[]{1, 2, 3}; byte[] dynamicAcceptedKey = new byte[]{7, 8, 9}; byte[] key = k(m); client().put(key, 0, 0, v(m)); client().put(staticAcceptedKey, 0, 0, v(m)); client().put(dynamicAcceptedKey, 0, 0, v(m)); withClientListener(client(), eventListener, Optional.of( new KeyValuePair<>("static-filter-factory", Collections.emptyList())), Optional.empty(), false, true, () -> { eventListener.expectNoEvents(Optional.empty()); }); withClientListener(client(), eventListener, Optional.of( new KeyValuePair<>("dynamic-filter-factory", Collections.singletonList(new byte[]{7, 8, 9}))), Optional.empty(), false, true, () -> { eventListener.expectNoEvents(Optional.empty()); }); } static class StaticKeyValueFilterFactory implements CacheEventFilterFactory { private byte[] staticKey; StaticKeyValueFilterFactory(byte[] staticKey) { this.staticKey = staticKey; } @Override public <K, V> CacheEventFilter<K, V> getFilter(Object[] params) { return (key, prevValue, prevMetadata, value, metadata, eventType) -> Arrays.equals(((byte[]) key), staticKey); } } static class DynamicKeyValueFilterFactory implements CacheEventFilterFactory { @Override public <K, V> CacheEventFilter<K, V> getFilter(Object[] params) { return (key, oldValue, oldMetadata, newValue, newMetadata, eventType) -> { byte[] acceptedKey = (byte[]) params[0]; return Arrays.equals(((byte[]) key), acceptedKey); }; } } }