/*
* JBoss, Home of Professional Open Source.
* Copyright 2009 Red Hat, Inc. and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.cluster.testutil;
import java.util.List;
import org.jboss.cache.Cache;
import org.jboss.cache.CacheSPI;
/**
* Utilities related to dealing with JBoss Cache.
*
* @author Brian Stansberry
*
* @version $Revision: $
*/
public class JBossCacheUtil
{
/**
* Loops, continually calling {@link #areCacheViewsComplete(org.jboss.cache.Cache[])}
* until it either returns true or <code>timeout</code> ms have elapsed.
*
* @param caches caches which must all have consistent views
* @param timeout max number of ms to loop
* @throws RuntimeException if <code>timeout</code> ms have elapse without
* all caches having the same number of members.
*/
public static void blockUntilViewsReceived(Cache[] caches, long timeout)
{
long failTime = System.currentTimeMillis() + timeout;
while (System.currentTimeMillis() < failTime)
{
sleepThread(100);
if (areCacheViewsComplete(caches))
{
return;
}
}
throw new RuntimeException("timed out before caches had complete views" + views(caches));
}
/**
* Checks each cache to see if the number of elements in the array
* returned by {@link CacheSPI#getMembers()} matches the size of
* the <code>caches</code> parameter.
*
* @param caches caches that should form a View
* @return <code>true</code> if all caches have
* <code>caches.length</code> members; false otherwise
* @throws IllegalStateException if any of the caches have MORE view
* members than caches.length
*/
public static boolean areCacheViewsComplete(Cache[] caches)
{
return areCacheViewsComplete(caches, true);
}
public static boolean areCacheViewsComplete(Cache[] caches, boolean barfIfTooManyMembers)
{
int memberCount = caches.length;
for (int i = 0; i < memberCount; i++)
{
if (!isCacheViewComplete(caches[i], memberCount, barfIfTooManyMembers))
{
return false;
}
}
return true;
}
public static boolean isCacheViewComplete(Cache c, int memberCount)
{
return isCacheViewComplete(c, memberCount, true);
}
public static boolean isCacheViewComplete(Cache cache, int memberCount, boolean barfIfTooManyMembers)
{
List members = cache.getMembers();
if (members == null || memberCount > members.size())
{
return false;
}
else if (memberCount < members.size())
{
if (barfIfTooManyMembers)
{
// This is an exceptional condition
StringBuilder sb = new StringBuilder("Cache at address ");
sb.append(cache.getLocalAddress());
sb.append(" had ");
sb.append(members.size());
sb.append(" members; expecting ");
sb.append(memberCount);
sb.append(". Members were (");
for (int j = 0; j < members.size(); j++)
{
if (j > 0)
{
sb.append(", ");
}
sb.append(members.get(j));
}
sb.append(')');
throw new IllegalStateException(sb.toString());
}
else return false;
}
return true;
}
/**
* Puts the current thread to sleep for the desired number of ms, suppressing
* any exceptions.
*
* @param sleeptime number of ms to sleep
*/
public static void sleepThread(long sleeptime)
{
try
{
Thread.sleep(sleeptime);
}
catch (InterruptedException ie)
{
}
}
private static String views(Cache... caches)
{
StringBuilder builder = new StringBuilder("[\n");
for (Cache c:caches)
{
builder.append(" ").append(c.getLocalAddress()).append("->").append(c.getMembers()).append("\n");
}
builder.append("]");
return builder.toString();
}
/**
* Prevent instantiation
*/
private JBossCacheUtil()
{
// TODO Auto-generated constructor stub
}
}