/*
* Copyright 2008-2012 LinkedIn, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package voldemort.client;
import static org.junit.Assert.fail;
import java.lang.management.ManagementFactory;
import java.net.URISyntaxException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import voldemort.ServerTestUtils;
import voldemort.serialization.SerializerFactory;
import voldemort.server.AbstractSocketService;
import voldemort.utils.JmxUtils;
/**
*
* @author lgao Note: this test suite was originally created for testing mbean
* registration with client context. Because changing mbean names can be
* difficult for customers who builds monitoring systems based on the
* mbean names. We need to give some more thoughts on using client
* context as part of mbean names. This test suit is just a place holder
* for now.
*/
public class ClientJmxTest extends AbstractStoreClientFactoryTest {
private static String STATS_DOMAIN = "voldemort.store.stats";
private static String AGGREGATE_STATS_DOMAIN = "voldemort.store.stats.aggregate";
private AbstractSocketService socketService;
private MBeanServer mbServer = null;
private static int factoryJmxId = 0;
public ClientJmxTest() {
super();
}
private static String getAndIncrementJmxId() {
int current = factoryJmxId;
factoryJmxId++;
return (0 == current ? "" : "-" + current);
}
@Override
@Before
public void setUp() throws Exception {
super.setUp();
socketService = ServerTestUtils.getSocketService(true,
getClusterXml(),
getStoreDefXml(),
getValidStoreName(),
getLocalNode().getSocketPort());
socketService.start();
mbServer = ManagementFactory.getPlatformMBeanServer();
}
@Override
@After
public void tearDown() throws Exception {
mbServer = null;
super.tearDown();
socketService.stop();
}
@Override
protected StoreClientFactory getFactory(String... bootstrapUrls) {
return new SocketStoreClientFactory(new ClientConfig().setBootstrapUrls(bootstrapUrls)
.setEnableLazy(false)
.setEnableJmx(true)
.enableDefaultClient(true));
}
protected StoreClientFactory getFactoryWithClientContext(String clientContext,
String... bootstrapUrls) {
return new SocketStoreClientFactory(new ClientConfig().setBootstrapUrls(bootstrapUrls)
.setEnableLazy(false)
.setClientContextName(clientContext)
.setEnableJmx(true)
.enableDefaultClient(true));
}
@Test
public void testTwoClientContextOnJmx() throws Exception {
String clientContext1 = "clientA";
String clientContext2 = "clientB";
String jmxId1 = getAndIncrementJmxId();
String jmxId2 = getAndIncrementJmxId();
StoreClient<Object, Object> c1 = getFactoryWithClientContext(clientContext1,
getValidBootstrapUrl()).getStoreClient(getValidStoreName());
StoreClient<Object, Object> c2 = getFactoryWithClientContext(clientContext2,
getValidBootstrapUrl()).getStoreClient(getValidStoreName());
// checking for aggregate stats
ObjectName c1Name = JmxUtils.createObjectName(AGGREGATE_STATS_DOMAIN, "aggregate-perf"
+ jmxId1);
ObjectName c2Name = JmxUtils.createObjectName(AGGREGATE_STATS_DOMAIN, "aggregate-perf"
+ jmxId2);
checkForMbeanFound(c1Name);
checkForMbeanFound(c2Name);
mbServer.unregisterMBean(c1Name);
mbServer.unregisterMBean(c2Name);
// checking for per store stats
String c1type = "test" + jmxId1;
String c2type = "test" + jmxId2;
c1Name = JmxUtils.createObjectName(STATS_DOMAIN, c1type);
c2Name = JmxUtils.createObjectName(STATS_DOMAIN, c2type);
checkForMbeanFound(c1Name);
checkForMbeanFound(c2Name);
mbServer.unregisterMBean(c1Name);
mbServer.unregisterMBean(c2Name);
}
@SuppressWarnings("unchecked")
@Test
public void testSameContextOnJmx() throws Exception {
String clientContext = "clientContext";
String jmxId1 = getAndIncrementJmxId();
String jmxId2 = getAndIncrementJmxId();
StoreClient<Object, Object>[] clients = new StoreClient[2];
for(int i = 0; i < 2; i++) {
clients[i] = getFactoryWithClientContext(clientContext, getValidBootstrapUrl()).getStoreClient(getValidStoreName());
}
// checking for aggregate stats
ObjectName c1Name = JmxUtils.createObjectName(AGGREGATE_STATS_DOMAIN, "aggregate-perf"
+ jmxId1);
ObjectName c2Name = JmxUtils.createObjectName(AGGREGATE_STATS_DOMAIN, "aggregate-perf"
+ jmxId2);
checkForMbeanFound(c1Name);
checkForMbeanFound(c2Name);
mbServer.unregisterMBean(c1Name);
mbServer.unregisterMBean(c2Name);
// checking for per store stats
String c1type = "test" + jmxId1;
String c2type = "test" + jmxId2;
c1Name = JmxUtils.createObjectName(STATS_DOMAIN, c1type);
c2Name = JmxUtils.createObjectName(STATS_DOMAIN, c2type);
checkForMbeanFound(c1Name);
checkForMbeanFound(c2Name);
mbServer.unregisterMBean(c1Name);
mbServer.unregisterMBean(c2Name);
}
@Test
public void testTwoClientNoContextOnJmx() throws Exception {
String clientContextCompare = "";
String jmxId1 = getAndIncrementJmxId();
String jmxId2 = getAndIncrementJmxId();
StoreClient<Object, Object> c1 = getFactory(getValidBootstrapUrl()).getStoreClient(getValidStoreName());
StoreClient<Object, Object> c2 = getFactory(getValidBootstrapUrl()).getStoreClient(getValidStoreName());
// checking for aggregate stats
ObjectName c1Name = JmxUtils.createObjectName(AGGREGATE_STATS_DOMAIN, "aggregate-perf"
+ jmxId1);
ObjectName c2Name = JmxUtils.createObjectName(AGGREGATE_STATS_DOMAIN, "aggregate-perf"
+ jmxId2);
checkForMbeanFound(c1Name);
checkForMbeanFound(c2Name);
mbServer.unregisterMBean(c1Name);
mbServer.unregisterMBean(c2Name);
// checking for per store stats
String c1type = clientContextCompare + "test" + jmxId1;
String c2type = clientContextCompare + "test" + jmxId2;
c1Name = JmxUtils.createObjectName(STATS_DOMAIN, c1type);
c2Name = JmxUtils.createObjectName(STATS_DOMAIN, c2type);
checkForMbeanFound(c1Name);
checkForMbeanFound(c2Name);
mbServer.unregisterMBean(c1Name);
mbServer.unregisterMBean(c2Name);
}
@Test
public void testTwoClientNullContextOnJmx() throws Exception {
String clientContextCompare = "";
String jmxId1 = getAndIncrementJmxId();
String jmxId2 = getAndIncrementJmxId();
StoreClient<Object, Object> c1 = getFactoryWithClientContext(null, getValidBootstrapUrl()).getStoreClient(getValidStoreName());
StoreClient<Object, Object> c2 = getFactoryWithClientContext(null, getValidBootstrapUrl()).getStoreClient(getValidStoreName());
// checking for aggregate stats
ObjectName c1Name = JmxUtils.createObjectName(AGGREGATE_STATS_DOMAIN, "aggregate-perf"
+ jmxId1);
ObjectName c2Name = JmxUtils.createObjectName(AGGREGATE_STATS_DOMAIN, "aggregate-perf"
+ jmxId2);
checkForMbeanFound(c1Name);
checkForMbeanFound(c2Name);
mbServer.unregisterMBean(c1Name);
mbServer.unregisterMBean(c2Name);
// checking for per store stats
String c1type = clientContextCompare + "test" + jmxId1;
String c2type = clientContextCompare + "test" + jmxId2;
c1Name = JmxUtils.createObjectName(STATS_DOMAIN, c1type);
c2Name = JmxUtils.createObjectName(STATS_DOMAIN, c2type);
checkForMbeanFound(c1Name);
checkForMbeanFound(c2Name);
mbServer.unregisterMBean(c1Name);
mbServer.unregisterMBean(c2Name);
}
@SuppressWarnings("unchecked")
@Test
public void testSameContextAndFactory() throws Exception {
String clientContext = "clientContext";
String jmxId = getAndIncrementJmxId();
StoreClientFactory factory = getFactoryWithClientContext(clientContext,
getValidBootstrapUrl());
StoreClient<Object, Object>[] clients = new StoreClient[2];
for(int i = 0; i < 2; i++) {
clients[i] = factory.getStoreClient(getValidStoreName());
}
ObjectName cName = JmxUtils.createObjectName(AGGREGATE_STATS_DOMAIN, "aggregate-perf"
+ jmxId);
checkForMbeanFound(cName);
mbServer.unregisterMBean(cName);
// checking for per store stats
String ctype = "test" + jmxId;
ObjectName c1Name = JmxUtils.createObjectName(STATS_DOMAIN, ctype);
ObjectName c2Name = JmxUtils.createObjectName(STATS_DOMAIN, ctype);
checkForMbeanFound(c1Name);
checkForMbeanFound(c2Name);
mbServer.unregisterMBean(c1Name);
}
@SuppressWarnings("unchecked")
@Test
public void testDifferentId() throws Exception {
String clientContext = "clientContext";
String jmxId = getAndIncrementJmxId();
StoreClientFactory factory = getFactoryWithClientContext(clientContext,
getValidBootstrapUrl());
StoreClient<Object, Object>[] clients = new StoreClient[2];
clients[0] = factory.getStoreClient(getValidStoreName());
clients[1] = factory.getStoreClient(getValidStoreName());
ObjectName cName = JmxUtils.createObjectName(AGGREGATE_STATS_DOMAIN, "aggregate-perf"
+ jmxId);
checkForMbeanFound(cName);
mbServer.unregisterMBean(cName);
// checking for per store stats
String ctype = "test" + jmxId;
ObjectName c1Name = JmxUtils.createObjectName(STATS_DOMAIN, ctype);
ObjectName c2Name = JmxUtils.createObjectName(STATS_DOMAIN, ctype);
checkForMbeanFound(c1Name);
checkForMbeanFound(c2Name);
// assertTrue(!c1Name.equals(c2Name));
mbServer.unregisterMBean(c1Name);
// mbServer.unregisterMBean(c2Name);
}
private void checkForMbeanFound(ObjectName name) {
try {
mbServer.getMBeanInfo(name);
} catch(InstanceNotFoundException e) {
fail("MBean not found on the JMX Server: " + name.toString());
} catch(Exception e) {
fail("Test failed: " + e.getMessage());
}
}
@Override
protected StoreClientFactory getFactoryWithSerializer(SerializerFactory factory,
String... bootstrapUrls) {
return new SocketStoreClientFactory(new ClientConfig().setBootstrapUrls(bootstrapUrls)
.setEnableLazy(false)
.setSerializerFactory(factory)
.enableDefaultClient(true));
}
@Override
protected String getValidBootstrapUrl() throws URISyntaxException {
return getLocalNode().getSocketUrl().toString();
}
@Override
protected String getValidScheme() {
return SocketStoreClientFactory.URL_SCHEME;
}
}