package org.radargun.service;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import com.tangosol.coherence.component.util.SafeNamedCache;
import com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.ReplicatedCache;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.CacheService;
import com.tangosol.net.NamedCache;
import com.tangosol.net.PartitionedService;
import com.tangosol.net.management.MBeanHelper;
import org.radargun.logging.Log;
import org.radargun.logging.LogFactory;
import org.radargun.traits.CacheInformation;
/**
* @author Radim Vansa <rvansa@redhat.com>
*/
public class CoherenceCacheInfo implements CacheInformation {
private static final Log log = LogFactory.getLog(Coherence3Service.class);
private static final String CACHE_JMX_NAME_TEMPLATE = "Coherence:type=Cache,service=%s,name=%s,nodeId=%d,tier=back";
private MBeanServer mBeanServer;
private String jmxCacheName;
private final Coherence3Service service;
public CoherenceCacheInfo(Coherence3Service service) {
this.service = service;
}
@Override
public String getDefaultCacheName() {
return service.cacheName;
}
@Override
public Collection<String> getCacheNames() {
return service.caches.keySet();
}
@Override
public CacheInformation.Cache getCache(String cacheName) {
return new Cache(service.getCache(cacheName));
}
protected class Cache implements CacheInformation.Cache {
protected NamedCache nc;
public Cache(NamedCache cache) {
nc = cache instanceof SafeNamedCache ? ((SafeNamedCache) cache).getNamedCache() : cache;
}
@Override
public long getOwnedSize() {
if (nc.getCacheService() instanceof PartitionedService) {
return getCacheSize();
} else {
return -1;
}
}
/**
* The size reports owned entries for distributed (partitioned) cache and all entries for replicated cache
* @return
*/
protected long getCacheSize() {
if (nc != null) {
synchronized (this) {
if (mBeanServer == null || jmxCacheName == null) {
int nodeId = CacheFactory.getCluster().getLocalMember().getId();
jmxCacheName = String.format(CACHE_JMX_NAME_TEMPLATE, nc.getCacheService().getInfo().getServiceType(), nc.getCacheName(), nodeId);
mBeanServer = MBeanHelper.findMBeanServer();
}
}
try {
AttributeList list = mBeanServer.getAttributes(new ObjectName(jmxCacheName), new String[] { "Units", "UnitFactor" } );
return ((Integer) ((Attribute) list.get(0)).getValue()) * ((Integer) ((Attribute)list.get(1)).getValue());
} catch (Exception e) {
log.warn("Failed to retrieve JMX info from object " + jmxCacheName + "\n" + e);
return -1;
}
} else {
log.info("Cache is not available.");
return -1;
}
}
@Override
public long getLocallyStoredSize() {
if (nc.getCacheService() instanceof PartitionedService) {
return -1;
} else {
return getCacheSize();
}
}
@Override
public long getMemoryStoredSize() {
return -1;
}
@Override
public long getTotalSize() {
return nc == null ? -1 : nc.size();
}
@Override
public Map<?, Long> getStructuredSize() {
return Collections.singletonMap(nc.getCacheName(), getOwnedSize());
}
@Override
public int getNumReplicas() {
CacheService service = nc.getCacheService();
if (service instanceof PartitionedService) {
return ((PartitionedService) service).getBackupCount() + 1;
} else if (service instanceof ReplicatedCache) {
return service.getCluster().getMemberSet().size();
} else {
return 1;
}
}
@Override
public int getEntryOverhead() {
return -1;
}
}
}