/*
* Copyright 2010 Proofpoint, 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 io.airlift.jmx.http.rpc;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Binder;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Scopes;
import io.airlift.bootstrap.Bootstrap;
import io.airlift.bootstrap.LifeCycleManager;
import io.airlift.http.server.TheServlet;
import io.airlift.http.server.testing.TestingHttpServer;
import io.airlift.http.server.testing.TestingHttpServerModule;
import io.airlift.json.JsonModule;
import io.airlift.node.testing.TestingNodeModule;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.weakref.jmx.MBeanExporter;
import org.weakref.jmx.Managed;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.lang.management.ManagementFactory;
import java.util.UUID;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import static org.weakref.jmx.ObjectNames.generatedNameOf;
@Test(singleThreaded = true)
public class TestMBeanServerResource
{
private LifeCycleManager lifeCycleManager;
private TestingHttpServer server;
private MBeanServerConnection mbeanServerConnection;
private MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
private TestMBean testMBean;
private ObjectName testMBeanName;
@BeforeMethod
public void setup()
throws Exception
{
Bootstrap app = new Bootstrap(
new TestingNodeModule(),
new TestingHttpServerModule(),
new JsonModule(),
new JmxHttpRpcModule(TheServlet.class),
new Module()
{
@Override
public void configure(Binder binder)
{
binder.bind(MBeanServer.class).toInstance(platformMBeanServer);
binder.bind(TestMBean.class).in(Scopes.SINGLETON);
}
});
Injector injector = app
.strictConfig()
.doNotInitializeLogging()
.initialize();
lifeCycleManager = injector.getInstance(LifeCycleManager.class);
server = injector.getInstance(TestingHttpServer.class);
testMBean = injector.getInstance(TestMBean.class);
testMBeanName = new ObjectName(generatedNameOf(TestMBean.class));
MBeanExporter exporter = new MBeanExporter(platformMBeanServer);
exporter.export(testMBeanName.toString(), testMBean);
JMXConnector connect = JMXConnectorFactory.connect(
new JMXServiceURL("service:jmx:" + server.getBaseUrl()),
ImmutableMap.of(JMXConnector.CREDENTIALS, new String[] {"foo", "bar"}));
mbeanServerConnection = connect.getMBeanServerConnection();
}
@AfterMethod(alwaysRun = true)
public void teardown()
throws Exception
{
if (lifeCycleManager != null) {
lifeCycleManager.stop();
platformMBeanServer.unregisterMBean(testMBeanName);
}
}
@Test
public void testGetMBeanCount()
throws Exception
{
assertEquals(mbeanServerConnection.getMBeanCount(), platformMBeanServer.getMBeanCount());
}
@Test
public void testIsRegistered()
throws Exception
{
assertEquals(mbeanServerConnection.isRegistered(testMBeanName), true);
assertEquals(mbeanServerConnection.isRegistered(new ObjectName("fake", "fake", "fake")), false);
}
@Test
public void testIsInstanceOf()
throws Exception
{
assertEquals(mbeanServerConnection.isInstanceOf(testMBeanName, TestMBean.class.getName()), true);
assertEquals(mbeanServerConnection.isInstanceOf(testMBeanName, Object.class.getName()), true);
assertEquals(mbeanServerConnection.isInstanceOf(testMBeanName, UUID.class.getName()), false);
}
@Test
public void testGetDefaultDomain()
throws Exception
{
assertEquals(mbeanServerConnection.getDefaultDomain(), platformMBeanServer.getDefaultDomain());
}
@Test
public void testGetDomains()
throws Exception
{
assertEquals(mbeanServerConnection.getDomains(), platformMBeanServer.getDomains());
}
@Test
public void testGetObjectInstance()
throws Exception
{
assertEquals(mbeanServerConnection.getObjectInstance(testMBeanName), platformMBeanServer.getObjectInstance(testMBeanName));
}
@Test
public void testGetMBeanInfo()
throws Exception
{
assertEquals(mbeanServerConnection.getMBeanInfo(testMBeanName), platformMBeanServer.getMBeanInfo(testMBeanName));
}
@Test
public void testGetQueryMBeanNames()
throws Exception
{
assertEquals(mbeanServerConnection.queryNames(testMBeanName, null), platformMBeanServer.queryNames(testMBeanName, null));
assertEquals(mbeanServerConnection.queryNames(new ObjectName("*:*"), null), platformMBeanServer.queryNames(new ObjectName("*:*"), null));
}
@Test
public void testGetQueryMBeans()
throws Exception
{
assertEquals(mbeanServerConnection.queryMBeans(testMBeanName, null), platformMBeanServer.queryMBeans(testMBeanName, null));
assertEquals(mbeanServerConnection.queryMBeans(new ObjectName("*:*"), null), platformMBeanServer.queryMBeans(new ObjectName("*:*"), null));
}
@Test
public void testGetAttribute()
throws Exception
{
assertEquals(mbeanServerConnection.getAttribute(testMBeanName, "Value"), null);
testMBean.setValue("FOO");
assertEquals(mbeanServerConnection.getAttribute(testMBeanName, "Value"), "FOO");
assertEquals(mbeanServerConnection.getAttribute(testMBeanName, "ObjectValue"), null);
testMBean.setObjectValue(UUID.randomUUID());
assertEquals(mbeanServerConnection.getAttribute(testMBeanName, "ObjectValue"), testMBean.getObjectValue());
}
@Test
public void testGetAttributes()
throws Exception
{
assertEquals(mbeanServerConnection.getAttributes(testMBeanName, new String[]{"Value", "ObjectValue"}),
new AttributeList(ImmutableList.of(new Attribute("Value", null), new Attribute("ObjectValue", null))));
testMBean.setValue("FOO");
testMBean.setObjectValue(UUID.randomUUID());
assertEquals(mbeanServerConnection.getAttributes(testMBeanName, new String[]{"Value", "ObjectValue"}),
new AttributeList(ImmutableList.of(new Attribute("Value", "FOO"), new Attribute("ObjectValue", testMBean.getObjectValue()))));
}
@Test
public void testSetAttribute()
throws Exception
{
mbeanServerConnection.setAttribute(testMBeanName, new Attribute("Value", "Foo"));
assertEquals(testMBean.getValue(), "Foo");
mbeanServerConnection.setAttribute(testMBeanName, new Attribute("Value", null));
assertEquals(testMBean.getValue(), null);
UUID uuid = UUID.randomUUID();
mbeanServerConnection.setAttribute(testMBeanName, new Attribute("ObjectValue", uuid));
assertEquals(testMBean.getObjectValue(), uuid);
mbeanServerConnection.setAttribute(testMBeanName, new Attribute("ObjectValue", null));
assertEquals(testMBean.getObjectValue(), null);
}
@Test
public void testSetAttributes()
throws Exception
{
UUID uuid = UUID.randomUUID();
mbeanServerConnection.setAttributes(testMBeanName, new AttributeList(ImmutableList.of(new Attribute("Value", "Foo"), new Attribute("ObjectValue", uuid))));
assertEquals(testMBean.getValue(), "Foo");
assertEquals(testMBean.getObjectValue(), uuid);
mbeanServerConnection.setAttributes(testMBeanName, new AttributeList(ImmutableList.of(new Attribute("Value", null), new Attribute("ObjectValue", null))));
assertEquals(testMBean.getValue(), null);
assertEquals(testMBean.getObjectValue(), null);
}
@Test
public void testInvoke()
throws Exception
{
assertEquals(testMBean.noArgsMethodInvoked, false);
mbeanServerConnection.invoke(testMBeanName, "noArgsMethod", null, null);
assertEquals(testMBean.noArgsMethodInvoked, true);
UUID uuid = UUID.randomUUID();
assertEquals(mbeanServerConnection.invoke(testMBeanName, "echo", new Object[]{uuid}, new String[]{Object.class.getName()}), uuid);
}
@Test
public void testInvokeThrows()
throws Exception
{
try {
mbeanServerConnection.invoke(testMBeanName, "throwException", new Object[]{new Exception("exception-message")}, new String[]{Throwable.class.getName()});
fail("Expected exception");
}
catch (MBeanException e) {
assertTrue(e.getCause() instanceof Exception);
assertEquals(e.getCause().getMessage(), "exception-message");
}
}
public static class TestMBean
{
private String value;
private Object objectValue;
public boolean noArgsMethodInvoked;
@Managed
public String getValue()
{
return value;
}
@Managed
public void setValue(String value)
{
this.value = value;
}
@Managed
public Object getObjectValue()
{
return objectValue;
}
@Managed
public void setObjectValue(Object objectValue)
{
this.objectValue = objectValue;
}
@Managed
public void noArgsMethod()
{
noArgsMethodInvoked = true;
}
@Managed
public Object echo(Object object)
{
return object;
}
@Managed
public void throwException(Throwable t)
throws Throwable
{
throw t;
}
}
}