/*
* (c) Rob Gordon 2006
*/
package org.oddjob.jmx.handlers;
import javax.management.Notification;
import javax.management.NotificationListener;
import junit.framework.TestCase;
import org.oddjob.MockStateful;
import org.oddjob.Stateful;
import org.oddjob.jmx.RemoteOperation;
import org.oddjob.jmx.client.MockClientSideToolkit;
import org.oddjob.jmx.server.MockServerSideToolkit;
import org.oddjob.jmx.server.ServerInterfaceHandler;
import org.oddjob.state.JobState;
import org.oddjob.state.StateEvent;
import org.oddjob.state.StateListener;
public class StatefulHandlerFactoryTest extends TestCase {
private class OurStateful extends MockStateful {
StateListener l;
public void addStateListener(StateListener listener) {
assertNull(l);
l = listener;
l.jobStateChange(new StateEvent(this, JobState.READY));
}
public void removeStateListener(StateListener listener) {
assertNotNull(l);
l = null;
}
}
private class OurClientToolkit extends MockClientSideToolkit {
ServerInterfaceHandler server;
NotificationListener listener;
@SuppressWarnings("unchecked")
@Override
public <T> T invoke(RemoteOperation<T> remoteOperation, Object... args)
throws Throwable {
return (T) server.invoke(remoteOperation, args);
}
public void registerNotificationListener(String eventType, NotificationListener notificationListener) {
if (listener != null) {
throw new RuntimeException("Only one listener expected.");
}
assertEquals(StatefulHandlerFactory.STATE_CHANGE_NOTIF_TYPE, eventType);
this.listener = notificationListener;
}
@Override
public void removeNotificationListener(String eventType,
NotificationListener notificationListener) {
if (listener == null) {
throw new RuntimeException("Only one listener remove expected.");
}
assertEquals(StatefulHandlerFactory.STATE_CHANGE_NOTIF_TYPE, eventType);
assertEquals(this.listener, notificationListener);
this.listener = null;
}
}
private class OurServerSideToolkit extends MockServerSideToolkit {
long seq = 0;
NotificationListener listener;
public void runSynchronized(Runnable runnable) {
runnable.run();
}
@Override
public Notification createNotification(String type) {
return new Notification(type, this, seq++);
}
public void sendNotification(Notification notification) {
if (listener != null) {
listener.handleNotification(notification, null);
}
}
}
private class Result implements StateListener {
StateEvent event;
public void jobStateChange(StateEvent event) {
this.event = event;
}
}
public void testAddRemoveListener() throws Exception {
StatefulHandlerFactory test = new StatefulHandlerFactory();
assertEquals(1, test.getMBeanNotificationInfo().length);
OurStateful stateful = new OurStateful();
OurServerSideToolkit serverToolkit = new OurServerSideToolkit();
// create the handler
ServerInterfaceHandler serverHandler = test.createServerHandler(
stateful, serverToolkit);
// which should add a listener to our stateful
assertNotNull("listener added.", stateful.l);
OurClientToolkit clientToolkit = new OurClientToolkit();
Stateful local = new StatefulHandlerFactory.ClientStatefulHandlerFactory(
).createClientHandler(new MockStateful(), clientToolkit);
clientToolkit.server = serverHandler;
Result result = new Result();
local.addStateListener(result);
assertEquals("State ready", JobState.READY,
result.event.getState());
Result result2 = new Result();
local.addStateListener(result2);
assertEquals("State ready", JobState.READY,
result2.event.getState());
serverToolkit.listener = clientToolkit.listener;
stateful.l.jobStateChange(new StateEvent(stateful, JobState.COMPLETE));
// check the notification is sent
assertEquals("State complete", JobState.COMPLETE,
result.event.getState());
assertEquals("State complete", JobState.COMPLETE,
result2.event.getState());
local.removeStateListener(result);
assertNotNull(clientToolkit.listener);
local.removeStateListener(result2);
assertNull(clientToolkit.listener);
}
private class OurClientToolkit2 extends MockClientSideToolkit {
ServerInterfaceHandler server;
@SuppressWarnings("unchecked")
@Override
public <T> T invoke(RemoteOperation<T> remoteOperation, Object... args)
throws Throwable {
return (T) server.invoke(remoteOperation, args);
}
}
public void testLastStateEventCallsRemoteOpWhenNoListenerAdded() throws Exception {
StatefulHandlerFactory test = new StatefulHandlerFactory();
// assertEquals(1, test.getMBeanOperationInfo().length);
OurStateful stateful = new OurStateful();
OurServerSideToolkit serverToolkit = new OurServerSideToolkit();
// create the handler
ServerInterfaceHandler serverHandler = test.createServerHandler(
stateful, serverToolkit);
OurClientToolkit2 clientToolkit = new OurClientToolkit2();
Stateful local = new StatefulHandlerFactory.ClientStatefulHandlerFactory(
).createClientHandler(new MockStateful(), clientToolkit);
clientToolkit.server = serverHandler;
stateful.l.jobStateChange(new StateEvent(stateful, JobState.COMPLETE));
StateEvent lastStateEvent = local.lastStateEvent();
assertEquals(JobState.COMPLETE,
lastStateEvent.getState());
}
}