Samples :: SSL

Ssl Buy Side

Description

This is a FIX Initiator that connects to the pre-defined host and port.

The connection is secured using SSL.

When the session is established, the “SingleOrder - New”(MsgType=‘D’) FIX message is sent to the counterparty.

This sample can be run together with the “SellSide SSL” sample. The “SellSide SSL” must be started first.

Directory Contents

Item Description
conf/sample/buyside.cer SSL certificate
conf/sample/buyside.keystore.bin SSL key store
conf/sample/buyside.truststore.bin SSL trust store

Usage

  • Run the sample:
    • win: 2-SslBuySide.bat
    • linux: 2-SslBuySide.sh
  • Clean everything:
    • win: clean.bat
    • linux: clean.sh

Source Code

import biz.onixs.fix.dictionary.Version;
import biz.onixs.fix.engine.Engine;
import biz.onixs.fix.engine.Session;
import biz.onixs.fix.engine.SessionState;
import biz.onixs.fix.engine.SslContextFactory;
import biz.onixs.fix.parser.Message;
import biz.onixs.fix.tag.FIX40;
import biz.onixs.fix.tag.Tag;
import biz.onixs.util.TimestampFormat;
import biz.onixs.util.settings.PropertyBasedSettings;
import biz.onixs.util.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.security.GeneralSecurityException;
import java.util.concurrent.Semaphore;

/**
 * FIX Initiator - Buy Side. With SSL support.
 */
public class SslBuySide implements Session.InboundApplicationMessageListener, Session.StateChangeListener,
        Session.MessageResendingListener, Session.InboundSessionMessageListener, Session.WarningListener,
        Session.ErrorListener {
    private static final Logger LOG = LoggerFactory.getLogger(SslBuySide.class);
    private static final String SETTINGS_RESOURCE = "sample/SslBuySide.properties";
    private final Semaphore sessionIsEstablished = new Semaphore(0);
    private final Semaphore executionReportIsReceived = new Semaphore(0);
    private Settings settings = null;
    private Version fixVersion = null;
    private Session session = null;

    public void run() throws GeneralSecurityException, InterruptedException {
        LOG.info("Loading settings from: {}", SETTINGS_RESOURCE);
        settings = new PropertyBasedSettings(SETTINGS_RESOURCE);
        //
        startEngine();
        createSession();
        establishConnection();
        //
        LOG.info("Waiting for session establishment...");
        sessionIsEstablished.acquire();
        //
        final Message order = createOrder();
        session.send(order);
        //
        LOG.info("Waiting for execution report...");
        executionReportIsReceived.acquire();
        //
        session.logout("The session is disconnected by SimpleBuySide");
        session.dispose();
        //
        LOG.info("Engine shutdown...");
        Engine.getInstance().shutdown();
    }

    private void startEngine() {
        LOG.info("Starting the Engine...");
        Engine.init(settings);
        //
        if (settings.getBoolean("SslDebug", false)) {
            System.setProperty("javax.net.debug", "ssl");
        }
    }

    private void createSession() throws GeneralSecurityException {
        fixVersion = Version.getByNumber(settings.getString("FIXVersion"));
        session = new Session(settings.getString("SenderCompID"), settings.getString("TargetCompID"),
                fixVersion, false);
        //
        session.setSenderSubID("SenderSubID (50) field")
                .setSendingTimeFormat(TimestampFormat.YYYYMMDDHHMMSSMsec)
                .setInboundApplicationMessageListener(this)
                .setInboundSessionMessageListener(this)
                .addStateChangeListener(this)
                .setMessageResendingListener(this)
                .setErrorListener(this)
                .setWarningListener(this);
        //
        // init SSL support for Initiator session
        final SSLContext sslContext = SslContextFactory.getInstance(
                settings.getString("KeyStore"), settings.getString("TrustStore"), settings.getString("KeyPass"),
                settings.getString("KeyStorePass"), settings.getString("TrustStorePass"));
        session.setSSLContext(sslContext);
    }

    private void establishConnection() {
        final String host = settings.getString("CounterpartyHost");
        final int port = settings.getInteger("CounterpartyPort");
        LOG.info("Establishing connection to {}:{}...", host, port);
        session.logonAsInitiator(host, port, true);
    }

    private Message createOrder() {
        final Message order = Message.create(FIX40.MsgType.Order_Single, fixVersion);
        order.set(Tag.HandlInst, "1")
                .set(Tag.ClOrdID, "Unique identifier for Order")
                .set(Tag.Symbol, "IBM")
                .set(Tag.Side, "1")
                .set(Tag.OrderQty, 1000)
                .set(Tag.OrdType, "1");
        return order;
    }

    @Override
    public void onInboundApplicationMessage(final Object sender, final Session.InboundApplicationMessageArgs args) {
        final Message message = args.getMsg();
        LOG.info("Incoming application-level message: {}", message);
        if (message.checkType(FIX40.MsgType.Execution_Report)) {
            LOG.info("Execution report received.");
            executionReportIsReceived.release();
        }
        // Processing of the incoming application-level message...
    }

    @Override
    public void onInboundSessionMessage(final Object sender, final Session.InboundSessionMessageArgs args) {
        final Message message = args.getMsg();
        LOG.info("Incoming session-level message: {}", message);
        // Processing of the incoming session-level message...
    }

    @Override
    public void onStateChange(final Object sender, final Session.StateChangeArgs args) {
        final SessionState newState = args.getNewState();
        final SessionState prevState = args.getPrevState();
        LOG.info("Session state changed from {} to {}", prevState, newState);
        if (SessionState.ESTABLISHED == newState) {
            sessionIsEstablished.release();
        }
    }

    @Override
    public void onError(final Object sender, final Session.ErrorArgs args) {
        LOG.error("{}", args);
    }

    @Override
    public void onWarning(final Object sender, final Session.WarningArgs args) {
        LOG.warn("{}", args);
    }

    @Override
    public boolean onMessageResending(final Object sender, final Session.MessageResendingArgs args) {
        LOG.info("Message resending request: {}", args.getMsg());
        // Return false if it's necessary to skip this message (GapFill will be sent).
        return false;
    }

    @Override
    public void onMessageResendingStarted(final Object sender, final long beginSeqNum, final long endSeqNum) {
        LOG.info("Message resending is about to start from {} to {} seq. numbers", beginSeqNum, endSeqNum);
    }

    @Override
    public void onMessageResendingFinished(final Object sender, final long beginSeqNum, final long endSeqNum) {
        LOG.info("Message resending is finished from {} to {} seq. numbers", beginSeqNum, endSeqNum);
    }

    public static void main(final String[] args) {
        try {
            LOG.info("SslBuySide");
            LOG.info("The application is starting...");
            final SslBuySide buySide = new SslBuySide();
            buySide.run();
        } catch (final Throwable throwable) {
            LOG.error(throwable.getMessage(), throwable);
        } finally {
            LOG.info("The application is stopped.");
        }
    }
}

