package org.infinispan.client.hotrod.event;
import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.withClientListener;
import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
import static org.testng.AssertJUnit.assertNull;
import java.util.concurrent.TimeUnit;
import org.infinispan.Cache;
import org.infinispan.client.hotrod.event.CustomEventLogListener.CustomEvent;
import org.infinispan.client.hotrod.event.CustomEventLogListener.FilterConverterFactory;
import org.infinispan.client.hotrod.event.CustomEventLogListener.FilterCustomEventLogListener;
import org.infinispan.client.hotrod.event.CustomEventLogListener.StaticConverterFactory;
import org.infinispan.client.hotrod.event.CustomEventLogListener.StaticCustomEventLogListener;
import org.infinispan.client.hotrod.event.EventLogListener.StaticCacheEventFilterFactory;
import org.infinispan.client.hotrod.event.EventLogListener.StaticFilteredEventLogListener;
import org.infinispan.client.hotrod.test.HotRodClientTestingUtil;
import org.infinispan.client.hotrod.test.MultiHotRodServersTest;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.notifications.cachelistener.CacheNotifier;
import org.infinispan.server.hotrod.HotRodServer;
import org.infinispan.server.hotrod.configuration.HotRodServerConfigurationBuilder;
import org.infinispan.test.TestingUtil;
import org.infinispan.util.ControlledTimeService;
import org.infinispan.util.TimeService;
import org.testng.annotations.Test;
@Test(groups = "functional", testName = "client.hotrod.event.ClientClusterExpirationEventsTest")
public class ClientClusterExpirationEventsTest extends MultiHotRodServersTest {
static final int NUM_SERVERS = 2;
protected ControlledTimeService ts0;
protected ControlledTimeService ts1;
@Override
protected void createCacheManagers() throws Throwable {
createHotRodServers(NUM_SERVERS, getCacheConfiguration());
injectTimeServices();
}
private ConfigurationBuilder getCacheConfiguration() {
ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false);
builder.clustering().hash().numOwners(1);
return hotRodCacheConfiguration(builder);
}
protected HotRodServer addHotRodServer(ConfigurationBuilder builder) {
EmbeddedCacheManager cm = addClusterEnabledCacheManager(builder);
HotRodServerConfigurationBuilder serverBuilder = new HotRodServerConfigurationBuilder();
HotRodServer server = HotRodClientTestingUtil.startHotRodServer(cm, serverBuilder);
server.addCacheEventConverterFactory("static-converter-factory", new StaticConverterFactory());
server.addCacheEventFilterConverterFactory("filter-converter-factory", new FilterConverterFactory());
servers.add(server);
return server;
}
private void injectTimeServices() {
long now = System.currentTimeMillis();
ts0 = new ControlledTimeService(now);
TestingUtil.replaceComponent(server(0).getCacheManager(), TimeService.class, ts0, true);
ts1 = new ControlledTimeService(now);
TestingUtil.replaceComponent(server(1).getCacheManager(), TimeService.class, ts1, true);
}
public void testSimpleExpired() {
final Integer key0 = HotRodClientTestingUtil.getIntKeyForServer(server(0));
final EventLogListener<Integer> l = new EventLogListener<>(client(0).getCache());
withClientListener(l, remote -> {
l.expectNoEvents();
remote.put(key0, "one", 10, TimeUnit.MINUTES);
l.expectOnlyCreatedEvent(key0);
ts0.advance(TimeUnit.MINUTES.toMillis(10) + 1);
assertNull(remote.get(key0));
l.expectOnlyExpiredEvent(key0);
});
}
public void testFilteringInCluster() {
// Generate key and add static filter in all servers
final Integer key0 = HotRodClientTestingUtil.getIntKeyForServer(server(0));
final Integer key1 = HotRodClientTestingUtil.getIntKeyForServer(server(1));
for (HotRodServer server : servers)
server.addCacheEventFilterFactory("static-filter-factory", new StaticCacheEventFilterFactory(key1));
final StaticFilteredEventLogListener<Integer> l = new StaticFilteredEventLogListener<>(client(0).getCache());
withClientListener(l, remote -> {
l.expectNoEvents();
remote.put(key0, "one", 10, TimeUnit.MINUTES);
l.expectNoEvents();
remote.put(key1, "two", 10, TimeUnit.MINUTES);
l.expectOnlyCreatedEvent(key1);
// Now expire both
ts0.advance(TimeUnit.MINUTES.toMillis(10) + 1);
ts1.advance(TimeUnit.MINUTES.toMillis(10) + 1);
assertNull(remote.get(key0));
l.expectNoEvents();
assertNull(remote.get(key1));
l.expectOnlyExpiredEvent(key1);
});
}
public void testConversionInCluster() {
final Integer key0 = HotRodClientTestingUtil.getIntKeyForServer(server(0));
final Integer key1 = HotRodClientTestingUtil.getIntKeyForServer(server(1));
final StaticCustomEventLogListener<Integer> l = new StaticCustomEventLogListener<>(client(0).getCache());
withClientListener(l, remote -> {
l.expectNoEvents();
remote.put(key0, "one", 10, TimeUnit.MINUTES);
l.expectCreatedEvent(new CustomEvent(key0, "one", 0));
remote.put(key1, "two", 10, TimeUnit.MINUTES);
l.expectCreatedEvent(new CustomEvent(key1, "two", 0));
// Now expire both
ts0.advance(TimeUnit.MINUTES.toMillis(10) + 1);
ts1.advance(TimeUnit.MINUTES.toMillis(10) + 1);
assertNull(remote.get(key0));
l.expectExpiredEvent(new CustomEvent(key0, "one", 0));
assertNull(remote.get(key1));
l.expectExpiredEvent(new CustomEvent(key1, "two", 0));
});
}
public void testFilterCustomEventsInCluster() {
final Integer key0 = HotRodClientTestingUtil.getIntKeyForServer(server(0));
final Integer key1 = HotRodClientTestingUtil.getIntKeyForServer(server(1));
final FilterCustomEventLogListener<Integer> l = new FilterCustomEventLogListener<>(client(0).getCache());
withClientListener(l, new Object[]{key0}, null, remote -> {
remote.put(key0, "one", 10, TimeUnit.MINUTES);
l.expectCreatedEvent(new CustomEvent(key0, null, 1));
remote.put(key1, "two", 10, TimeUnit.MINUTES);
l.expectCreatedEvent(new CustomEvent(key1, "two", 1));
// Now expire both
ts0.advance(TimeUnit.MINUTES.toMillis(10) + 1);
ts1.advance(TimeUnit.MINUTES.toMillis(10) + 1);
assertNull(remote.get(key0));
l.expectExpiredEvent(new CustomEvent(key0, null, 2));
assertNull(remote.get(key1));
l.expectExpiredEvent(new CustomEvent(key1, "two", 2));
});
}
public void testNullValueMetadataExpiration() {
final Integer key = HotRodClientTestingUtil.getIntKeyForServer(server(0));
final EventLogListener<Integer> l = new EventLogListener<>(client(0).getCache());
withClientListener(l, remote -> {
Cache<Integer, String> cache0 = cache(0);
CacheNotifier notifier = cache0.getAdvancedCache().getComponentRegistry().getComponent(CacheNotifier.class);
byte[] keyBytes = HotRodClientTestingUtil.toBytes(key);
// Note we are manually forcing an expiration event with a null value and metadata
notifier.notifyCacheEntryExpired(keyBytes, null, null, null);
l.expectOnlyExpiredEvent(key);
});
}
}