package org.jboss.cache.notifications;
import org.jboss.cache.Cache;
import org.jboss.cache.CacheFactory;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.buddyreplication.BuddyGroup;
import org.jboss.cache.buddyreplication.BuddyReplicationTestsBase;
import org.jboss.cache.config.BuddyReplicationConfig;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.misc.TestingUtil;
import org.jboss.cache.notifications.annotation.BuddyGroupChanged;
import org.jboss.cache.notifications.annotation.CacheListener;
import org.jboss.cache.notifications.annotation.ViewChanged;
import org.jboss.cache.notifications.event.BuddyGroupChangedEvent;
import org.jboss.cache.notifications.event.ViewChangedEvent;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.concurrent.CountDownLatch;
/**
* @author Manik Surtani (<a href="mailto:manik@jboss.org">manik@jboss.org</a>)
* @since 2.1.0
*/
@Test(groups = "functional")
public class BuddyGroupChangeNotificationTest extends BuddyReplicationTestsBase
{
Cache c1, c2, c3;
Listener listener;
static CountDownLatch latch1 = new CountDownLatch(1);
static CountDownLatch latch2 = new CountDownLatch(1);
static boolean stage2 = false;
static boolean notificationsReceived = true;
@BeforeMethod
public void setUp() throws CloneNotSupportedException
{
CacheFactory cf = new DefaultCacheFactory();
c1 = cf.createCache(false);
c1.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
BuddyReplicationConfig brc = new BuddyReplicationConfig();
brc.setEnabled(true);
c1.getConfiguration().setBuddyReplicationConfig(brc);
c2 = cf.createCache(c1.getConfiguration().clone(), false);
c3 = cf.createCache(c1.getConfiguration().clone(), false);
c1.start();
c2.start();
c3.start();
// make sure views are received and groups are formed first
TestingUtil.blockUntilViewsReceived(60000, c1, c2, c3);
Cache[] caches = new Cache[]{c1, c2, c3};
listener = new Listener(caches);
c2.addCacheListener(listener);
}
@AfterMethod
public void tearDown()
{
TestingUtil.killCaches(c1, c2, c3);
}
@Test(timeOut = 60000)
public void testChangingGroups() throws InterruptedException
{
// initial state
assertIsBuddy(c1, c2, true);
assertIsBuddy(c2, c3, true);
assertIsBuddy(c3, c1, true);
// kill c3
c3.stop();
latch1.await();
assertIsBuddy(c1, c2, true);
assertIsBuddy(c2, c1, true);
stage2 = true;
c3.start();
latch2.await();
assertIsBuddy(c1, c2, true);
assertIsBuddy(c2, c3, true);
assertIsBuddy(c3, c1, true);
assert notificationsReceived;
}
@CacheListener
public static class Listener
{
Cache[] caches;
int numActiveCaches;
public Listener(Cache[] caches)
{
this.caches = caches;
}
@ViewChanged
public void viewChanged(ViewChangedEvent e)
{
numActiveCaches = e.getNewView().getMembers().size();
}
@BuddyGroupChanged
public void buddyChanged(BuddyGroupChangedEvent e)
{
System.out.println("Received event " + e);
if (!e.isPre())
{
BuddyGroup bg = e.getBuddyGroup();
boolean passed = bg.getDataOwner().equals(caches[1].getLocalAddress()) &&
bg.getBuddies().size() == 1 &&
bg.getBuddies().contains(caches[(numActiveCaches == 3) ? 2 : 0].getLocalAddress());
notificationsReceived = notificationsReceived && passed;
if (stage2)
latch2.countDown();
else
latch1.countDown();
}
}
}
}