QuickFIX/J User Manual

Using MINA Filters

Adding a custom MINA IO Filter allows you to inspect and manipulate:

MINA's javadoc for IoFilter gives some examples of how this could be useful:

To add a filter, you need to insert it into the filter chain by supplying an IoFilterChainBuilder to the connector or acceptor with setIoFilterChainBuilder().

final BlacklistFilter blacklistFilter = new BlacklistFilter();  
...
 /*
  * setIoFilterChainBuilder is defined on the SessionConnector abstract class 
  */
((SessionConnector) acceptor).setIoFilterChainBuilder(new IoFilterChainBuilder() {

    public void buildFilterChain(IoFilterChain chain) {
        chain.addBefore(FIXProtocolCodecFactory.FILTER_NAME, "BlacklistFilter", blacklistFilter);
    }});

Note the reference to FIXProtocolCodecFactory.FILTER_NAME. QuickFIX/J uses a ProtocolCodecFilter to transform between streamed byte data on the wire and quickfix.Message objects, as shown below.

You should add your filter before this one to have it act on the byte stream, or after it to act on quickfix.Message data.

Following are some examples showing how to add filters to the example order executor application


Blacklist Filter

MINA comes with a Blacklist filter which closes incoming connections from blacklisted addresses. Lets add this filter to the order executor and make it block connections from localhost. We will add it before the protocol codec filter.

To do this, change:

acceptor = new SocketAcceptor (application, messageStoreFactory, settings, logFactory, messageFactory);
acceptor.start();

to this (plus the appropriate imports):

acceptor = new SocketAcceptor (application, messageStoreFactory, settings, logFactory, messageFactory);

/* create the filter and add an address to the blacklist */
final BlacklistFilter blacklistFilter = new BlacklistFilter();

blacklistFilter.block(InetAddress.getByName("localhost"));

/* add it to the acceptor */
((SessionConnector) acceptor).setIoFilterChainBuilder(new IoFilterChainBuilder() {

    public void buildFilterChain(IoFilterChain chain) {
        chain.addBefore(FIXProtocolCodecFactory.FILTER_NAME, "BlacklistFilter", blacklistFilter);
    }});
acceptor.start();

Now when you start the executor and banzai apps you'll see this:

Executor Log
<20060913-10:54:22, FIX.4.2:EXEC->BANZAI, event> (Session FIX.4.2:EXEC->BANZAI schedule is daily, 00:00:00 UTC - 00:00:00 UTC)
<20060913-10:54:22, FIX.4.2:EXEC->BANZAI, event> (Valid order types: [F, 2])
<20060913-10:54:22, FIX.4.2:EXEC->BANZAI, event> (Created session: FIX.4.2:EXEC->BANZAI)
13/09/2006 20:54:22 quickfix.mina.acceptor.AbstractSocketAcceptor startAcceptingConnections
INFO: Listening for connections at 0.0.0.0/0.0.0.0:9876
press <enter> to quit
13/09/2006 20:54:26 quickfix.mina.acceptor.AcceptorIoHandler sessionCreated
INFO: MINA session created: /127.0.0.1:4538
13/09/2006 20:54:26 org.apache.mina.util.SessionLog info
INFO: [/127.0.0.1:4538] Remote address in the blacklist; closing.
13/09/2006 20:54:26 org.apache.mina.util.SessionLog info
INFO: [/127.0.0.1:4538] Remote address in the blacklist; closing.

Banzai Log

<20060913-10:54:26, FIX.4.2:BANZAI->EXEC, event> (Session FIX.4.2:BANZAI->EXEC schedule is daily, 00:00:00 UTC - 00:00:00 UTC)
<20060913-10:54:26, FIX.4.2:BANZAI->EXEC, event> (Created session: FIX.4.2:BANZAI->EXEC)
<20060913-10:54:26, FIX.4.2:BANZAI->EXEC, outgoing> (8=FIX.4.29=6535=A34=449=BANZAI52=20060913-10:54:26.75056=EXEC98=0108=3010=223)
<20060913-10:54:26, FIX.4.2:BANZAI->EXEC, event> (Initiated logon request)
<20060913-10:54:26, FIX.4.2:BANZAI->EXEC, event> (Disconnecting)
13/09/2006 20:54:26 quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created: /127.0.0.1:4538

Whitelist Filter

A whitelist filter is available at http://www.quickfixj.org/confluence/download/attachments/530/WhitelistFilter.java. The code changes required to use it are similar to the Blacklist filter, except that:

acceptor = new SocketAcceptor (application, messageStoreFactory, settings, logFactory, messageFactory);

final WhitelistFilter whitelistFilter = new WhitelistFilter(settings);
((SessionConnector) acceptor).setIoFilterChainBuilder(new IoFilterChainBuilder() {
    public void buildFilterChain(IoFilterChain chain) {
        chain.addAfter(FIXProtocolCodecFactory.FILTER_NAME, "WhitelistFilter", whitelistFilter);
    }});
    
acceptor.start();

Specify valid IP addresses with the WhitelistHost setting, at either the default or session levels as required.

[default]
...
WhitelistHost=www.quickfixj.org

[session]
SenderCompID=EXEC
TargetCompID=BANZAI

[session]
SenderCompID=EXEC
TargetCompID=SONOFBANZAI
WhitelistHost1=127.0.0.1
WhitelistHost2=192.168.0.1, 192.168.0.2

[session]
SenderCompID=EXEC
TargetCompID=FREEFORALL
WhitelistHost=

On startup the valid hosts will be logged:

INFO: Authorised IPs for FIX.4.2:EXEC->FREEFORALL: [Any]
INFO: Authorised IPs for FIX.4.2:EXEC->BANZAI: [www.quickfixj.org/213.246.61.101]
INFO: Authorised IPs for FIX.4.2:EXEC->SONOFBANZAI: [/192.168.0.1, /127.0.0.1, www.quickfixj.org/213.246.61.101, /192.168.0.2]

New connections will be validated against the authorised IPs once the first message is received and closed if they are not valid:

WARNING: [/127.0.0.1:2633] Closing FIX.4.2:EXEC->BANZAI connection from unauthorised address.