/* * (c) Rob Gordon 2005 */ package org.oddjob.framework; import java.beans.ExceptionListener; import java.util.Map; import junit.framework.TestCase; import org.apache.commons.beanutils.PropertyUtils; import org.apache.log4j.Logger; import org.oddjob.Describeable; import org.oddjob.Oddjob; import org.oddjob.OddjobLookup; import org.oddjob.Resetable; import org.oddjob.Stateful; import org.oddjob.Stoppable; import org.oddjob.arooa.ArooaDescriptor; import org.oddjob.arooa.ArooaSession; import org.oddjob.arooa.ArooaTools; import org.oddjob.arooa.MockArooaSession; import org.oddjob.arooa.life.ArooaContextAware; import org.oddjob.arooa.life.ArooaSessionAware; import org.oddjob.arooa.parsing.MockArooaContext; import org.oddjob.arooa.registry.ComponentPool; import org.oddjob.arooa.registry.MockComponentPool; import org.oddjob.arooa.runtime.MockRuntimeConfiguration; import org.oddjob.arooa.runtime.RuntimeConfiguration; import org.oddjob.arooa.runtime.RuntimeEvent; import org.oddjob.arooa.runtime.RuntimeListener; import org.oddjob.arooa.standard.StandardArooaDescriptor; import org.oddjob.arooa.standard.StandardTools; import org.oddjob.arooa.xml.XMLConfiguration; import org.oddjob.state.JobState; import org.oddjob.state.ParentState; import org.oddjob.state.ServiceState; import org.oddjob.tools.OddjobTestHelper; import org.oddjob.tools.StateSteps; public class ServiceWrapperTest extends TestCase { private static final Logger logger = Logger.getLogger(ServiceWrapperTest.class); @Override protected void setUp() throws Exception { super.setUp(); logger.info("------------------------- " + getName() + " ------------------------"); } private class OurContext extends MockArooaContext { OurSession session; RuntimeListener listener; @Override public ArooaSession getSession() { return session; } @Override public RuntimeConfiguration getRuntime() { return new MockRuntimeConfiguration() { @Override public void addRuntimeListener(RuntimeListener listener) { if (OurContext.this.listener != null) { throw new IllegalStateException(); } OurContext.this.listener = listener; } }; } } private class OurSession extends MockArooaSession { Object configured; Object saved; ArooaDescriptor descriptor = new StandardArooaDescriptor(); @Override public ArooaDescriptor getArooaDescriptor() { return descriptor; } @Override public ComponentPool getComponentPool() { return new MockComponentPool() { @Override public void configure(Object component) { configured = component; } @Override public void save(Object component) { saved = component; } }; } @Override public ArooaTools getTools() { return new StandardTools(); } } public static class MyService { boolean started; boolean stopped; public void start() { started = true; } public void stop() { stopped = true; } public boolean isStarted() { return started; } public boolean isStopped() { return stopped; } } public void testStartStop() throws Exception { MyService myService = new MyService(); OurSession session = new OurSession(); ServiceAdaptor service = new ServiceStrategies().serviceFor( myService, session); OurContext context = new OurContext(); context.session = session; Runnable wrapper = (Runnable) new ServiceProxyGenerator().generate( service, getClass().getClassLoader()); ((ArooaSessionAware) wrapper).setArooaSession(session); ((ArooaContextAware) wrapper).setArooaContext(context); wrapper.run(); assertEquals(wrapper, session.configured); assertEquals(ServiceState.STARTED, OddjobTestHelper.getJobState(wrapper)); assertEquals(new Boolean(true), PropertyUtils.getProperty(wrapper, "started")); ((Stoppable) wrapper).stop(); assertEquals(ServiceState.STOPPED, OddjobTestHelper.getJobState(wrapper)); assertEquals(new Boolean(true), PropertyUtils.getProperty(wrapper, "stopped")); ((Resetable) wrapper).hardReset(); // Service don't persist. assertNull(session.saved); assertEquals(ServiceState.STARTABLE, OddjobTestHelper.getJobState(wrapper)); } public void testInOddjob() throws Exception { String xml = "<oddjob>" + " <job>" + " <bean class='" + MyService.class.getName() + "' id='s' />" + " </job>" + "</oddjob>"; Oddjob oj = new Oddjob(); oj.setConfiguration(new XMLConfiguration("XML", xml)); oj.run(); Object test = new OddjobLookup(oj).lookup("s"); assertEquals(ServiceState.STARTED, OddjobTestHelper.getJobState(test)); assertEquals(new Boolean(true), PropertyUtils.getProperty(test, "started")); oj.stop(); assertEquals(ServiceState.STOPPED, OddjobTestHelper.getJobState(test)); assertEquals(new Boolean(true), PropertyUtils.getProperty(test, "stopped")); Map<String, String> description = ((Describeable) test).describe(); assertEquals("true", description.get("started")); assertEquals("true", description.get("stopped")); oj.destroy(); } public interface FruitService { String getFruit(); } public static class FruitJob implements Runnable { private FruitService fruitService; public void setFruitService(FruitService service) { this.fruitService = service; } @Override public void run() { fruitService.getFruit(); } } public static class MyFallibleService implements FruitService { ExceptionListener exceptionListener; @Start public void myStart() { } @Stop public void myStop() { } @AcceptExceptionListener public void handler(ExceptionListener exceptionListener) { this.exceptionListener = exceptionListener; } @Override public String getFruit() { exceptionListener.exceptionThrown(new Exception("No More Fruit!")); return "Apple"; } } public void testExceptionCallbackInOddjob() throws Exception { String xml = "<oddjob>" + " <job>" + " <sequential>" + " <jobs>" + " <bean id='fruit-service' class='" + MyFallibleService.class.getName() + "'/>" + " <bean id='fruit-job' class='" + FruitJob.class.getName() + "'>" + " <fruitService>" + " <value value='${fruit-service}'/>" + " </fruitService>" + " </bean>" + " </jobs>" + " </sequential>" + " </job>" + "</oddjob>"; Oddjob oddjob = new Oddjob(); oddjob.setConfiguration(new XMLConfiguration("XML", xml)); oddjob.load(); OddjobLookup lookup = new OddjobLookup(oddjob); Stateful service = lookup.lookup("fruit-service", Stateful.class); StateSteps serviceStates = new StateSteps(service); serviceStates.startCheck(ServiceState.STARTABLE, ServiceState.STARTING, ServiceState.STARTED, ServiceState.EXCEPTION); oddjob.run(); serviceStates.checkNow(); Stateful job = lookup.lookup("fruit-job", Stateful.class); assertEquals(JobState.COMPLETE, job.lastStateEvent().getState()); assertEquals(ParentState.EXCEPTION, oddjob.lastStateEvent().getState()); oddjob.destroy(); } public void testServiceDestroyedWhileRunningStates() throws Exception { MyService myService = new MyService(); OurSession session = new OurSession(); ServiceAdaptor service = new ServiceStrategies().serviceFor( myService, session); OurContext context = new OurContext(); context.session = session; Runnable wrapper = (Runnable) new ServiceProxyGenerator().generate( service, getClass().getClassLoader()); ((ArooaSessionAware) wrapper).setArooaSession(session); ((ArooaContextAware) wrapper).setArooaContext(context); wrapper.run(); assertEquals(wrapper, session.configured); assertEquals(ServiceState.STARTED, OddjobTestHelper.getJobState(wrapper)); StateSteps serviceStates = new StateSteps((Stateful) wrapper); serviceStates.startCheck(ServiceState.STARTED, ServiceState.STOPPED, ServiceState.DESTROYED); RuntimeEvent event = new RuntimeEvent(new MockRuntimeConfiguration()); context.listener.beforeDestroy(event); context.listener.afterDestroy(event); serviceStates.checkNow(); } }