package org.marketcetera.client;
import org.marketcetera.client.jms.OrderEnvelope;
import org.marketcetera.util.misc.ClassVersion;
import org.marketcetera.util.ws.tags.SessionId;
import org.marketcetera.module.*;
import org.marketcetera.trade.*;
import static org.marketcetera.trade.TypesTestBase.*;
import org.marketcetera.quickfix.FIXVersion;
import org.junit.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.apache.commons.lang.ObjectUtils;
import javax.management.JMX;
import java.util.Date;
import java.util.List;
import java.math.BigDecimal;
/* $License$ */
/**
* Base class for testing the client module.
*
* @author anshul@marketcetera.com
* @version $Id: ClientModuleTestBase.java 16154 2012-07-14 16:34:05Z colin $
* @since 1.0.0
*/
@ClassVersion("$Id: ClientModuleTestBase.java 16154 2012-07-14 16:34:05Z colin $") //$NON-NLS-1$
@Ignore
public class ClientModuleTestBase extends ModuleTestBase {
/**
* Verifies the provider and module infos.
*
* @throws Exception if there were unexpected errors
*/
@Test
public void info() throws Exception {
assertProviderInfo(mManager, ClientModuleFactory.PROVIDER_URN,
new String[0], new Class[0],
Messages.PROVIDER_DESCRIPTION.getText(),false, false);
assertModuleInfo(mManager, ClientModuleFactory.INSTANCE_URN,
ModuleState.STARTED, null, null, false,
true, true, true, false);
}
@Test
public void jmx() throws Exception {
//Verify descriptors
verifyBeanInfo(getMBeanServer().getMBeanInfo(
ClientModuleFactory.PROVIDER_URN.toObjectName()));
verifyBeanInfo(getMBeanServer().getMBeanInfo(
ClientModuleFactory.INSTANCE_URN.toObjectName()));
ClientModuleFactoryMXBean factory = JMX.newMXBeanProxy(getMBeanServer(),
ClientModuleFactory.PROVIDER_URN.toObjectName(),
ClientModuleFactoryMXBean.class);
assertEquals(getExpectedURL(), factory.getURL());
assertEquals(getExpectedUsername(), factory.getUsername());
ClientModuleMXBean instance = JMX.newMXBeanProxy(getMBeanServer(),
ClientModuleFactory.INSTANCE_URN.toObjectName(),
ClientModuleMXBean.class);
final Date lastTime = ClientManager.getInstance().getLastConnectTime();
assertEquals(lastTime,
instance.getLastConnectTime());
ClientTest.assertCPEquals(ClientManager.getInstance().getParameters(),
instance.getParameters());
//Sleep so that we definitely get a different connect time.
Thread.sleep(100);
instance.reconnect();
assertEquals(ClientManager.getInstance().getLastConnectTime(),
instance.getLastConnectTime());
assertTrue(instance.getLastConnectTime().compareTo(lastTime) > 0);
}
protected Object getExpectedUsername() {
return null;
}
protected Object getExpectedURL() {
return null;
}
@Test
public void invalidRequests() throws Exception {
new ExpectedFailure<IllegalRequestParameterValue>(
Messages.REQUEST_PARAMETER_SPECIFIED) {
protected void run() throws Exception {
mManager.createDataFlow(new DataRequest[]{new DataRequest(
ClientModuleFactory.INSTANCE_URN, "some string value")});
}
};
}
@Test
public void dataFlow() throws Exception {
//Create all kinds of orders to send
Order[] orders = new Order[]{
ClientTest.createOrderSingle(),
ClientTest.createOrderReplace(),
Factory.getInstance().createOrderCancel(ClientTest.createExecutionReport()),
Factory.getInstance().createOrder(
FIXVersion.FIX44.getMessageFactory().newLimitOrder(
"ord1", quickfix.field.Side.BUY,
new BigDecimal(4.3), new Equity("IBM"), new BigDecimal("93.23"),
quickfix.field.TimeInForce.AT_THE_OPENING,
"acc"), new BrokerID("broke"))
};
//Initialize mock server with reports to return
ReportBase[] reports = new ReportBase[] {
ClientTest.createExecutionReport(),
ClientTest.createExecutionReport(),
ClientTest.createCancelReject(),
ClientTest.createExecutionReport()};
sServer.getHandler().addToSend(reports[0]);
sServer.getHandler().addToSend(reports[1]);
sServer.getHandler().addToSend(reports[2]);
sServer.getHandler().addToSend(reports[3]);
//Add a sink listener to receive these reports
BlockingSinkDataListener sink = new BlockingSinkDataListener();
mManager.addSinkListener(sink);
//Initialize a module to send this data
ModuleURN senderURN = mManager.createModule(
OrderSenderModuleFactory.PROVIDER_URN, "sendOrders", orders);
assertEquals(0, sServer.getHandler().numReceived());
DataFlowID flowID = mManager.createDataFlow(new DataRequest[]{
new DataRequest(senderURN, null),
new DataRequest(ClientModuleFactory.INSTANCE_URN, null)
});
assertFlowInfo(mManager.getDataFlowInfo(flowID), flowID, 3, true,
false, null, null);
//Wait until sink has received all the data And verify each report.
for (ReportBase report : reports) {
if (report instanceof ExecutionReport) {
assertExecReportEquals(
((ExecutionReport) report),
(ExecutionReport) sink.getNextData());
} else if (report instanceof OrderCancelReject) {
assertCancelRejectEquals(
((OrderCancelReject) report),
(OrderCancelReject) sink.getNextData());
} else {
fail("Support for FIXResponse messages is pending");
}
}
//Sleep for a little while to let the sendMessage() call to the MQ
//Broker to return back. It's been observed that sometimes we receive
//execution reports even though the sendMessage() call has not returned.
//Cancelling the data flow at that point results in the sendMessage()
//call failing, as it's I/O gets interrupted.
Thread.sleep(1000);
//All the data has been transmitted, cancel the data flow
mManager.cancel(flowID);
//Verify data flow has ended
assertTrue(mManager.getDataFlows(true).isEmpty());
List<DataFlowInfo> history = mManager.getDataFlowHistory();
assertEquals(1, history.size());
DataFlowInfo info = history.get(0);
assertFlowInfo(info, flowID, 3, true,
true, null, null);
assertFlowStep(info.getFlowSteps()[0], senderURN, true, 4, 0,
null, false, 0, 0, null, null, null);
assertFlowStep(info.getFlowSteps()[1], ClientModuleFactory.INSTANCE_URN,
true, 4, 0, null, true, 4, 0, null,
ClientModuleFactory.INSTANCE_URN, null);
assertFlowStep(info.getFlowSteps()[2], SinkModuleFactory.INSTANCE_URN,
false, 0, 0, null, true, 4, 0, null,
SinkModuleFactory.INSTANCE_URN, null);
//Verify that the server got the orders
SessionId id = ((ClientImpl)(ClientManager.getInstance())).
getSessionId();
assertEquals(4, sServer.getHandler().numReceived());
OrderEnvelope e=(OrderEnvelope)sServer.getHandler().removeReceived();
assertEquals(id, e.getSessionId());
Order order = (Order) e.getOrder();
assert(order instanceof OrderSingle);
assertOrderSingleEquals((OrderSingle)orders[0], (OrderSingle) order);
e=(OrderEnvelope)sServer.getHandler().removeReceived();
assertEquals(id, e.getSessionId());
order = (Order) e.getOrder();
assert(order instanceof OrderReplace);
assertOrderReplaceEquals((OrderReplace)orders[1], (OrderReplace) order);
e=(OrderEnvelope)sServer.getHandler().removeReceived();
assertEquals(id, e.getSessionId());
order = (Order) e.getOrder();
assert(order instanceof OrderCancel);
assertOrderCancelEquals((OrderCancel)orders[2], (OrderCancel) order);
e=(OrderEnvelope)sServer.getHandler().removeReceived();
assertEquals(id, e.getSessionId());
order = (Order) e.getOrder();
assert(order instanceof FIXOrder);
assertOrderFIXEquals((FIXOrder)orders[3], (FIXOrder) order);
mManager.removeSinkListener(sink);
mManager.stop(senderURN);
mManager.deleteModule(senderURN);
}
@Test
public void dataFlowUnsupportedTypeError() throws Exception {
//test suggestion
OrderSingleSuggestion errorData = Factory.getInstance().
createOrderSingleSuggestion();
ModuleURN senderURN = mManager.createModule(
OrderSenderModuleFactory.PROVIDER_URN, "unsupported",
new Object[]{
errorData,
ClientTest.createOrderSingle()});
BlockingSinkDataListener sink = new BlockingSinkDataListener();
mManager.addSinkListener(sink);
DataFlowID flowID = mManager.createDataFlow(new DataRequest[]{
new DataRequest(senderURN, null),
new DataRequest(ClientModuleFactory.INSTANCE_URN, null)
});
assertFlowInfo(mManager.getDataFlowInfo(flowID), flowID, 3, true,
false, null, null);
//Wait for sink to receive the report in respose to the order.
Object data = sink.getNextData();
assertTrue(data.getClass().getName(), data instanceof ExecutionReport);
//Sleep for a little while to let the sendMessage() call to the MQ
//Broker to return back. It's been observed that sometimes we receive
//execution reports even though the sendMessage() call has not returned.
//Cancelling the data flow at that point results in the sendMessage()
//call failing, as it's I/O gets interrupted.
Thread.sleep(1000);
//We've received all data, cancel the data flow
mManager.cancel(flowID);
assertTrue(mManager.getDataFlows(true).isEmpty());
List<DataFlowInfo> history = mManager.getDataFlowHistory();
assertEquals(1, history.size());
DataFlowInfo info = history.get(0);
assertFlowInfo(info, flowID, 3, true,
true, null, null);
assertFlowStep(info.getFlowSteps()[0], senderURN, true, 2, 0,
null, false, 0, 0, null, null, null);
assertFlowStep(info.getFlowSteps()[1], ClientModuleFactory.INSTANCE_URN,
true, 1, 0, null, true, 2, 1,
Messages.UNSUPPORTED_DATA_TYPE.getText(flowID,
ObjectUtils.toString(errorData)),
ClientModuleFactory.INSTANCE_URN, null);
assertFlowStep(info.getFlowSteps()[2], SinkModuleFactory.INSTANCE_URN,
false, 0, 0, null, true, 1, 0, null,
SinkModuleFactory.INSTANCE_URN, null);
mManager.removeSinkListener(sink);
mManager.stop(senderURN);
mManager.deleteModule(senderURN);
}
@Test(timeout = 60000)
public void dataFlowNotInitializedError() throws Exception {
OrderSingle order = ClientTest.createOrderSingle();
ModuleURN senderURN = mManager.createModule(
OrderSenderModuleFactory.PROVIDER_URN, "clientNotInit",
new Object[]{Boolean.FALSE, order});
DataFlowID flowID = mManager.createDataFlow(new DataRequest[]{
new DataRequest(senderURN, null),
new DataRequest(ClientModuleFactory.INSTANCE_URN, null)
});
assertFlowInfo(mManager.getDataFlowInfo(flowID), flowID, 3, true,
false, null, null);
//The data flow should terminate as the client is not initialized
while(!mManager.getDataFlows(true).isEmpty()) {
Thread.sleep(1000);
}
List<DataFlowInfo> history = mManager.getDataFlowHistory();
assertEquals(1, history.size());
DataFlowInfo info = history.get(0);
assertFlowInfo(info, flowID, 3, true,
true, null, ClientModuleFactory.INSTANCE_URN);
assertFlowStep(info.getFlowSteps()[0], senderURN, true, 1, 0,
null, false, 0, 0, null, null, null);
assertFlowStep(info.getFlowSteps()[1], ClientModuleFactory.INSTANCE_URN,
true, 0, 0, null, true, 1, 1,
Messages.SEND_ORDER_FAIL_NO_CONNECT.getText(
ObjectUtils.toString(order)),
ClientModuleFactory.INSTANCE_URN, null);
assertFlowStep(info.getFlowSteps()[2], SinkModuleFactory.INSTANCE_URN,
false, 0, 0, null, true, 0, 0, null,
SinkModuleFactory.INSTANCE_URN, null);
mManager.stop(senderURN);
mManager.deleteModule(senderURN);
}
@BeforeClass
public static void serverSetup() throws Exception {
sServer = new MockServer();
}
@AfterClass
public static void serverCleanup() throws Exception {
if (sServer != null) {
sServer.close();
sServer = null;
}
}
@Before
public void clearMessageHandler() {
if (sServer != null) {
sServer.getHandler().clear();
}
}
@After
public void clientCleanup() throws Exception {
if (mManager != null) {
mManager.stop();
}
mManager = null;
if (ClientManager.isInitialized()) {
ClientManager.getInstance().close();
}
}
protected ModuleManager mManager;
private static MockServer sServer;
protected static final String IDPREFIX = "my";
}