Ssl Sell Side

Description

This is a FIX Acceptor that waits for incoming connections on the pre-defined port (ListenPort).

The connection is secured using SSL.

If the incoming application-level message is “SingleOrder - New” (MsgType=‘D’) then the “ExecutionReport” (MsgType=‘8’) message is send to the counterparty. Otherwise the “Email” (MsgType=‘C’) message is sent back.

This sample can be run together with the “BuySide SSL” sample. “SellSide SSL” must be started first.

Directory Contents

Item Description
conf/sample/sellside.cer SSL certificate
conf/sample/sellside.keystore.bin SSL key store
conf/sample/sellside.truststore.bin SSL trust store

Usage

  • Run the sample:
    • win: 1-SslSellSide.bat
    • linux: 1-SslSellSide.sh
  • Clean everything:
    • win: clean.bat
    • linux: clean.sh

Source Code

import biz.onixs.fix.dictionary.Version;
import biz.onixs.fix.engine.Engine;
import biz.onixs.fix.engine.Session;
import biz.onixs.fix.engine.SessionState;
import biz.onixs.fix.engine.SslContextFactory;
import biz.onixs.fix.parser.Message;
import biz.onixs.fix.tag.FIX40;
import biz.onixs.fix.tag.Tag;
import biz.onixs.util.GuidGenerator;
import biz.onixs.util.TimestampFormat;
import biz.onixs.util.settings.PropertyBasedSettings;
import biz.onixs.util.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.security.GeneralSecurityException;
import java.util.concurrent.Semaphore;

/**
 * FIX Acceptor - Sell Side. With SSL support.
 */
