/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.cache.buddyreplication;
import org.jboss.cache.Fqn;
import org.jboss.cache.PropertyConfigurator;
import org.jboss.cache.TreeCache;
import org.jboss.cache.TreeCacheMBean;
import org.jboss.cache.config.Option;
import org.jboss.cache.misc.TestingUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Tests handling of the buddy backup region during region
* activation and inactivation
*
* @author Brian Stansberry
*/
public class BuddyBackupActivationInactivationTest extends BuddyReplicationTestsBase
{
public static final Fqn A = Fqn.fromString("/a");
public static final Fqn A_B = Fqn.fromString("/a/b");
public static final String JOE = "JOE";
protected Map caches;
private ClassLoader orig_TCL;
public void testBuddyBackupActivation() throws Exception
{
TreeCacheMBean[] caches = new TreeCacheMBean[2];
caches[0] = createCache("cache1", true, true, true);
caches[1] = createCache("cache2", true, true, true);
TestingUtil.blockUntilViewsReceived(caches, VIEW_BLOCK_TIMEOUT);
caches[0].activateRegion("/a");
caches[0].put(A_B, "name", JOE);
TestingUtil.sleepThread(getSleepTimeout());
caches[1].activateRegion("/a");
Fqn fqn = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN,
BuddyManager.getGroupNameFromAddress(caches[0].getLocalAddress()));
fqn = new Fqn(fqn, A_B);
assertEquals("State transferred with activation", JOE, caches[1].get(fqn, "name"));
}
public void testReplToInactiveRegion() throws Exception
{
TreeCacheMBean[] caches = new TreeCacheMBean[2];
caches[0] = createCache("cache1", true, true, true);
caches[1] = createCache("cache2", true, true, true);
TestingUtil.blockUntilViewsReceived(caches, VIEW_BLOCK_TIMEOUT);
caches[0].activateRegion("/a");
// Activate the buddy backup subtree in the recipient so any
// repl message doesn't get rejected due to that tree being inactive
caches[1].activateRegion(BuddyManager.BUDDY_BACKUP_SUBTREE);
caches[0].put(A_B, "name", JOE);
TestingUtil.sleepThread(getSleepTimeout());
assertNull("No replication to inactive region", caches[1].get(A_B, "name"));
Fqn fqn = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN,
BuddyManager.getGroupNameFromAddress(caches[0].getLocalAddress()));
fqn = new Fqn(fqn, A_B);
assertNull("No replication to inactive backup region", caches[1].get(fqn, "name"));
}
public void testBuddyBackupInactivation() throws Exception
{
TreeCacheMBean cache1 = createCache("cache1", true, true, true);
cache1.activateRegion("/a");
Option option = new Option();
option.setCacheModeLocal(true);
Fqn fqn = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, "test");
fqn = new Fqn(fqn, A_B);
cache1.put(fqn, "name", JOE, option);
assertEquals("Put OK", JOE, cache1.get(fqn, "name"));
cache1.inactivateRegion("/a");
assertNull("Inactivation cleared region", cache1.get(fqn, "name"));
}
protected TreeCacheMBean createCache(String cacheID,
boolean sync,
boolean useMarshalling,
boolean startCache)
throws Exception
{
if (caches.get(cacheID) != null)
throw new IllegalStateException(cacheID + " already created");
TreeCacheMBean tree=new TreeCache();
PropertyConfigurator config=new PropertyConfigurator();
String configFile = sync ? "META-INF/replSync-service.xml"
: "META-INF/replAsync-service.xml";
config.configure(tree, configFile); // read in generic replAsync xml
tree.setClusterName("Test");
if (useMarshalling) {
tree.setUseRegionBasedMarshalling(true);
tree.setInactiveOnStartup(true);
}
tree.setBuddyReplicationConfig(getBuddyConfig());
// Call the hook that allows testing with the multiplexer
configureMultiplexer(tree);
// Put the cache in the map before starting, so if it fails in
// start it can still be destroyed later
caches.put(cacheID, tree);
if (startCache)
{
tree.createService();
tree.startService();
validateMultiplexer(tree);
}
return tree;
}
protected void setUp() throws Exception
{
super.setUp();
caches = new HashMap();
// Save the TCL in case a test changes it
orig_TCL = Thread.currentThread().getContextClassLoader();
}
protected void tearDown() throws Exception
{
super.tearDown();
// Restore the TCL in case a test changed it
Thread.currentThread().setContextClassLoader(orig_TCL);
Set keys = caches.keySet();
String[] cacheIDs = new String[keys.size()];
cacheIDs = (String[]) keys.toArray(cacheIDs);
for (int i = 0; i < cacheIDs.length; i++)
{
stopCache((TreeCache) caches.get(cacheIDs[i]));
}
}
protected void stopCache(TreeCache cache)
{
if (cache != null)
{
try {
cache.stopService();
cache.destroyService();
}
catch (Exception e) {
System.out.println("Exception stopping cache " + e.getMessage());
e.printStackTrace(System.out);
}
}
}
private Element getBuddyConfig() throws Exception
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
Element config = doc.createElement("config");
doc.appendChild(config);
Element replEnabled = doc.createElement("buddyReplicationEnabled");
replEnabled.appendChild(doc.createTextNode("true"));
config.appendChild(replEnabled);
Element gravDisabled = doc.createElement("autoDataGravitation");
gravDisabled.appendChild(doc.createTextNode("false"));
config.appendChild(gravDisabled);
return config;
}
}