|
|
| WSO2 ESB | 1.7 |
| Apache Synapse | 1.2 |
Messaging and transport plays a major role in financial application development. Developing a sophisticated messaging and transport layer is always a challenge in the development of financial applications. Typically, a financial application environment is built with several applications integrated running both internally and externally. We call these components self-contained services. Different services may use different messaging formats with support for different transport media.
Due to these challenges, a common messaging and transport framework is impotent for the financial application developer. The WSO2 ESB comes as a good fit for such a framework, as it supports message routing, smart routing, transformation and persistence.
FIX is an open specification intended to streamline electronic communications in the financial industry. FIX was initiated in 1992, for equity trading between 'Fidelity Investment' and 'Salomon Brothers'. FIX is governed by fixprotocol.org. FIX messages are constructed with name value pairs that contains a standard header, a body and a trailer. FIX header contains a message type (tag 35) property, to differentiate between messages. FIX messages can be divided into two main categories; they are administration messages and application messages.
FIX communicates by creating sessions between FIX engines. FIX engines use a slimilar model to RM (Reliable Messaging), in that it enables message recovery through sequence numbers attached to messages.
Users benefit by using FIX due to many reasons. FIX specifications are open and free. Therefore, its usage dose not cost the user. FIX is a widely used protocol among every major stock exchange, investment banks, world's largest mutual funds and money managers. Thousands of small investment firms use FIX. FIX supports derivatives like equity, options, FOREX (Foreign Exchange) and fixed incomes, like bonds.
Sample FIX message: Buy 1000 DELL @ MKT
8=FIX.4.0#9=105#35=D#34=2#49=BANZAI#52=20080711-06:42:26#56=SYNAPSE#11=1215758546278#21=1#38=1000#40=1#54=1#55=DELL#59=0#10=253
AMQP is and open protocol for business messaging. AMQP was initiated in 1994 by JPMorgen & Chase Co,. iMatix had a parallel development on Java and C/C++. AMQP is popular in the financial community as a high performance and a reliable middleware solution. There are several AMQP implementations that include OpenAMQ, Apache QPid, RabbitMQ and ZeroMQ. The WSO2 ESB AMQP transport is built using Apache Qpid.

FIX implementations are done in the transport layer of the WSO2 ESB. Incoming FIX messages comes to a FIX acceptor connection that runs inside a Quickfix/J FIX engine. FIX transport transforms incoming FIX message to a XML infoset. XML infoset is the internal data representation of the original FIX message.
The WSO2 ESB FIX transport layer creates initiator session(s) to dispatch out going FIX messages to external FIX acceptor endpoints. Based on the address endpoint configuration in the ESB configuration, messages will route by handover to the relevant session.
If messages are expected to be dispatched or retrieved through other transport layers, an XML infoset will be handover or generated from the relevant transport implementation.
The WSO2 ESB has implemented the FIX transport layer using a leading open source FIX implementation known as QuickFIX. The Java implementation of QuickFIX is: Quickfix/J.
FIX messages generated from a FIX-IN source to a Web service hosted in a HTTP based Web application server. FIX-IN source will generate orders, submissions and order instructions such as order amend/cancel, replace and order cancellations. An Order Blotter, OMS (Order Management System), OR (Order Router), ETS (Electronic Trading System) can act as sample FIX-IN sources. Web services that accepts orders can be an OMS, Exchange, an OR or an ETS. Web services that accepts Orders/Submissions/Order instructions will send the executions, acknowledgments and corrections back to the WSO2 ESB via HTTP and the ESB will send these messages to the original FIX endpoint.
WSO2 ESB accepts FIX messages through FIX acceptor session(s), converts message(s) to XML infosets and creates relevant SOAP message(s) based on the ESB configuration.

