package com.activequant.utils.recorder; import java.io.IOException; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.log4j.Logger; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.activequant.component.ComponentBase; import com.activequant.domainmodel.ETransportType; import com.activequant.domainmodel.exceptions.DaoException; import com.activequant.domainmodel.exceptions.TransportException; import com.activequant.domainmodel.trade.event.OrderEvent; import com.activequant.interfaces.dao.IDaoFactory; import com.activequant.interfaces.dao.IOrderEventDao; import com.activequant.interfaces.transport.ITransportFactory; import com.activequant.interfaces.utils.IEventListener; import com.activequant.messages.AQMessages.BaseMessage; import com.activequant.messages.Marshaller; import com.google.protobuf.InvalidProtocolBufferException; /** * A recorder that records order events that come in over the trading bus. In * the near future, this might record more than just order events. * * @author GhostRider * */ public class TradingBusRecorder extends ComponentBase { private final ITransportFactory transFac; private final Logger log = Logger.getLogger(TradingBusRecorder.class); private final Timer t = new Timer(true); private final long collectionPhase = 5000l; private final ConcurrentLinkedQueue<OrderEvent> collectionList = new ConcurrentLinkedQueue<OrderEvent>(); private final IOrderEventDao orderEventDao; class InternalTimerTask extends TimerTask { int counter; @Override public void run() { OrderEvent o = collectionList.poll(); counter = 0; while (o != null) { try { orderEventDao.create(o); } catch (DaoException e) { log.error(o.toString() + " was not stored: ", e); } // counter++; o = collectionList.poll(); } log.info("Collected " + counter + " events. "); t.schedule(new InternalTimerTask(), (collectionPhase - System.currentTimeMillis() % collectionPhase)); } } public TradingBusRecorder(IDaoFactory daoF, ITransportFactory transFac) throws Exception { super("TradingBusRecorder", transFac); this.transFac = transFac; this.orderEventDao = daoF.orderEventDao(); log.info("Transport initialized."); subscribe(); t.schedule( new InternalTimerTask(), (collectionPhase - System.currentTimeMillis() % collectionPhase)); } private Marshaller marshaller = new Marshaller(); private void subscribe() throws IOException, TransportException { log.info("Subscribing to all order events on the TRAD_DATA bus."); transFac.getReceiver(ETransportType.TRAD_DATA, "*").getRawEvent() .addEventListener(new IEventListener<byte[]>() { @Override public void eventFired(byte[] event) { BaseMessage bm; try { bm = marshaller.demarshall(event); OrderEvent o = marshaller.demarshallOrderEvent(bm); if (o != null) collectionList.add(o); } catch (InvalidProtocolBufferException e) { e.printStackTrace(); } } }); } /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { args[0] }); IDaoFactory idf = (IDaoFactory) appContext.getBean(IDaoFactory.class); ITransportFactory transFac = appContext .getBean(ITransportFactory.class); new TradingBusRecorder(idf, transFac); } @Override public String getDescription() { return "Records all order events to persistence layer. Writes in five second intervals. No supported commands. "; } }