package org.oddjob.jmx; import java.lang.management.ManagementFactory; import java.util.HashMap; import java.util.Map; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; import javax.management.remote.rmi.RMIConnectorServer; import junit.framework.TestCase; import org.apache.log4j.Logger; import org.oddjob.Oddjob; import org.oddjob.OddjobLookup; import org.oddjob.Resetable; import org.oddjob.Stateful; import org.oddjob.Structural; import org.oddjob.arooa.registry.BeanDirectory; import org.oddjob.arooa.registry.BeanDirectoryOwner; import org.oddjob.arooa.standard.StandardArooaSession; import org.oddjob.arooa.xml.XMLConfiguration; import org.oddjob.jmx.general.Vendor; import org.oddjob.rmi.RMIRegistryJob; import org.oddjob.state.ParentState; import org.oddjob.state.ServiceState; import org.oddjob.structural.StructuralEvent; import org.oddjob.structural.StructuralListener; import org.oddjob.tools.StateSteps; public class JMXServiceJobTest extends TestCase { private static final Logger logger = Logger.getLogger(JMXServiceJobTest.class); ObjectName objectName; MBeanServer mBeanServer; JMXConnectorServer cntorServer; Vendor simple = new Vendor("Hay Medows"); @Override protected void setUp() throws Exception { super.setUp(); logger.info("----------------- " + getName() + " ----------------"); } protected void createServer(Map<String, ?> environment) throws Exception { RMIRegistryJob rmi = new RMIRegistryJob(); rmi.setPort(13013); rmi.run(); JMXServiceURL serviceURL = new JMXServiceURL( "service:jmx:rmi://ignored/jndi/rmi://localhost:13013/jmxrmi"); objectName = new ObjectName("fruit:service=vendor,name=Pickles"); mBeanServer = ManagementFactory.getPlatformMBeanServer(); mBeanServer.registerMBean(simple, objectName); cntorServer = JMXConnectorServerFactory.newJMXConnectorServer( serviceURL, environment, mBeanServer); cntorServer.start(); String address = cntorServer.getAddress().toString(); logger.info("Server started. Clients may connect to: " + address); } @Override protected void tearDown() throws Exception { mBeanServer.unregisterMBean(objectName); cntorServer.stop(); } private class ChildCatcher implements StructuralListener { final Map<String, Object> children = new HashMap<String, Object>(); public void childAdded(StructuralEvent event) { // Check for bug where directory was set after children // created. if (event.getSource() instanceof BeanDirectoryOwner) { BeanDirectoryOwner directoryOwner = (BeanDirectoryOwner) event.getSource(); BeanDirectory directory = directoryOwner.provideBeanDirectory(); if (directory == null) { throw new NullPointerException( "This is the bug - directory is null!!!"); } } Object child = event.getChild(); String name = child.toString(); if (children.containsKey(name)) { throw new IllegalStateException(); } children.put(name, child); } public void childRemoved(StructuralEvent event) { children.remove(event.getChild().toString()); } } public void testExample() throws Exception { createServer(null); Oddjob oddjob = new Oddjob(); oddjob.setConfiguration(new XMLConfiguration( "org/oddjob/jmx/JMXServiceExample.xml", getClass().getClassLoader())); oddjob.load(); OddjobLookup lookup = new OddjobLookup(oddjob); Object test = lookup.lookup("jmx-service"); // here to catch a bug with BeanDirectoryOwner ChildCatcher domainsCatcher = new ChildCatcher(); ((Structural) test).addStructuralListener(domainsCatcher); oddjob.run(); assertEquals(ParentState.STARTED, oddjob.lastStateEvent().getState()); // Test Bean Directory String farm = lookup.lookup("echo-farm.text", String.class); assertEquals("Hay Medows", farm); // Check property set. assertEquals(4.2, lookup.lookup( "jmx-service/fruit:service=vendor,name=Pickles.Rating", double.class), 0.01); // Check invoked assertEquals(94.23, lookup.lookup( "invoke-quote.result", double.class), 0.01); // Check domains assertTrue(domainsCatcher.children.containsKey("fruit")); Structural fruitDomain = (Structural) domainsCatcher.children.get("fruit"); ChildCatcher fruitCatcher = new ChildCatcher(); fruitDomain.addStructuralListener(fruitCatcher); assertTrue(fruitCatcher.children.size() == 1); oddjob.stop(); assertEquals(ParentState.COMPLETE, oddjob.lastStateEvent().getState()); assertEquals(0, fruitCatcher.children.size()); assertEquals(0, domainsCatcher.children.size()); // Do it all again Object sequential = lookup.lookup("sequential"); ((Resetable) sequential).hardReset(); assertEquals(ParentState.READY, ((Stateful) sequential).lastStateEvent().getState()); ((Runnable) sequential).run(); assertEquals(ParentState.STARTED, oddjob.lastStateEvent().getState()); // Check invoked assertEquals(94.23, lookup.lookup( "invoke-quote.result", double.class), 0.01); oddjob.stop(); assertEquals(ParentState.COMPLETE, oddjob.lastStateEvent().getState()); oddjob.destroy(); } public void testHeartBeat() throws Exception { Map<String, Object> env = new HashMap<String, Object>(); FailableSocketFactory ssf = new FailableSocketFactory(); env.put(RMIConnectorServer. RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf); createServer(env); JMXServiceJob client = new JMXServiceJob(); client.setConnection("localhost:13013"); client.setArooaSession(new StandardArooaSession()); client.setHeartbeat(100); StateSteps clientStates = new StateSteps(client); clientStates.startCheck(ServiceState.STARTABLE, ServiceState.STARTING, ServiceState.STARTED); client.run(); clientStates.checkNow(); clientStates.startCheck(ServiceState.STARTED, ServiceState.EXCEPTION); Thread.sleep(400); logger.info("Setting scoket to fail!"); ssf.setFail(true); clientStates.checkWait(); ssf.setFail(false); clientStates.startCheck(ServiceState.EXCEPTION, ServiceState.STARTABLE, ServiceState.STARTING, ServiceState.STARTED); logger.debug("Client Running Again."); client.hardReset(); client.run(); clientStates.checkNow(); client.stop(); } public static void main(String... args) throws Exception { JMXServiceJobTest test = new JMXServiceJobTest(); test.createServer(null); System.in.read(); test.tearDown(); } }