In this example, FIX messages are generated from the default order blotter that comes with the Quickfix/J bundle "Banzai" and sends these messages to the placeOrder sample Web service hosted in the Axis2 Server. ESB configuration for a sample scenario will look like the following synapse.xml file. To configure the ESB to support FIX, please refer instructions listed in the WSO2 ESB 1.7 documentation.
synapse.xml
<definitions xmlns="http://ws.apache.org/ns/synapse"> <localEntry key="xslt-key-req" src="file:repository/conf/sample/resources/transform/fixtransform.xslt" /> <proxy name="FIXProxy" transports="fix"> <target> <endpoint> <address uri="http://localhost:9000/soap/SimpleStockQuoteService" /> </endpoint> <inSequence> <log level="full" /> <xslt key="xslt-key-req" /> <log level="full" /> </inSequence> <outSequence> <log level="full" /> </outSequence> </target> <parameter name="transport.fix.AcceptorConfigURL"> file:repository/conf/fix-synapse.cfg </parameter> <parameter name="transport.fix.AcceptorMessageStore"> file </parameter> <parameter name="transport.fix.InitiatorConfigURL"> file:repository/conf/synapse-sender.cfg </parameter> <parameter name="transport.fix.InitiatorMessageStore"> file </parameter> </proxy> </definitions>
fixtransform.xslt
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/02/xpath-functions"> <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" /> <xsl:template match="/"> <m0:placeOrder xmlns:m0="http://services.samples/xsd"> <m0:order> <m0:price><xsl:value-of select="//message/body/field[@id='44']"/></m0:price> <m0:quantity><xsl:value-of select="//message/body/field[@id='38']"/></m0:quantity> <m0:symbol><xsl:value-of select="//message/body/field[@id='55']"/></m0:symbol> </m0:order> </m0:placeOrder> </xsl:template> </xsl:stylesheet>
FIX messages generated from a FIX-IN source send to order acceptance source that communicates via AMQP. The FIX in source can be a Blotter, OMS or a ETS and service can be again a OMS, OR or an ETS.
The WSO2 ESB accepts FIX messages through FIX acceptor session(s), converts messages to internal XML infoset, loads message payloads to an AMQP message and dispatch to a given Queue/Topic that has already initialized in a AMQP broker.

In this example, a FIX message generated from "Banzai" is sent to an AMQP message consumer through the WSO2 ESB. The consumer application generates executions (full-fill received order) and the WSO2 ESB sends the execution/fill back to the blotter.
synapse.xml
<definitions xmlns="http://ws.apache.org/ns/synapse"> <localEntry key="xslt-rem-ns" src="file:repository/conf/sample/resources/transform/fix-rm-ns.xslt" /> <proxy name="FIXProxy" transports="fix"> <target> <endpoint> <address uri="jms:/QpidStockQuoteService?transport.jms.ConnectionFactoryJNDIName=qpidConnectionfactory&java.naming.factory.initial=org.apache.qpid.jndi.PropertiesFileInitialContextFactory&java.naming.provider.url=/home/asankaa/workspace/synapse-1.2-test/repository/conf/server.properties&transport.jms.ReplyDestination=replyQueue"/> </endpoint> <inSequence> <log level="full" /> </inSequence> <outSequence> <property name="transport.fix.ServiceName" value="FIXProxy" scope="axis2-client" /> <log level="full" /> <xslt key="xslt-rem-ns" /> <send /> <log level="full" /> </outSequence> </target> <parameter name="transport.fix.AcceptorConfigURL"> file:repository/conf/fix-synapse.cfg </parameter> <parameter name="transport.fix.AcceptorMessageStore"> file </parameter> <parameter name="transport.fix.InitiatorConfigURL"> file:repository/conf/synapse-sender.cfg </parameter> <parameter name="transport.fix.InitiatorMessageStore"> file </parameter> </proxy> </definitions>
server.properties
#initial context factory #java.naming.factory.initial =org.apache.qpid.jndi.PropertiesFileInitialContextFactory # register some connection factories # connectionfactory.[jndiname] = [ConnectionURL] connectionfactory.qpidConnectionfactory=amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672' # Register an AMQP destination in JNDI # destination.[jndiName] = [BindingURL] destination.directQueue=direct://amq.direct//QpidStockQuoteService
fix-rm-ns.xslt
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no" />
<xsl:template match="/|comment()|processing-instruction()">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
In a trading environment there can be applications accepting different FIX versions. There can be FIX-IN sources send messages belonging to different FIX versions and there can be FIX-OUT sources that needs to send messages out in different FIX versions.
The WSO2 ESB accepts FIX input via the FIX transport layer and dispatches to another FIX acceptor that accept messages in a different FIX version. e.g. FIX 4.2 to FIX.4.4. The WSO2 ESB converts incoming message using a configured transformation mediator and uses the outgoing FIX session to create the FIX message header. XSLT mediator, script mediator or a POJO can be used to transform the message. An alternate approach to implementing the bridge, is to use compatible FIX specs/data-dictionary in the endpoint FIX engines. As an example, execution message (35=8) of FIX4.0 does not contain tag 150(ExecType) and 151(LeavesQty). Tag 150 and 151 are mandetory fields of FIX4.1, to switch messages from version 4.0 to 4.1 and get the executions back, user can add the tag 150 and 151 to the FIX4.0 specification as optional fields.

