package org.infinispan.server.test.jmx.management;
import static org.infinispan.server.test.util.ITestUtils.SERVER1_MGMT_PORT;
import static org.infinispan.server.test.util.ITestUtils.SERVER2_MGMT_PORT;
import static org.infinispan.server.test.util.ITestUtils.getAttribute;
import static org.infinispan.server.test.util.ITestUtils.invokeOperation;
import static org.infinispan.server.test.util.ITestUtils.sleepForSecs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import java.util.List;
import javax.management.ObjectName;
import org.infinispan.Version;
import org.infinispan.arquillian.core.InfinispanResource;
import org.infinispan.arquillian.core.RemoteInfinispanServer;
import org.infinispan.arquillian.core.RunningServer;
import org.infinispan.arquillian.core.WithRunningServer;
import org.infinispan.arquillian.utils.MBeanServerConnectionProvider;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.configuration.Configuration;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.server.infinispan.spi.InfinispanSubsystem;
import org.infinispan.server.test.client.memcached.MemcachedClient;
import org.jboss.arquillian.junit.Arquillian;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Test that JMX statistics/operations are available for an Infinispan server instance.
* <p/>
* TODO: operations/attributes of Transactions MBean - Transactions are only available in embedded mode (to be impl.
* for HotRod later: ISPN-375)
* <p/>
* operations/attributes of RecoveryAdmin MBean - the same as above
*
* @author <a href="mailto:mgencur@redhat.com">Martin Gencur</a>
*/
@RunWith(Arquillian.class)
@WithRunningServer({@RunningServer(name = "jmx-management-1"),@RunningServer(name = "jmx-management-2")})
public class JmxManagementIT {
final String JMX_DOMAIN = "jboss." + InfinispanSubsystem.SUBSYSTEM_NAME;
/* cache MBeans */
final String distCachePrefix = JMX_DOMAIN + ":type=Cache,name=\"default(dist_sync)\",manager=\"clustered\",component=";
final String memcachedCachePrefix = JMX_DOMAIN + ":type=Cache,name=\"memcachedCache(dist_sync)\",manager=\"clustered\",component=";
final String distCacheMBean = distCachePrefix + "Cache";
final String distributionManagerMBean = distCachePrefix + "DistributionManager";
// was renamed from DistributedStateTransferManager to StateTransferManager in 6.1.0ER1
final String distributionStateTransferManagerMBean = distCachePrefix + "StateTransferManager";
final String lockManagerMBean = distCachePrefix + "LockManager";
final String rpcManagerMBean = distCachePrefix + "RpcManager";
final String distCacheStatisticsMBean = distCachePrefix + "Statistics";
final String memcachedCacheStatisticsMBean = memcachedCachePrefix + "Statistics";
final String newExtraCacheMBean = JMX_DOMAIN + ":type=Cache,name=\"extracache(local)\",manager=\"clustered\",component=Cache";
/* cache manager MBeans */
final String managerPrefix = JMX_DOMAIN + ":type=CacheManager,name=\"clustered\",component=";
final String cacheManagerMBean = managerPrefix + "CacheManager";
/* server module MBeans */
final String hotRodServerMBean = JMX_DOMAIN + ":type=Server,name=HotRod,component=Transport";
final String memCachedServerMBean = JMX_DOMAIN + ":type=Server,name=Memcached,component=Transport";
final String protocolMBeanPrefix = "jgroups:type=protocol,cluster=\"default\",protocol=";
@InfinispanResource("jmx-management-1")
RemoteInfinispanServer server1;
@InfinispanResource("jmx-management-2")
RemoteInfinispanServer server2;
MBeanServerConnectionProvider provider;
MBeanServerConnectionProvider provider2;
RemoteCacheManager manager;
RemoteCache distCache;
MemcachedClient mc;
@Before
public void setUp() throws Exception {
if (provider == null) { // initialize just once
provider = new MBeanServerConnectionProvider(server1.getHotrodEndpoint().getInetAddress().getHostName(), SERVER1_MGMT_PORT);
provider2 = new MBeanServerConnectionProvider(server2.getHotrodEndpoint().getInetAddress().getHostName(), SERVER2_MGMT_PORT);
Configuration conf = new ConfigurationBuilder().addServer().host(server1.getHotrodEndpoint().getInetAddress().getHostName()).port(server1
.getHotrodEndpoint().getPort()).build();
manager = new RemoteCacheManager(conf);
distCache = manager.getCache();
mc = new MemcachedClient("UTF-8", server1.getMemcachedEndpoint().getInetAddress()
.getHostName(), server1.getMemcachedEndpoint().getPort(), 10000);
}
resetCacheStatistics();
distCache.clear();
}
private void resetCacheStatistics() throws Exception {
invokeOperation(provider, memcachedCacheStatisticsMBean, "resetStatistics", null, null);
}
@Test
public void testHotRodConnectionCount() throws Exception {
// get number of current local/global connections
int initialLocal = Integer.parseInt(getAttribute(provider, hotRodServerMBean, "numberOfLocalConnections"));
int initialGlobal = Integer.parseInt(getAttribute(provider, hotRodServerMBean, "numberOfGlobalConnections"));
assertEquals("Number of global connections obtained from node1 and node2 is not the same", initialGlobal,
Integer.parseInt(getAttribute(provider2, hotRodServerMBean, "numberOfGlobalConnections")));
// create another RCM and use it
Configuration conf = new ConfigurationBuilder().addServer().host(server1.getHotrodEndpoint().getInetAddress().getHostName()).port(server1
.getHotrodEndpoint().getPort()).build();
RemoteCacheManager manager2 = new RemoteCacheManager(conf);
manager2.getCache().put("key", "value");
// local connections increase by 1, global (in both nodes) by 2 (because we have distributed cache with 2 nodes, both nodes are accessed)
assertEquals(initialLocal + 1, Integer.parseInt(getAttribute(provider, hotRodServerMBean, "numberOfLocalConnections")));
assertEquals(initialGlobal + 2, Integer.parseInt(getAttribute(provider, hotRodServerMBean, "numberOfGlobalConnections")));
assertEquals(initialGlobal + 2, Integer.parseInt(getAttribute(provider2, hotRodServerMBean, "numberOfGlobalConnections")));
}
@Test
public void testMemCachedConnectionCount() throws Exception {
int initialLocal = Integer.parseInt(getAttribute(provider, memCachedServerMBean, "numberOfLocalConnections"));
int initialGlobal = Integer.parseInt(getAttribute(provider, memCachedServerMBean, "numberOfGlobalConnections"));
assertEquals("Number of global connections obtained from node1 and node2 is not the same", initialGlobal,
Integer.parseInt(getAttribute(provider2, memCachedServerMBean, "numberOfGlobalConnections")));
MemcachedClient mc2 = new MemcachedClient("UTF-8", server1.getMemcachedEndpoint().getInetAddress()
.getHostName(), server1.getMemcachedEndpoint().getPort(), 10000);
mc2.set("key", "value");
// with the memcached endpoint, the connection is counted only once
assertEquals(initialLocal + 1, Integer.parseInt(getAttribute(provider, memCachedServerMBean, "numberOfLocalConnections")));
assertEquals(initialGlobal + 1, Integer.parseInt(getAttribute(provider, memCachedServerMBean, "numberOfGlobalConnections")));
assertEquals(initialGlobal + 1, Integer.parseInt(getAttribute(provider2, memCachedServerMBean, "numberOfGlobalConnections")));
}
@Test
public void testHotRodServerAttributes() throws Exception {
distCache.put("key1", new byte[]{1, 2, 3, 4, 5});
assertNotEquals(0, Integer.parseInt(getAttribute(provider, hotRodServerMBean, "TotalBytesRead")));
assertNotEquals(0, Integer.parseInt(getAttribute(provider, hotRodServerMBean, "TotalBytesWritten")));
assertEquals(11222, Integer.parseInt(getAttribute(provider, hotRodServerMBean, "Port")));
assertEquals(Boolean.TRUE, Boolean.parseBoolean(getAttribute(provider, hotRodServerMBean, "tcpNoDelay")));
assertEquals(0, Integer.parseInt(getAttribute(provider, hotRodServerMBean, "ReceiveBufferSize")));
assertEquals(-1, Integer.parseInt(getAttribute(provider, hotRodServerMBean, "IdleTimeout")));
assertEquals(0, Integer.parseInt(getAttribute(provider, hotRodServerMBean, "SendBufferSize")));
assertNotEquals(0, Integer.parseInt(getAttribute(provider, hotRodServerMBean, "NumberWorkerThreads")));
assertNotEquals(0, getAttribute(provider, hotRodServerMBean, "HostName").length());
}
@Test
public void testMemcachedServerAttributes() throws Exception {
mc.set("key1", "value1");
assertNotEquals(0, Integer.parseInt(getAttribute(provider, memCachedServerMBean, "TotalBytesRead")));
assertNotEquals(0, Integer.parseInt(getAttribute(provider, memCachedServerMBean, "TotalBytesWritten")));
assertEquals(11211, Integer.parseInt(getAttribute(provider, memCachedServerMBean, "Port")));
assertEquals(Boolean.TRUE, Boolean.parseBoolean(getAttribute(provider, memCachedServerMBean, "tcpNoDelay")));
assertEquals(0, Integer.parseInt(getAttribute(provider, memCachedServerMBean, "ReceiveBufferSize")));
assertEquals(-1, Integer.parseInt(getAttribute(provider, memCachedServerMBean, "IdleTimeout")));
assertEquals(0, Integer.parseInt(getAttribute(provider, memCachedServerMBean, "SendBufferSize")));
assertNotEquals(0, Integer.parseInt(getAttribute(provider, memCachedServerMBean, "NumberWorkerThreads")));
assertNotEquals(0, getAttribute(provider, memCachedServerMBean, "HostName").length());
}
@Test
public void testCacheManagerAttributes() throws Exception {
assertEquals(6, Integer.parseInt(getAttribute(provider, cacheManagerMBean, "CreatedCacheCount")));
assertEquals(6, Integer.parseInt(getAttribute(provider, cacheManagerMBean, "DefinedCacheCount")));
assertEquals("clustered", getAttribute(provider, cacheManagerMBean, "Name"));
assertEquals(2, Integer.parseInt(getAttribute(provider, cacheManagerMBean, "ClusterSize")));
assertEquals("RUNNING", getAttribute(provider, cacheManagerMBean, "CacheManagerStatus"));
assertNotEquals(0, getAttribute(provider, cacheManagerMBean, "ClusterMembers").length());
assertNotEquals(0, getAttribute(provider, cacheManagerMBean, "NodeAddress").length());
assertEquals(6, Integer.parseInt(getAttribute(provider, cacheManagerMBean, "RunningCacheCount")));
assertNotEquals(0, getAttribute(provider, cacheManagerMBean, "PhysicalAddresses").length());
assertEquals(Version.getVersion(), getAttribute(provider, cacheManagerMBean, "Version"));
String names = getAttribute(provider, cacheManagerMBean, "DefinedCacheNames");
assertTrue(names.contains("default") && names.contains("memcachedCache"));
}
@Test
public void testDefaultCacheAttributes() throws Exception {
assertTrue(getAttribute(provider, distCacheMBean, "CacheName").contains("default"));
assertEquals("RUNNING", getAttribute(provider, distCacheMBean, "CacheStatus"));
}
@Test
public void testDefaultCacheOperations() throws Exception {
assertEquals("RUNNING", getAttribute(provider, distCacheMBean, "CacheStatus"));
invokeOperation(provider, distCacheMBean, "stop", null, null);
assertEquals("TERMINATED", getAttribute(provider, distCacheMBean, "CacheStatus"));
invokeOperation(provider, distCacheMBean, "start", null, null);
assertEquals("RUNNING", getAttribute(provider, distCacheMBean, "CacheStatus"));
}
@Test
public void testDistributionStateTransferManagerAttributes() throws Exception {
assertEquals(Boolean.FALSE, Boolean.parseBoolean(getAttribute(provider, distributionStateTransferManagerMBean, "StateTransferInProgress")));
assertEquals(Boolean.TRUE, Boolean.parseBoolean(getAttribute(provider, distributionStateTransferManagerMBean, "JoinComplete")));
}
@Test
public void testDistributionManagerOperations() throws Exception {
distCache.put("key2", "value1");
assertEquals(Boolean.FALSE, Boolean.parseBoolean(invokeOperation(provider, distributionManagerMBean, "isAffectedByRehash",
new Object[]{"key2"}, new String[]{"java.lang.Object"}).toString()));
assertEquals(Boolean.TRUE, Boolean.parseBoolean(invokeOperation(provider, distributionManagerMBean, "isLocatedLocally",
new Object[]{"key2"}, new String[]{"java.lang.String"}).toString()));
Object keyLocation = invokeOperation(provider, distributionManagerMBean, "locateKey", new Object[]{"key1"}, new String[]{"java.lang.String"});
assertTrue(keyLocation instanceof List);
}
@Test
public void testLockManagerAttributes() throws Exception {
assertEquals(0, Integer.parseInt(getAttribute(provider, lockManagerMBean, "NumberOfLocksHeld")));
assertEquals(0, Integer.parseInt(getAttribute(provider, lockManagerMBean, "NumberOfLocksAvailable")));
assertEquals(1000, Integer.parseInt(getAttribute(provider, lockManagerMBean, "ConcurrencyLevel")));
}
@Test
public void testCacheStatisticsAttributes() throws Exception {
mc.set("key1", "value1");
mc.set("key2", "value2");
mc.get("key1");
assertEquals(2, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "NumberOfEntries")));
assertEquals(1, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "NumberOfEntriesInMemory")));
mc.delete("key1");
assertEquals(2, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "Evictions")));
assertEquals(0, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "RemoveMisses")));
assertNotEquals(0.0, Double.parseDouble(getAttribute(provider, memcachedCacheStatisticsMBean, "ReadWriteRatio")));
assertNotEquals(0, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "Hits")));
assertEquals(Boolean.TRUE, Boolean.parseBoolean(getAttribute(provider, memcachedCacheStatisticsMBean, "StatisticsEnabled")));
sleepForSecs(2);
assertNotEquals(0, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "TimeSinceReset")));
assertNotEquals(0, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "ElapsedTime")));
assertEquals(0, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "Misses")));
assertNotEquals(0, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "RemoveHits")));
assertNotEquals(null, getAttribute(provider, memcachedCacheStatisticsMBean, "AverageWriteTime"));
assertNotEquals(0, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "Stores")));
assertTrue(1.0 == Double.parseDouble(getAttribute(provider, memcachedCacheStatisticsMBean, "HitRatio")));
assertNotEquals(null, getAttribute(provider, memcachedCacheStatisticsMBean, "AverageReadTime"));
}
@Test
public void testCacheStatisticsOperations() throws Exception {
resetCacheStatistics();
mc.set("key1", "value1");
assertEquals(1, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "Stores")));
resetCacheStatistics();
assertEquals(0, Integer.parseInt(getAttribute(provider, memcachedCacheStatisticsMBean, "Stores")));
}
@Test
public void testRpcManagerAttributes() throws Exception {
distCache.put("key1", "value1");
distCache.put("key2", "value2");
distCache.put("key3", "value3");
Integer.parseInt(getAttribute(provider, rpcManagerMBean, "AverageReplicationTime"));
assertTrue(1.0 == Double.parseDouble(getAttribute(provider, rpcManagerMBean, "SuccessRatioFloatingPoint")));
assertEquals(0, Integer.parseInt(getAttribute(provider, rpcManagerMBean, "ReplicationFailures")));
assertEquals(Boolean.TRUE, Boolean.parseBoolean(getAttribute(provider, rpcManagerMBean, "StatisticsEnabled")));
assertNotEquals(0, Integer.parseInt(getAttribute(provider, rpcManagerMBean, "ReplicationCount")));
assertEquals("100%", getAttribute(provider, rpcManagerMBean, "SuccessRatio"));
}
@Test
public void testRpcManagerOperations() throws Exception {
assertNotEquals(0, Integer.parseInt(getAttribute(provider, rpcManagerMBean, "ReplicationCount")));
invokeOperation(provider, rpcManagerMBean, "resetStatistics", null, null);
assertEquals(0, Integer.parseInt(getAttribute(provider, rpcManagerMBean, "ReplicationCount")));
}
/* for channel and protocol MBeans, test only they're registered, not all the attributes/operations */
@Test
public void testJGroupsChannelMBeanAvailable() throws Exception {
assertTrue(provider.getConnection().isRegistered(new ObjectName("jgroups:type=channel,cluster=\"cluster\"")));
}
}