Inserting MINA IoFilters
As of version 1.1.0 quickfixj allows custom IoFilters. MINA's javadoc for IoFilter
gives some examples of how this could be useful:
A filter which intercepts IoHandler events like Servlet filters. Filters can be used for these purposes:
- Event logging,
- Performance measurement,
- Authorization,
- Overload control,
- Message transformation (e.g. encryption and decryption, ...),
- and many more.
This page shows how to add filters by adding a simple filter to the order executor example.
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. 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:
It is as simple as that!
Whitelist Filter
Attached is a sample Whitelist filter - WhitelistFilter.java
. It allows an acceptor to accept specific sessions from specific IPs only.
The code changes required to use it are similar to the Blacklist filter, except that:
- The filter is configured from SessionSettings.
- You have to add the filter after FIXProtocolCodecFactory.FILTER_NAME as it relies on this to parse received messages.
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.
On startup the valid hosts will be logged:
New connections will be validated against the authorised IPs once the first message is received and closed if they are not valid:
Brad, do we need to create a factory for the builder? Is there any reason we can't just specify an IoFilterChainBuilder directly? I'm thinking the user would provide an IoFilterChain with just their filter modifications rather than inheriting from a default builder. The codec filter would be inserted automatically into the filter chain before calling the user's builder. The codec would have a well-defined name so it shouldn't limit the flexibility in how a filter chain can be configured. What do you think? I'd prefer to not have the factory unless it's necessary.