In this example messages comming from "Banzai" with FIX4.0 will be send to the "Executor" that act as the order acceptor that accept messages in FIX4.1 format. Banzai is using a custom FIX sepcification by making FIX engine to accept 4.1 messages.
synapse.xml
<definitions xmlns="http://ws.apache.org/ns/synapse">
<proxy name="OrderProcesserProxy41" transports="fix">
<target>
<endpoint>
<address uri="fix://localhost:19877?BeginString=FIX.4.1&SenderCompID=SYNAPSE&TargetCompID=EXEC"/>
</endpoint>
<inSequence><log level="full"/></inSequence>
<outSequence><log level="full"/><send/></outSequence>
</target>
<parameter name="transport.fix.AcceptorConfigURL">file:repository/conf/fix-synapse-m40.cfg</parameter>
<parameter name="transport.fix.AcceptorMessageStore">file</parameter>
<parameter name="transport.fix.InitiatorConfigURL">file:repository/conf/synapse-sender-m.cfg</parameter>
<parameter name="transport.fix.InitiatorMessageStore">file</parameter>
</proxy>
</definitions>
fix-synapse-m40.cfg
[default] FileStorePath=E:\etc\data\store\synapse FileLogPath=E:\etc\data\log\synapse ConnectionType=acceptor StartTime=00:00:00 EndTime=00:00:00 HeartBtInt=30 ValidOrderTypes=1,2,F SenderCompID=SYNAPSE TargetCompID=BANZAI UseDataDictionary=Y DefaultMarketPrice=12.30 SendResetSeqNumFlag=Y [session] BeginString=FIX.4.0 SocketAcceptPort=9876 DataDictionary=/home/asankaa/etc/spec/FIX40-synapse.xml
synapse-sender-m.cfg
[default] FileStorePath=E:\etc\data\store\synapse-sender FileLogPath=E:\etc\data\log\synapse-sender StartTime=00:00:00 EndTime=00:00:00 HeartBtInt=30 ReconnectInterval=5 SendResetSeqNumFlag=Y
On a trading platform, incoming FIX messages need to route to deferent destinations based on conditions. As an example, consider multiple OMSs running services for a set of symbols and listening to a MDD (Market Data Distribution) Server that publish market data only for defined symbols. In such a situation, FIX messages need to be routed based on symbols (tag 55) and sent to relevant OMS instances. Another example will be route orders based on the side (buy/sell) and all the buy orders will ve accepted by one OMS and sell orders by another.
Users can implement a simple EDA (Event Driven Architecture) that the WSO2 ESB acts on, as the event processing engine. User can send requests such as fill order, partially fill orders, rejected, cancel and new orders to different event queues listed as endpoints.
User can use any available tag and perform CBR by implementing a simple rule.
The WSO2 ESB takes incoming FIX messages through the FIX transport layer and route messages based on user configuration. Based on conditions defined by a switch/case statement and a regex, the value to be compared will be fetched using a simple XPath statement (that navigates through the XML infoset to find the value).

Example describes routing messages by symbol (tag 55), to define endpoints. If 2 switch messages come tagged with 'IBM' and 'MSFT' to two define endpoints, the sample keeps the default switch blank for the system to ignore messages with other symbols. Alternatively, we could define an endpoint in the default block in order to route the rest of messages to another endpoint.
synapse.xml
<definitions xmlns="http://ws.apache.org/ns/synapse"> <sequence name="proxy_1"> <in> <switch source="//message/body/field[@id='55']"> <case regex="IBM"> <send> <endpoint> <address uri="fix://localhost:19876?BeginString=FIX.4.0&SenderCompID=SYNAPSE&TargetCompID=EXEC" /> </endpoint> </send> </case> <case regex="MSFT"> <send> <endpoint> <address uri="fix://localhost:19877?BeginString=FIX.4.1&SenderCompID=SYNAPSE&TargetCompID=EXEC" /> </endpoint> </send> </case> <default></default> </switch> </in> <out> <send /> </out> </sequence> <proxy name="FIXProxy" transports="fix"> <target inSequence="proxy_1" /> <parameter name="transport.fix.AcceptorConfigURL"> file:repository/conf/fix-synapse.cfg </parameter> <parameter name="transport.fix.AcceptorMessageStore"> file </parameter> <parameter name="transport.fix.InitiatorConfigURL"> file:repository/conf/synapse-sender.cfg </parameter> <parameter name="transport.fix.InitiatorMessageStore"> file </parameter> </proxy> </definitions>
Data Services, is a mechanism to expose data stored in persistence storage as Web service(s). In a trading environment, orders/submissions/order instructions may be stored in persistence storage for various reasons and needs conversion to FIX format in order to post them to other system. A typical scenario is where GTC (good till cancel) and GTD (good till date) orders are stored in a persistence storage after the end-of-the-day process, if the orders are still in 'active' state. These stored orders need to be posedt to the market on the following day during the pre-trading session, where stored data needs to be converted to the FIX format before they are sent to their relevant endpoints. Data services will provide order/submission/order instructions information using a get<DS> method and are able to update acknowlegements/executions(fills)/corrections coming from the other end using a set<DS> method.
The WSO2 ESB use a trigger-mechanism that is self initiated to define intervals to call data services hosted externally to a Web application server. Data coming through a data service will be converted to FIX message/s and dispatched to the relevant FIX endpoint. User can split data sets into several 'Order Single' (35=D) messages using the aggregate pattern in the WSO2 ESB, or, alternatively send as a batch order 'Order List' (35=E) to the FIX destination.
Data services can be hosted in any Web application server that supports DS. The WSO2 Web Services Application Server (WSAS) offers full support for data services. Any RDBMS (Relational Database Management System) with JDBC (Java Database Connectivity), CSV (Comma Separated Values) files or Microsoft Excel files can act as persistence storage in such scenarios.

