package com.j256.simplejmx.client; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.net.InetAddress; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.management.Attribute; import javax.management.AttributeNotFoundException; import javax.management.JMException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.ObjectName; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import com.j256.simplejmx.common.IoUtils; import com.j256.simplejmx.common.JmxAttributeMethod; import com.j256.simplejmx.common.JmxOperation; import com.j256.simplejmx.common.JmxResource; import com.j256.simplejmx.common.ObjectNameUtil; import com.j256.simplejmx.server.JmxServer; public class JmxClientTest { private static final int JMX_PORT = 8000; private static final String JMX_DOMAIN = "foo.com"; private static JmxServer server; private static String beanName; private static ObjectName objectName; private static String anotherBeanName; private static ObjectName anotherObjectName; private static JmxClient client; private static JmxClient closedClient; private static JmxClientTestObject testObject; @BeforeClass public static void beforeClass() throws Exception { InetAddress address = InetAddress.getByName("localhost"); server = new JmxServer(address, JMX_PORT); server.start(); testObject = new JmxClientTestObject(); server.register(testObject); beanName = JmxClientTestObject.class.getSimpleName(); objectName = ObjectNameUtil.makeObjectName(JMX_DOMAIN, beanName); JmxClientTestAnotherObject anotherObj = new JmxClientTestAnotherObject(); server.register(anotherObj); anotherBeanName = JmxClientTestAnotherObject.class.getSimpleName(); anotherObjectName = ObjectNameUtil.makeObjectName(JMX_DOMAIN, anotherBeanName); client = new JmxClient(address, JMX_PORT); closedClient = new JmxClient(address, JMX_PORT); closedClient.closeThrow(); closedClient.closeThrow(); } @AfterClass public static void afterClass() { IoUtils.closeQuietly(client); client = null; IoUtils.closeQuietly(server); server = null; } @Test(expected = IllegalArgumentException.class) public void testNullUrl() throws Exception { new JmxClient(null).close(); } @Test(expected = JMException.class) public void testInvalidUrl() throws Exception { new JmxClient("invalid url").close(); } @Test public void testHostPort() throws Exception { @SuppressWarnings("resource") JmxClient client = new JmxClient("localhost", JMX_PORT); try { client.getAttribute(objectName, "x"); } finally { client.closeThrow(); } } @Test public void testHostPortEnvironment() throws Exception { @SuppressWarnings("resource") JmxClient client = new JmxClient("localhost", JMX_PORT, Collections.<String, Object> singletonMap("jmx.remote.x.client.connection.check.period", 5000L)); try { client.getAttribute(objectName, "x"); } finally { client.closeThrow(); } } @Test public void testGetBeanDomains() throws Exception { String[] domains = client.getBeanDomains(); boolean found = false; for (String domain : domains) { if (JMX_DOMAIN.equals(domain)) { found = true; } } assertTrue(found); } @Test(expected = IllegalArgumentException.class) public void testGetBeanDomainsClosed() throws Exception { closedClient.getBeanDomains(); } @Test public void testGetBeanNames() throws Exception { Set<ObjectName> names = client.getBeanNames(); boolean found = false; for (ObjectName name : names) { if (name.equals(objectName)) { found = true; } } assertTrue(found); } @Test(expected = IllegalArgumentException.class) public void testGetBeanNamesClosed() throws Exception { closedClient.getBeanNames(); } @Test public void testGetAttributesInfoStringString() throws Exception { MBeanAttributeInfo[] infos = client.getAttributesInfo(JMX_DOMAIN, beanName); assertEquals(2, infos.length); assertEquals("null", infos[0].getName()); assertEquals(String.class.getName(), infos[0].getType()); assertEquals("x", infos[1].getName()); assertEquals(int.class.getName(), infos[1].getType()); int val = 349813481; testObject.x = val; Object value = client.getAttribute(JMX_DOMAIN, beanName, "x"); assertTrue(value instanceof Integer); assertEquals(val, (int) value); } @Test public void testGetAttributesInfo() throws Exception { MBeanAttributeInfo[] infos = client.getAttributesInfo(objectName); assertEquals(2, infos.length); assertEquals("null", infos[0].getName()); assertEquals(String.class.getName(), infos[0].getType()); assertEquals("x", infos[1].getName()); assertEquals(int.class.getName(), infos[1].getType()); } @Test(expected = IllegalArgumentException.class) public void testGetAttributesInfoClosed() throws Exception { closedClient.getAttributesInfo(objectName); } @Test public void testGetAttributeInfo() throws Exception { MBeanAttributeInfo info = client.getAttributeInfo(objectName, "x"); assertNotNull(info); assertEquals(int.class.getName(), info.getType()); } @Test public void testGetAttributeInfoUnknown() throws Exception { assertNull(client.getAttributeInfo(objectName, "not-known")); } @Test(expected = IllegalArgumentException.class) public void testSetAttributeUnknown() throws Exception { client.setAttribute(objectName, "not-known", "1"); } @Test(expected = AttributeNotFoundException.class) public void testSetAttributeUnknownObj() throws Exception { client.setAttribute(objectName, "not-known", 1); } @Test(expected = IllegalArgumentException.class) public void testGetAttributeInfoClosed() throws Exception { closedClient.getAttributeInfo(objectName, "x"); } @Test public void testGetOperationsInfo() throws Exception { MBeanOperationInfo[] infos = client.getOperationsInfo(objectName); assertEquals(13, infos.length); Set<String> expectedNames = new HashSet<String>(Arrays.asList("times", "shortToString", "byteToString", "charToString", "doThrow")); // orders seem to change for (MBeanOperationInfo info : infos) { expectedNames.remove(info.getName()); } for (String expectedName : expectedNames) { fail("should have matched " + expectedName); } } @Test public void testGetOperationsInfoStringString() throws Exception { MBeanOperationInfo[] infos = client.getOperationsInfo(JMX_DOMAIN, beanName); assertEquals(13, infos.length); } @Test(expected = IllegalArgumentException.class) public void testGetOperationsInfoClosed() throws Exception { closedClient.getOperationsInfo(objectName); } @Test public void testGetOperationInfo() throws Exception { MBeanOperationInfo info = client.getOperationInfo(objectName, "times"); assertNotNull(info); MBeanParameterInfo[] params = info.getSignature(); assertEquals(2, params.length); assertEquals(short.class.getName(), params[0].getType()); assertEquals(int.class.getName(), params[1].getType()); assertEquals(long.class.getName(), info.getReturnType()); } @Test public void testGetOperationInfoUnknown() throws Exception { assertNull(client.getOperationInfo(objectName, "unknownoperation")); } @Test(expected = IllegalArgumentException.class) public void testGetOperationInfoClosed() throws Exception { closedClient.getOperationInfo(objectName, "times"); } @Test public void testGetAttributeStringString() throws Exception { int val = 13123; client.setAttribute(objectName, "x", val); Object result = client.getAttribute(JMX_DOMAIN, beanName, "x"); assertEquals(val, result); } @Test public void testGetAttribute() throws Exception { int val = 13123; client.setAttribute(objectName, "x", val); Object result = client.getAttribute(objectName, "x"); assertEquals(val, result); } @Test public void testGetAttributes() throws Exception { int val = 13123; client.setAttribute(objectName, "x", val); List<Attribute> results = client.getAttributes(objectName, new String[] { "x" }); assertNotNull(results); assertEquals(1, results.size()); assertEquals(new Attribute("x", val), results.get(0)); } @Test public void testGetAttributesStringString() throws Exception { int val = 213132; client.setAttribute(objectName, "x", val); List<Attribute> results = client.getAttributes(JMX_DOMAIN, beanName, new String[] { "x" }); assertNotNull(results); assertEquals(1, results.size()); assertEquals(new Attribute("x", val), results.get(0)); } @Test(expected = IllegalArgumentException.class) public void testGetAttributeClosed() throws Exception { closedClient.getAttribute(objectName, "x"); } @Test public void testGetAttributeAsStringStringString() throws Exception { int val = 13123; client.setAttribute(objectName, "x", val); String result = client.getAttributeString(JMX_DOMAIN, beanName, "x"); assertEquals(Integer.toString(val), result); } @Test public void testGetAttributeAsString() throws Exception { int val = 13123; client.setAttribute(objectName, "x", val); String result = client.getAttributeString(objectName, "x"); assertEquals(Integer.toString(val), result); } @Test public void testGetAttributeAsStringNull() throws Exception { String result = client.getAttributeString(objectName, "null"); assertNull(result); } @Test(expected = IllegalArgumentException.class) public void testGetAttributeAsStringClosed() throws Exception { closedClient.getAttributeString(objectName, "x"); } @Test public void testSetAttributeStringString() throws Exception { int val = 2131231231; client.setAttribute(JMX_DOMAIN, beanName, "x", val); Object result = client.getAttribute(objectName, "x"); assertEquals(val, result); } @Test public void testSetAttributeStringStringToString() throws Exception { int val = 2131231231; client.setAttribute(JMX_DOMAIN, beanName, "x", Integer.toString(val)); Object result = client.getAttribute(objectName, "x"); assertEquals(val, result); } @Test public void testSetAttributeToString() throws Exception { int val = 2131231231; client.setAttribute(objectName, "x", Integer.toString(val)); Object result = client.getAttribute(objectName, "x"); assertEquals(val, result); } @Test public void testSetAttributes() throws Exception { int val = 217731231; client.setAttributes(objectName, Collections.singletonList(new Attribute("x", val))); Object result = client.getAttribute(objectName, "x"); assertEquals(val, result); } @Test public void testSetAttributesStringString() throws Exception { int val = 218131231; client.setAttributes(JMX_DOMAIN, beanName, Collections.singletonList(new Attribute("x", val))); Object result = client.getAttribute(objectName, "x"); assertEquals(val, result); } @Test(expected = IllegalArgumentException.class) public void testSetAttributeClosed() throws Exception { closedClient.setAttribute(objectName, "x", 1); } @Test public void testInvokeOperationStringString() throws Exception { short val1 = 231; int val2 = 524; Object result = client.invokeOperation(JMX_DOMAIN, beanName, "times", val1, val2); long times = val1 * val2; assertEquals(times, result); } @Test public void testInvokeOperationStringStringString() throws Exception { short val1 = 231; int val2 = 524; Object result = client.invokeOperation(JMX_DOMAIN, beanName, "times", Short.toString(val1), Integer.toString(val2)); long times = val1 * val2; assertEquals(times, result); } @Test public void testInvokeOperation() throws Exception { short val1 = 231; int val2 = 524; Object result = client.invokeOperation(objectName, "times", val1, val2); long times = val1 * val2; assertEquals(times, result); } @Test public void testInvokeOperationStrings() throws Exception { short val1 = 231; int val2 = 524; Object result = client.invokeOperation(objectName, "times", Short.toString(val1), Integer.toString(val2)); long times = val1 * val2; assertEquals(times, result); } @Test public void testInvokeOperationStringsNoArgs() throws Exception { assertNull(client.invokeOperation(objectName, "returnNull", new String[0])); } @Test public void testInvokeOperationNoArgs() throws Exception { assertNull(client.invokeOperation(objectName, "returnNull", new Object[0])); } @Test public void testInvokeOperationStringStringNoArgs() throws Exception { assertNull(client.invokeOperation(JMX_DOMAIN, beanName, "returnNull", new String[0])); } @Test public void testInvokeOperationArgs() throws Exception { assertNull(client.invokeOperation(objectName, "returnNull", 1)); } @Test(expected = IllegalArgumentException.class) public void testInvokeOperationClosed() throws Exception { closedClient.invokeOperation(objectName, "returnNull", new Object[0]); } @Test(expected = IllegalArgumentException.class) public void testInvokeOperationUnknown() throws Exception { client.invokeOperation(objectName, "unknown-operation"); } @Test public void testInvokeOperationToString() throws Exception { short val1 = 21231; int val2 = 524; String result = client.invokeOperationToString(objectName, "times", Short.toString(val1), Integer.toString(val2)); int times = val1 * val2; assertEquals(Long.toString(times), result); } @Test public void testBoolToString() throws Exception { testThingtoString("booleanToString", true); } @Test public void testCharToString() throws Exception { testThingtoString("charToString", '\0'); } @Test public void testCharToStringNoArg() throws Exception { testThingtoString("charToString", "\0", ""); } @Test public void testByteToString() throws Exception { testThingtoString("byteToString", (byte) 10); } @Test public void testShortToString() throws Exception { testThingtoString("shortToString", (short) 1042); } @Test public void testIntToString() throws Exception { testThingtoString("intToString", (int) 123423320); } @Test public void testLongToString() throws Exception { testThingtoString("longToString", (long) 10824424242L); } @Test public void testFloatToString() throws Exception { testThingtoString("floatToString", (float) 12.56); } @Test public void testDoubleToString() throws Exception { testThingtoString("doubleToString", (double) 1313.4122); } @Test public void testInvokeOperationStringsObject() throws Exception { testThingtoString("dateToString", new Date()); } @Test public void testSystem() throws Exception { client.getAttribute(ObjectName.getInstance("java.lang:type=OperatingSystem"), "AvailableProcessors"); } @Test public void testGetBeansForDomain() throws Exception { String domainName = "java.lang"; Set<ObjectName> beans = client.getBeanNames(domainName); boolean found = false; String beanName = domainName + ":type=OperatingSystem"; for (ObjectName objectName : beans) { String nameString = objectName.getCanonicalName(); assertTrue(nameString.startsWith(domainName + ":")); if (beanName.equals(nameString)) { found = true; } } assertTrue("Found bean " + beanName, found); } @Test public void testAnotherObjectAttribute() throws Exception { int val = 273907923; client.setAttribute(anotherObjectName, "y", Integer.toString(val)); assertEquals(val, client.getAttribute(anotherObjectName, "y")); } @Test public void testAnotherObjectOperation() throws Exception { short val1 = 23; int val2 = 245; Object result = client.invokeOperation(anotherObjectName, "timesTwo", val1, val2); long times = val1 * val2; assertEquals(times, result); } @Test public void testCoverage() { try { new JmxClient(JMX_PORT).close(); } catch (JMException jme) { // ignored } } @Test public void testUserNamePass() throws Exception { new JmxClient("localhost", JMX_PORT, "user", "pass").close(); } @Test public void testUserNamePassNull() throws Exception { new JmxClient("localhost", JMX_PORT, null, null).close(); } @Test public void testServiceUrl() throws Exception { new JmxClient("service:jmx:rmi:///jndi/rmi://localhost:" + JMX_PORT + "/jmxrmi").close(); } @Test public void testUserNamePassServiceUrl() throws Exception { new JmxClient("service:jmx:rmi:///jndi/rmi://localhost:" + JMX_PORT + "/jmxrmi", null, null).close(); } @Test public void testUserNamePassNull2() throws Exception { new JmxClient("service:jmx:rmi:///jndi/rmi://localhost:" + JMX_PORT + "/jmxrmi", null, null, Collections.<String, Object> emptyMap()).close(); } /* ======================================================================= */ private void testThingtoString(String methodName, Object arg) throws Exception { String argString = arg.toString(); testThingtoString(methodName, argString, argString); } private void testThingtoString(String methodName, String expected, String argString) throws Exception { assertEquals(expected, client.invokeOperationToString(objectName, methodName, argString)); } @JmxResource(domainName = JMX_DOMAIN) protected static class JmxClientTestObject { volatile int x; @JmxAttributeMethod public void setX(int x) { this.x = x; } @JmxAttributeMethod public int getX() { return x; } @JmxAttributeMethod public String getNull() { return null; } @JmxOperation public long times(short x1, int x2) { return x1 * x2; } @JmxOperation public void doThrow() { throw new RuntimeException("throw away!"); } @JmxOperation public Object returnNull() { return null; } @JmxOperation public Object returnNull(int anotherArg) { return null; } @JmxOperation public String dateToString(Date date) { return date.toString(); } @JmxOperation public String booleanToString(boolean booleanVal) { return Boolean.toString(booleanVal); } @JmxOperation public String charToString(char charVal) { return Character.toString(charVal); } @JmxOperation public String byteToString(byte byteVal) { return Byte.toString(byteVal); } @JmxOperation public String shortToString(short shortVal) { return Short.toString(shortVal); } @JmxOperation public String intToString(int intVal) { return Integer.toString(intVal); } @JmxOperation public String longToString(long longVal) { return Long.toString(longVal); } @JmxOperation public String floatToString(float floatVal) { return Float.toString(floatVal); } @JmxOperation public String doubleToString(double doubleVal) { return Double.toString(doubleVal); } } @JmxResource(domainName = JMX_DOMAIN) protected static class JmxClientTestAnotherObject { int y; @JmxAttributeMethod public int getY() { return y; } @JmxAttributeMethod public void setY(int y) { this.y = y; } @JmxOperation public long timesTwo(short y1, int y2) { return y1 * y2; } } }