FIXEdge Transport Adaptors Developer Guide

Overview

Transport Adaptors (TA) is a library that can be loaded by FIX Edge under Transport Layer. Technically it is a DLL that is loaded by server in the run time. TA handles sessions, which are identified by the ClientID in contrast to FIX Session, which are identified by pair SenderCompID and TargetCompID.

There are Transport Adaptors (TAs) and Bridge Adaptors (BAs). The difference between them is only that TAs use raw interface i.e. FIX message is serialized to byte array to pass through the adaptors’ border, whereas bridges have object interface. This also means that bridges require knowledge of FIX Message object, whereas transports adaptors can overlook the type and handle message as a sequence of bytes. In order to have an ability of working with FIX Message object stitic libraries from libs folder of SDK should be linked.

Interface

Transport Adaptor

Each TA should implement the following interface:

namespace FixServer
{
/// TransportLayerImpl namespace.
namespace TransportLayerImpl
{  
class TransportAdaptorObserver : public FixServer::TransportLayerImpl::AdaptorObserver
		{    
		public:        
			/// It called when a new message is received from the client.        
			/// @param msg Message has been received.
			/// @param id The identifier of client sent the message
			/// @param msgSize The size of message.
      /// @return true if message was successfully routed to some client or session.
      /// If no suitable destination was nor found it returns false.
      /// @throw Utils::Exception if Client was not logged in or logged in through another TA
			virtual bool onMessageFromClient(const char* msg, size_t msgSize, const char* clientId) = 0;

			/// This call-back method is called when a message have to be rejected. 
			/// @param rejectMsg Message has been rejected.
			/// @param id The identifier of client sent the message
			/// @param msgSize The size of message.
			/// @return true if reject message was successfully routed to some client or session.
			/// If no suitable destination was nor found it returns false.
		      	/// @throw Utils::Exception if Client was not logged in or logged in through another TA
			virtual bool onMessageReject(const char* rejectMsg, size_t msgSize, const char* clientId) = 0;
			/// This call-back method is called when a session-level Reject message (MsgType = 3) is received.
			/// @param rejectMsg Session level reject message.
			/// @param id The identifier of client sent the message
			/// @param msgSize The size of message.
			/// @return true if reject message was successfully routed to some client or session.
			/// If no suitable destination was nor found it returns false.
		      	/// @throw Utils::Exception if Client was not logged in or logged in through another TA
			virtual bool onSessionLevelReject(const char* rejectMsg, size_t msgSize, const char* clientId) = 0;
		};
		  
		//////////////////////////////////////////////////////////////////////////
		/// Generic Transport Adaptor.    
		class TransportAdaptor : public FixServer::TransportLayerImpl::Adaptor
		{    
		public:        
			/// It performs Adaptor initialization.
			///virtual void init(const Utils::Properties& configuration ) = 0;
	    
			/// Sends the given message to the client.    
			/// @param msg The opaque byte sequence.  
			/// @param msgSize The size of message.  
			/// @param id The identifier of destination client
			/// @throw FixServer::TransportLayer::TransportException if send fails
			virtual void sendToClient(const char* msg, size_t msgSize, const char* id) = 0;
			/// Subscribes AdaptorObserver to receiving Adaptor's events.
			/// @param observer The observer for Adaptor
			virtual void attach(TransportAdaptorObserver* observer) = 0;        
		protected:
			TransportAdaptor() {
#ifndef __BCPLUSPLUS__
				type = Adaptor::TRANSPORT_ADAPTOR;
#else
				type = TRANSPORT_ADAPTOR;
#endif
			}
		};
	};
}

Bridge Adaptor

Each BA should implement the following interface:

namespace FixServer
{
	/// TransportLayerImpl namespace.
	namespace TransportLayerImpl
	{  
		/** Interface for message finder **/
		struct MsgFinder
		{
			/** Finds message by Session ID and ClOrdID */
			virtual Engine::FIXMessage* find( const std::string& sessionId, const std::string& clOrdID ) = 0; 
		};

    /** Interface for History Message finder **/
    struct HistoryFinder
    {
      /// Finds record in history by key.
      virtual TransportLayer::HistoryHandle findInHistory(const std::string& historyName,
        const std::string& sessionId, const std::string& clOrdID) = 0; 
      
      /// Gets given tag's value.
      virtual bool get(TransportLayer::HistoryHandle  handle, int tag, Engine::FIXFieldValue* val) = 0;
        