In this example, a DS call, getEquity, is made to WSAS that use an embedded 'Derby' database as persistance storage. Derby database contains an Order table. The WSO2 ESB calls the DS in given time intervals.The result is then handed over to the FIX transport layer. FIX transport layer converts the XML message payload coming from DS to FIX, which then dispatches it to the target FIX endpoint.
synapse.xml
<definitions xmlns="http://ws.apache.org/ns/synapse"> <!-- XSLT file to transform the message input from the DS --> <localEntry key="xslt-fix" src="file:repository/conf/sample/resources/transform/fixtransform-ds.xslt" /> <sequence name="FIXInsequence"> <log level="full" /> <xslt key="xslt-fix" /> <log level="full" /> <send> <endpoint key="FIXTRNS" /> </send> </sequence> <sequence name="errorHandler"> <log level="full" separator="," /> </sequence> <!-- Proxy to call the data service running on external WS --> <proxy name="FIXDataServiceProxy" startOnLoad="true"> <target outSequence="FIXInsequence" faultSequence="errorHandler"> <endpoint> <address uri="http://localhost:9762/services/DataServiceSample1" /> </endpoint> </target> </proxy> <task name="fetchDataFromTxnDB" class="org.apache.synapse.startup.tasks.MessageInjector"> <trigger cron="0 0/1 * * * ?" /> <property name="message"> <p:getEquities xmlns:p="http://ws.wso2.org/dataservice" /> </property> <property name="soapAction" value="urn:getEquities" /> <property name="to" value="http://localhost:8280/soap/FIXDataServiceProxy" /> </task> <in> <send /> </in> <!-- Proxy to Send the FIX message out --> <proxy name="FIXTransportProxy"> <target> <endpoint> <address uri="fix://localhost:19876?BeginString=FIX.4.0&SenderCompID=SYNAPSE&TargetCompID=EXEC" /> </endpoint> <inSequence> <property name="transport.fix.ServiceName" value="FIXTransportProxy" scope="axis2-client" /> <log level="full" /> </inSequence> <outSequence> <log level="full" /> </outSequence> </target> <parameter name="transport.fix.InitiatorConfigURL"> file:repository/conf/synapse-sender.cfg </parameter> <parameter name="transport.fix.InitiatorMessageStore"> /home/asankaa/var/data/store </parameter> </proxy> <endpoint name="FIXTRNS"> <address uri="http://localhost:8280/soap/FIXTransportProxy"/> </endpoint> </definitions>

The WSO2 ESB accepts orders, submissions and order instructions on protocols such as FIX, AMQP, HTTP and dispatches them to endpoints that accept messages using FIX, AMQP, HTTP protocols. The WSO2 ESB is able to route, smart route, transform and persist incoming messages based on user configurations. Users can use the Web-based GUI to configure scenarios, where the user-friendly graphical interface provides rich functionality to configure, manage and monitor activities. Users can handover message transformation and transport to the WSO2 ESB and concentrate on the business logic of such applications.
The WSO2 ESB 1.7 provides FIX and AMQP transport support - the two widely used protocols in the financial community. Performance is a key element in financial applications. ESB performance results prove that the WSO2 ESB is far ahead of others out there in the market!
[1] WSO2 ESB Samples Guide - http://wso2.org/project/esb/java/1.7/docs/ESB_Samples.html
[2] WSO2 ESB Samples Setup Guide - http://wso2.org/project/esb/java/1.7/docs/ESB_Samples_Setup.html
[3] WSO2 ESB Configuration Language Guide - http://wso2.org/project/esb/java/1.7/docs/ESB_Configuration_Language.html
Asanka Abeysinghe is a Software Architect at WSO2. asankaa at wso2 dot com
that site
Car Service Madison
Extremely useful information
Attorney
cell phone lookup
CV Joint Replacement Cost
breast enlargement
Happy
WSO2 is really a great tool.