From jbosscache-commits at lists.jboss.org Thu May 29 11:08:09 2008 Content-Type: multipart/mixed; boundary="===============1651376391750194441==" MIME-Version: 1.0 From: jbosscache-commits at lists.jboss.org To: jbosscache-commits at lists.jboss.org Subject: [jbosscache-commits] JBoss Cache SVN: r5918 - in core/trunk/src: main/java/org/jboss/cache/buddyreplication and 2 other directories. Date: Thu, 29 May 2008 11:08:09 -0400 Message-ID: --===============1651376391750194441== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: manik.surtani(a)jboss.com Date: 2008-05-29 11:08:09 -0400 (Thu, 29 May 2008) New Revision: 5918 Added: core/trunk/src/main/java/org/jboss/cache/RegionEmptyException.java core/trunk/src/test/java/org/jboss/cache/buddyreplication/EmptyRegionTes= t.java Modified: core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.j= ava core/trunk/src/main/java/org/jboss/cache/statetransfer/StateTransferMana= ger.java Log: JBCACHE-1349: Buddy replication state transfer fails if a marshalling regi= on is empty Added: core/trunk/src/main/java/org/jboss/cache/RegionEmptyException.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/src/main/java/org/jboss/cache/RegionEmptyException.java = (rev 0) +++ core/trunk/src/main/java/org/jboss/cache/RegionEmptyException.java 2008= -05-29 15:08:09 UTC (rev 5918) @@ -0,0 +1,29 @@ +package org.jboss.cache; + +/** + * Exception to represent a region being empty when state was expected in = that region. + * + * @author Manik Surtani (manik(a)jbo= ss.org) + * @since 2.2.0 + */ +public class RegionEmptyException extends CacheException +{ + public RegionEmptyException() + { + } + + public RegionEmptyException(Throwable cause) + { + super(cause); + } + + public RegionEmptyException(String msg) + { + super(msg); + } + + public RegionEmptyException(String msg, Throwable cause) + { + super(msg, cause); + } +} Modified: core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyMa= nager.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.= java 2008-05-29 14:49:10 UTC (rev 5917) +++ core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.= java 2008-05-29 15:08:09 UTC (rev 5918) @@ -15,6 +15,7 @@ import org.jboss.cache.Node; import org.jboss.cache.RPCManager; import org.jboss.cache.Region; +import org.jboss.cache.RegionEmptyException; import org.jboss.cache.RegionManager; import org.jboss.cache.commands.ReplicableCommand; import org.jboss.cache.commands.VisitableCommand; @@ -788,10 +789,7 @@ { Fqn f =3D r.getFqn(); state =3D acquireState(f); - if (state !=3D null) - { - stateMap.put(f, state); - } + if (state !=3D null) stateMap.put(f, state); } } else if (!configuration.isInactiveOnStartup()) @@ -885,7 +883,10 @@ byte[] state =3D generateState(fqn, timeouts[i], force); if (log.isDebugEnabled()) { - log.debug("acquireState(): got state"); + if (state =3D=3D null) + log.debug("acquireState(): Got null state. Region is pr= obably empty."); + else + log.debug("acquireState(): Got state"); } return state; } @@ -950,7 +951,14 @@ { ExposedByteArrayOutputStream baos =3D new ExposedByteArrayOutputS= tream(16 * 1024); out =3D new MarshalledValueOutputStream(baos); - stateTransferManager.getState(out, fqn, timeout, force, false); + try + { + stateTransferManager.getState(out, fqn, timeout, force, false); + } + catch (RegionEmptyException ree) + { + return null; + } result =3D baos.getRawBuffer(); } finally Modified: core/trunk/src/main/java/org/jboss/cache/statetransfer/StateTrans= ferManager.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/src/main/java/org/jboss/cache/statetransfer/StateTransferMan= ager.java 2008-05-29 14:49:10 UTC (rev 5917) +++ core/trunk/src/main/java/org/jboss/cache/statetransfer/StateTransferMan= ager.java 2008-05-29 15:08:09 UTC (rev 5918) @@ -12,6 +12,7 @@ import org.jboss.cache.CacheSPI; import org.jboss.cache.Fqn; import org.jboss.cache.NodeSPI; +import org.jboss.cache.RegionEmptyException; import org.jboss.cache.RegionManager; import org.jboss.cache.config.Configuration; import org.jboss.cache.factories.annotations.Inject; @@ -20,6 +21,7 @@ import org.jboss.cache.lock.LockManager; import static org.jboss.cache.lock.LockType.READ; import org.jboss.cache.lock.TimeoutException; +import org.jboss.cache.marshall.InactiveRegionException; import org.jboss.cache.marshall.Marshaller; import org.jboss.cache.marshall.NodeData; import org.jboss.cache.marshall.NodeDataMarker; @@ -83,7 +85,7 @@ public void getState(ObjectOutputStream out, Fqn fqn, long timeout, boo= lean force, boolean suppressErrors) throws Throwable { // can't give state for regions currently being activated/inactivated - boolean canProvideState =3D (!regionManager.isInactive(fqn) && cache= .peek(fqn, false, false) !=3D null); + boolean canProvideState =3D (!regionManager.isInactive(fqn) && cache= .peek(fqn, false) !=3D null); = boolean fetchTransientState =3D configuration.isFetchInMemoryState(); CacheLoaderManager cacheLoaderManager =3D cache.getCacheLoaderManage= r(); @@ -126,19 +128,20 @@ if (regionManager.isInactive(fqn)) { exceptionMessage +=3D " Region for fqn " + fqn + " is inact= ive."; + e =3D new InactiveRegionException(exceptionMessage); } + // this is not really an exception. Just provide empty state.= The exception is just a signal. Yes, lousy. - JBCACHE-1349 if (cache.peek(fqn, false, false) =3D=3D null) { - exceptionMessage +=3D " There is no cache node at fqn " + f= qn; + e =3D new RegionEmptyException(); } - e =3D new CacheException(exceptionMessage); } if (!fetchPersistentState && !fetchTransientState) { e =3D new CacheException("Cache instance at " + cache.getLocal= Address() + " is not configured to provide state"); } marshaller.objectToObjectStream(e, out); - throw e; + if (e !=3D null) throw e; } } = Added: core/trunk/src/test/java/org/jboss/cache/buddyreplication/EmptyRegio= nTest.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/src/test/java/org/jboss/cache/buddyreplication/EmptyRegionTe= st.java (rev 0) +++ core/trunk/src/test/java/org/jboss/cache/buddyreplication/EmptyRegionTe= st.java 2008-05-29 15:08:09 UTC (rev 5918) @@ -0,0 +1,88 @@ +package org.jboss.cache.buddyreplication; + +import org.jboss.cache.CacheSPI; +import org.jboss.cache.DefaultCacheFactory; +import org.jboss.cache.Fqn; +import org.jboss.cache.Region; +import org.jboss.cache.notifications.annotation.BuddyGroupChanged; +import org.jboss.cache.notifications.annotation.CacheListener; +import org.jboss.cache.notifications.event.Event; +import org.jboss.cache.util.CachePrinter; +import org.jboss.cache.util.TestingUtil; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * To test http://jira.jboss.org/jira/browse/JBCACHE-1349 + * + * @author Manik Surtani (manik(a)jbo= ss.org) + */ +(a)Test(groups =3D "functional") +public class EmptyRegionTest extends BuddyReplicationTestsBase +{ + CacheSPI c1, c2; + Fqn regionFqn =3D Fqn.fromString("/a/b/c"); + Fqn region2Fqn =3D Fqn.fromString("/d/e/f"); + Region region, region2; + CountDownLatch buddyJoinLatch =3D new CountDownLatch(1); + + @BeforeTest + public void setUp() throws Exception + { + c1 =3D createCache(1, null, false, false, false); + c1.getConfiguration().setUseRegionBasedMarshalling(true); + c1.getConfiguration().setFetchInMemoryState(true); + c2 =3D (CacheSPI) new DefaultCacheFactory().createCache(c1.getConfig= uration().clone(), false); + c1.start(); + region =3D c1.getRegion(regionFqn, true); + region2 =3D c1.getRegion(region2Fqn, true); + region.registerContextClassLoader(getClass().getClassLoader()); + region2.registerContextClassLoader(getClass().getClassLoader()); + c1.put(region2Fqn, "key", "value"); + + c2.create(); + c2.addCacheListener(new BuddyJoinListener()); + } + + @AfterTest + public void tearDown() + { + TestingUtil.killCaches(c1, c2); + } + + public void testEmptyRegion() throws InterruptedException + { + // region on c1 is empty - with no root node. + assert c1.getNode(regionFqn) =3D=3D null : "Node should not exist"; + assert c1.getRegion(regionFqn, false) !=3D null : "Region should exi= st"; + assert c1.getRegion(regionFqn, false).isActive() : "Region should be= active"; + + // now start c2 + c2.start(); + + // wait for buddy join notifications to complete. + buddyJoinLatch.await(60, TimeUnit.SECONDS); + + // should not throw any exceptions!! + + System.out.println("Cache1 " + CachePrinter.printCacheDetails(c1)); + System.out.println("Cache2 " + CachePrinter.printCacheDetails(c2)); + + // make sure region2 stuff did get transmitted! + assert c2.peek(BuddyFqnTransformer.getBackupFqn(c1.getLocalAddress()= , region2Fqn), false) !=3D null : "Region2 state should have transferred!"; + } + + @CacheListener + public class BuddyJoinListener + { + @BuddyGroupChanged + public void buddyJoined(Event e) + { + buddyJoinLatch.countDown(); + } + } +} --===============1651376391750194441==--