public class SslSellSide implements Session.InboundApplicationMessageListener, Session.StateChangeListener,
        Session.ErrorListener, Session.WarningListener, Session.MessageResendingListener,
        Session.InboundSessionMessageListener {
    private static final Logger LOG = LoggerFactory.getLogger(SslSellSide.class);
    private static final String SETTINGS_RESOURCE = "sample/SslSellSide.properties";
    private final Semaphore sessionIsDisconnected = new Semaphore(0);
    private final Semaphore sessionIsEstablished = new Semaphore(0);
    private final GuidGenerator guidGenerator = new GuidGenerator();
    private Settings settings = null;
    private Version fixVersion = null;
    private Session session = null;

    void run() throws Exception {
        LOG.info("Loading settings from: {}", SETTINGS_RESOURCE);
        settings = new PropertyBasedSettings(SETTINGS_RESOURCE);
        //

        startEngine();
        //
        createSession();
        session.logonAsAcceptor();
        sessionIsDisconnected.acquire();
        //
        LOG.info("Waiting for connection...");
        sessionIsEstablished.acquire();
        //
        LOG.info("Waiting for disconnection...");
        sessionIsDisconnected.acquire();
        session.logout();
        session.dispose();
        //
        LOG.info("Engine shutdown...");
        Engine.getInstance().shutdown();
    }

    private void startEngine() throws GeneralSecurityException {
        // init SSL support for Acceptor session
        final SSLContext sslContext = SslContextFactory.getInstance(
                settings.getString("KeyStore"), settings.getString("TrustStore"), settings.getString("KeyPass"),
                settings.getString("KeyStorePass"), settings.getString("TrustStorePass"));
        Engine.setSSLContext(sslContext);
        //
        LOG.info("Starting the Engine...");
        Engine.init(settings);
        //
        if (settings.getBoolean("SslDebug", false)) {
            System.setProperty("javax.net.debug", "ssl");
        }
    }

    private void createSession() {
        fixVersion = Version.getByNumber(settings.getString("FIXVersion"));
        session = new Session(settings.getString("SenderCompID"),
                settings.getString("TargetCompID"),
                fixVersion, false);
        //
        session.setInboundApplicationMessageListener(this)
                .setInboundSessionMessageListener(this)
                .addStateChangeListener(this)
                .setErrorListener(this)
                .setWarningListener(this)
                .setMessageResendingListener(this)
                .setSendingTimeFormat(TimestampFormat.YYYYMMDDHHMMSSMsec);
    }

    private Message createExecutionReport(final Message order) {
        final Message execReport = Message.create(FIX40.MsgType.Execution_Report, fixVersion);
        execReport.set(Tag.OrderID, order.get(Tag.ClOrdID))
                .set(Tag.ExecID, guidGenerator.generate())
                .set(Tag.ExecTransType, "0")
                .set(Tag.OrdStatus, "0")
                .set(Tag.Symbol, order.get(Tag.Symbol))
                .set(Tag.Side, order.get(Tag.Side))
                .set(Tag.OrderQty, order.get(Tag.OrderQty))
                .set(Tag.CumQty, order.get(Tag.OrderQty))
                .set(Tag.AvgPx, "100.0");
        return execReport;
    }

    @Override
    public void onInboundApplicationMessage(final Object sender, final Session.InboundApplicationMessageArgs args) {
        final Message message = args.getMsg();
        LOG.info("Incoming application-level message: {}", message);
        if (message.checkType(FIX40.MsgType.Order_Single)) {
            LOG.info("Order received.");
            final Message executionReport = createExecutionReport(message);
            LOG.info("Sending execution report in response: {}", executionReport);
            session.send(executionReport);
        }
    }

    @Override
    public void onInboundSessionMessage(final Object sender, final Session.InboundSessionMessageArgs args) {
        final Message message = args.getMsg();
        LOG.info("Incoming session-level message: {}", message);
        // Processing of the incoming session-level message...
    }

    @Override
    public void onStateChange(final Object sender, final Session.StateChangeArgs args) {
        final SessionState newState = args.getNewState();
        final SessionState prevState = args.getPrevState();
        LOG.info("Session state changed from {} to {}", prevState, newState);
        if (SessionState.AWAIT_LOGON == newState) {
            sessionIsDisconnected.release();
        } else if (SessionState.ESTABLISHED == newState) {
            sessionIsEstablished.release();
        }
    }

    @Override
    public void onError(final Object sender, final Session.ErrorArgs args) {
        LOG.error("{}", args);
    }

    @Override
    public void onWarning(final Object sender, final Session.WarningArgs args) {
        LOG.warn("{}", args);
    }

    @Override
    public boolean onMessageResending(final Object sender, final Session.MessageResendingArgs args) {
        LOG.info("Message resending request: {}", args.getMsg());
        // Return false if it's necessary to skip this message (GapFill will be sent).
        return false;
    }

    @Override
    public void onMessageResendingStarted(final Object sender, final long beginSeqNum, final long endSeqNum) {
        LOG.info("Message resending is about to start from {} to {} seq. numbers", beginSeqNum, endSeqNum);
    }

    @Override
    public void onMessageResendingFinished(final Object sender, final long beginSeqNum, final long endSeqNum) {
        LOG.info("Message resending is finished from {} to {} seq. numbers", beginSeqNum, endSeqNum);
    }

    public static void main(final String[] args) {
        try {
            LOG.info("SslSellSide");
            LOG.info("The application is starting...");
            final SslSellSide sellSide = new SslSellSide();
            sellSide.run();
        } catch (final Throwable throwable) {
            LOG.error(throwable.getMessage(), throwable);
        } finally {
            LOG.info("The application is stopped.");
        }
    }
}