      /// Closes find session.
      virtual void closeHandle(TransportLayer::HistoryHandle handle) = 0;
    };

	struct FixAntennaProvider
	{
		/// Provides adaptor with access to FixEdge's FixEngine instance
		/// note: This entry point is not expected to call any non-virtual functions across library boards (from adaptors dlls)
		/// For most purpose proxy() method is recommended
		virtual Engine::FixEngine* engine() = 0;
        /// Creates instance of the CQG FIX/FAST Market Data adapter
        /// It is user's responsibility to call Cqg::MDApplication::release method.
		virtual Cqg::MDApplication* createCqgMDApplication(Cqg::MDApplicationListener* listener, const Cqg::MDApplicationParams& params) = 0;
        /// Returns the pointer to the instance of StorageMgr.
		virtual Engine::StorageMgr* storageMgr( const Engine::MessageStorageType type ) = 0;
	};
		//////////////////////////////////////////////////////////////////////////
		/// Observer of Transport Adaptor.    
		class BridgeAdaptorObserver: 
      public FixServer::TransportLayerImpl::AdaptorObserver, 
      public FixServer::TransportLayerImpl::MsgFinder,
      public FixServer::TransportLayerImpl::HistoryFinder, 
	  public FixServer::TransportLayerImpl::FixAntennaProvider
		{    
		public:        
			/// It called when a new message is received from the client.        
			/// @param msg Message has been received.
			/// note: msg should be deleted by counterparty (BL, CC or other)
			/// @param id The identifier of client sent the message
      /// @return true if message was successfully routed to some client or session.
      /// If no suitable destination was nor found it returns false.
			/// @throw Utils::Exception if Client was not logged in or logged in through another TA
			virtual bool onMessageFromClient(Engine::FIXMessage* msg, 
        const FixServer::TransportLayer::ClientID& cid) = 0;
		};
		  
		//////////////////////////////////////////////////////////////////////////
		/// Bridge Adaptor.    
		class BridgeAdaptor : public FixServer::TransportLayerImpl::Adaptor
		{    
		public:        
		    
			/// Sends the given message to the client.    
			/// @param msg The message to client.  
			/// @param cid The identifier of destination client
			/// @throw FixServer::TransportLayer::TransportException if send fails
			virtual void sendToClient(const Engine::FIXMessage* msg, const FixServer::TransportLayer::ClientID& cid) = 0;
			/// Subscribes AdaptorObserver to receiving Adaptor's events.
			/// @param observer The observer for Adaptor
			virtual void attach(BridgeAdaptorObserver* observer) = 0;        
		protected:
			BridgeAdaptor() {
				type = Adaptor::BRIDGE_ADAPTOR;
			};
		};
	};
}

Receiving message

Incoming message is getting in sendToClient method

 

Sending Message

Transport adaptor can send  FIX message  using onMessagFromClient method of Adaptor's observer

 

Deployment and configuration

Libraries are placed in FIX Edge ‘bin’ directory and added to the properties file. To make transport layer load TA the following lines are to added:

# Comma separated list of identifiers of Transport Adapters should be loaded.
TransportLayer.TransportAdapters = TransportLayer.Adapor1_Name TransportLayer.Adaptor2_NAME
# Description of Transport Adaptor
TransportLayer. Adapor1_Name.Description = Test Adaptor
# Relative path and file name of DLL
TransportLayer. Adapor1_Name.DllName = bin/TestAdaptorAddin_71.dll

 

All properties related to this adaptor should be started with prefix ‘TransportLayer. Adapor1_Name’. All adaptor’s properties are passed to the adaptor as is on initialization.

Adaptors manage sessions and inform the transport layer about handled sessions sending them ClientIDs. Transport Layer in its turn sends this information to the business layer, which makes routing between sessions possible. ClientsIDs can be used in routing rules the same way as FIX Session IDs. For example:

<Rule>                    
	<Source>              
		<FixSession SenderCompID=".*" TargetCompID=".*"/>
	</Source>
	<Condition>
		<MatchField Field="35" Value="(D|F|G)"/>
	</Condition>
	<Action>
		<Send>
			<Client Name="XASE"/>
		</Send>
	</Action>             
</Rule>

 

For more info on configuring business layer see Configuring Business Layer.

Sample

Sample TA code is available at src_TA folder of SDK package