/*
* Copyright (C) The MX4J Contributors.
* All rights reserved.
*
* This software is distributed under the terms of the MX4J License version 1.0.
* See the terms of the MX4J License in the documentation provided with this software.
*/
package test.javax.management.remote.rmi;
import java.io.File;
import java.io.Serializable;
import java.net.URL;
import java.util.Set;
import javax.management.Attribute;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.loading.PrivateMLet;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import test.MX4JTestCase;
import test.javax.management.remote.support.Marshalling;
import test.javax.management.remote.support.Unknown;
/**
* @version $Revision: 1.5 $
*/
public class RMIMarshallingTest extends MX4JTestCase
{
private MBeanServer server = null;
private MBeanServerConnection conn = null;
private JMXConnectorServer cntorServer = null;
private JMXConnector cntor = null;
private ObjectName mbeanName;
private ObjectName mbeanLoaderName;
public RMIMarshallingTest(String s)
{
super(s);
}
public void setUp() throws Exception
{
super.setUp();
// Create a classloader that sees only the MBean and its parameter classes (Unknown)
File mbeanJar = new File("dist/test/mx4j-tests.jar");
PrivateMLet mbeanLoader = new PrivateMLet(new URL[]{mbeanJar.toURL()}, getClass().getClassLoader().getParent(), false);
mbeanLoaderName = ObjectName.getInstance("marshal:type=mlet");
server = newMBeanServer();
server.registerMBean(mbeanLoader, mbeanLoaderName);
JMXServiceURL url = new JMXServiceURL("rmi", "localhost", 0);
cntorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
cntorServer.start();
cntor = JMXConnectorFactory.connect(cntorServer.getAddress());
conn = cntor.getMBeanServerConnection();
mbeanName = ObjectName.getInstance("marshal:type=mbean");
}
public void tearDown() throws Exception
{
if (cntor != null) cntor.close();
if (cntorServer != null) cntorServer.stop();
}
protected static class MockNotificationListener implements NotificationListener, Serializable
{
long numberOfNotifications = 0;
public void handleNotification(Notification notification, Object handback)
{
// System.out.println("[MockNotificationListener] Notification: "+notification+" Handback: "+handback);
assertEquals(notification.getSequenceNumber(), numberOfNotifications);
assertEquals(notification.getType(), Unknown.class.getName());
numberOfNotifications++;
synchronized (this)
{
this.notify();
}
}
public synchronized void waitOnNotification(long timeout, long sequence) throws InterruptedException
{
long to;
if (timeout > 0)
to = System.currentTimeMillis() + timeout;
else
to = -1;
while (numberOfNotifications < sequence) // Check for missed notification
{
this.wait(timeout);
if (to > -1 && System.currentTimeMillis() >= to) // Check if waited for full timeout
{
Thread.currentThread().interrupt();
break;
}
}
}
}
protected static class MockNotificationFilter implements NotificationFilter, Serializable
{
public boolean isNotificationEnabled(Notification notification)
{
// System.out.println("[MockNotificationFilter] Notification: "+notification);
return true;
}
}
private void createMBean() throws Exception
{
ObjectInstance inst = conn.createMBean(Marshalling.class.getName(), mbeanName, new Object[]{new Unknown()}, new String[]{Unknown.class.getName()});
}
public void testCreateMBean() throws Exception
{
conn.createMBean(Marshalling.class.getName(), mbeanName);
checkRegistration();
conn.createMBean(Marshalling.class.getName(),
mbeanName, new Object[]{new Unknown()},
new String[]{Unknown.class.getName()});
checkRegistration();
}
private void checkRegistration() throws Exception
{
// Check registrations
if (!conn.isRegistered(mbeanName)) fail();
if (!server.isRegistered(mbeanName)) fail();
conn.unregisterMBean(mbeanName);
}
public void testInstanceOf() throws Exception
{
createMBean();
// Check instanceof
if (!conn.isInstanceOf(mbeanName, Marshalling.class.getName())) fail();
if (!server.isInstanceOf(mbeanName, Marshalling.class.getName())) fail();
}
public void testInvocationUnknownReturn() throws Exception
{
createMBean();
// Check invocation
Object returned = conn.invoke(mbeanName, "unknownReturnValue", new Object[0], new String[0]);
if (!returned.getClass().getName().equals(Unknown.class.getName())) fail();
returned = server.invoke(mbeanName, "unknownReturnValue", new Object[0], new String[0]);
if (!returned.getClass().getName().equals(Unknown.class.getName())) fail();
Object remoteUnk = conn.invoke(mbeanName, "unknownArgument", new Object[]{new Unknown()}, new String[]{Unknown.class.getName()});
Object localUnk = server.invoke(mbeanName, "unknownArgument", new Object[]{new Unknown()}, new String[]{Unknown.class.getName()});
assertEquals(remoteUnk, localUnk);
}
public void testUnregisterMBean() throws Exception
{
createMBean();
// Check unregistration
conn.unregisterMBean(mbeanName);
if (conn.isRegistered(mbeanName)) fail();
if (server.isRegistered(mbeanName)) fail();
}
public void testNotifications() throws Exception
{
createMBean();
MockNotificationListener listener = new MockNotificationListener();
conn.addNotificationListener(mbeanName,
listener,
new MockNotificationFilter(),
new Object());
Thread.sleep(1000L);
Attribute att = new Attribute("UnknownAttribute", new Unknown());
conn.setAttribute(mbeanName, att);
Thread.sleep(1000L);
// This triggers a notification
try
{
listener.waitOnNotification(1000L, 1);
}
catch (InterruptedException ignore)
{
}
assertEquals(1, listener.numberOfNotifications);
conn.removeNotificationListener(mbeanName, listener);
Thread.sleep(1000L);
conn.setAttribute(mbeanName, att);
Thread.sleep(1000L);
// This triggers a notification
try
{
listener.waitOnNotification(1000L, 2);
}
catch (InterruptedException ignore)
{
}
assertEquals(1, listener.numberOfNotifications);
}
public void testQuery() throws Exception
{
createMBean();
ObjectName pattern = mbeanName;
ObjectName query = mbeanName;
Set beans = conn.queryMBeans(pattern, query);
Object[] set = beans.toArray();
assertEquals(1, set.length);
// System.out.println("set[0]: "+set[0]+" class: "+set[0].getClass());
ObjectInstance inst = (ObjectInstance)set[0];
assertTrue(inst.getClassName().equals(Marshalling.class.getName()));
beans = conn.queryNames(pattern, query);
set = beans.toArray();
assertEquals(1, set.length);
// System.out.println("set[0]: "+set[0]+" class: "+set[0].getClass());
ObjectName nm = (ObjectName)set[0];
assertTrue(nm.equals(mbeanName));
}
public void testAttributes() throws Exception
{
createMBean();
Unknown value = new Unknown();
Attribute att = new Attribute("UnknownAttribute", value);
conn.setAttribute(mbeanName, att);
Object returned = conn.getAttribute(mbeanName, "UnknownAttribute");
assertTrue(returned.getClass().getName().equals(Unknown.class.getName()));
}
}