Samples :: Scheduler

Simple Acceptor

Description

This sample acts as a simple acceptor for other scheduler samples.

“SimpleAcceptor” application must be started first.

Directory Contents

Item Description
conf/sample/SimpleAcceptor.properties engine and application configuration file
conf/logback.xml logger configuration file

Usage

  • Run the sample:
    • win: 1-SimpleAcceptor.bat
    • linux: 1-SimpleAcceptor.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.scheduler.MultiDayLengthSchedule;
import biz.onixs.fix.scheduler.SequenceNumberResetPolicy;
import biz.onixs.fix.scheduler.SessionSchedule;
import biz.onixs.fix.scheduler.SessionScheduler;
import biz.onixs.fix.scheduler.SessionSchedulerException;
import biz.onixs.util.settings.PropertyBasedSettings;
import biz.onixs.util.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.DayOfWeek;
import java.time.LocalTime;

public class SimpleAcceptor {
    private static final Logger LOG = LoggerFactory.getLogger(SimpleAcceptor.class);
    private static final String SETTINGS_RESOURCE = "sample/SimpleAcceptor.properties";
    private final DemoSessionStateChangeListener stateChangeListener = new DemoSessionStateChangeListener();

    private void run() {
        SessionScheduler scheduler = null;
        try {
            LOG.info("Loading settings from: {}", SETTINGS_RESOURCE);
            final Settings settings = new PropertyBasedSettings(SETTINGS_RESOURCE);
            //
            LOG.info("Starting the Engine...");
            Engine.init(settings);
            //
            scheduler = createAndStartScheduler();
            final Session acceptor = createAcceptorSession(settings);
            //
            final SessionSchedule schedule = createSchedule();
            scheduler.registerAcceptor(acceptor, schedule);
            LOG.info("Acceptor session is registered in the scheduler.");
            //
            LOG.info("Waiting for connection...");
            stateChangeListener.waitEstablished();
            LOG.info("Connected");
            //
            LOG.info("Waiting for disconnection...");
            stateChangeListener.waitDisconnected();
            LOG.info("Disconnected");
            //
            scheduler.unregister(acceptor);
        } catch (final Exception e) {
            LOG.error(e.getMessage(), e);
        } finally {
            if (null != scheduler) {
                try {
                    scheduler.stop();
                } catch (final SessionSchedulerException e) {
                    LOG.error("Scheduler stop error", e);
                }
            }
            LOG.info("Stopping Engine...");
            if (Engine.isInited()) {
                Engine.getInstance().shutdown();
            }
        }
    }

    /**
     * Creates and configures the scheduler instance.
     */
    private SessionScheduler createAndStartScheduler() throws SessionSchedulerException {
        final SessionScheduler scheduler = new SessionScheduler();
        scheduler.getListenerManager().addErrorListener(new DemoErrorListener());
        scheduler.start();
        return scheduler;
    }

    /**
     * Creates and configures acceptor connection settings.
     */
    private Session createAcceptorSession(final Settings settings) {
        final Version fixVersion = Version.getById(settings.getString("FixVersion"));
        final Session session = new Session(settings.getString("SenderCompID"), settings.getString("TargetCompID"),
                fixVersion, false);
        session.addStateChangeListener(stateChangeListener);
        return session;
    }

    /**
     * Creates and configures session schedule. Details:
     * <ul>
     * <li>logon on Monday at 00:00:00</li>
     * <li>logout on Sunday at 23:59:55</li>
     * </ul>
     */
    private static SessionSchedule createSchedule() {
        final MultiDayLengthSchedule schedule = new MultiDayLengthSchedule();
        schedule.setLogonTime(LocalTime.of(0, 0, 0))
                .setLogoutTime(LocalTime.of(23, 59, 55))
                .setFirstDay(DayOfWeek.MONDAY)
                .setLastDay(DayOfWeek.SUNDAY)
                .setResetPolicy(SequenceNumberResetPolicy.DAILY);
        return schedule;
    }

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

Program Schedule Sample

Description

The sample demonstrates how to configure session scheduler programatically.

This sample can be run together with the “SimpleAcceptor” app. The “SimpleAcceptor” must be started first.

Directory Contents

Item Description
conf/sample/ProgramScheduleSample.properties engine and application configuration file
conf/logback.xml logger configuration file

Usage

  • Run the sample:
    • win: 2-ProgramScheduleSample.bat
    • linux: 2-ProgramScheduleSample.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.scheduler.InitiatorConnection;
import biz.onixs.fix.scheduler.SequenceNumberResetPolicy;
import biz.onixs.fix.scheduler.SessionSchedule;
import biz.onixs.fix.scheduler.SessionScheduler;
import biz.onixs.fix.scheduler.SessionSchedulerException;
import biz.onixs.fix.scheduler.SingleDayLengthSchedule;
import biz.onixs.util.settings.PropertyBasedSettings;
import biz.onixs.util.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.time.DayOfWeek;
import java.time.LocalTime;

public class ProgramScheduleSample {
    private static final Logger LOG = LoggerFactory.getLogger(ProgramScheduleSample.class);
    private final DemoSessionStateChangeListener stateChangeListener = new DemoSessionStateChangeListener();

    private void run() {
        Engine engine = null;
        SessionScheduler scheduler = null;
        try {
            final Settings appSettings = new PropertyBasedSettings("sample/ProgramScheduleSample.properties");
            //
            LOG.info("Starting Engine...");
            engine = Engine.init(appSettings);
            //
            LOG.info("---! Please make sure 'SimpleAcceptor' app is started !---");
            //
            scheduler = createAndStartScheduler();
            final Session initiator = createInitiatorSession(appSettings);
            //
            final SessionSchedule schedule = createSchedule();
            final InitiatorConnection connection = createInitiatorSettings(appSettings);
            scheduler.register(initiator, schedule, connection);
            LOG.info("Initiator session is registered in the scheduler.");
            //
            LOG.info("Waiting to connect...");
            stateChangeListener.waitEstablished();
            LOG.info("Connected.");
            //
            LOG.info("Waiting to disconnect...");
            stateChangeListener.waitDisconnected();
            LOG.info("Disconnected.");
            //
            scheduler.unregister(initiator);
        } catch (final Exception e) {
            LOG.error(e.getMessage(), e);
        } finally {
            if (null != scheduler) {
                try {
                    scheduler.stop();
                } catch (final SessionSchedulerException e) {
                    LOG.error("Scheduler stop error", e);
                }
            }
            LOG.info("Stopping Engine...");
            if (Engine.isInited()) {
                Engine.getInstance().shutdown();
            }
        }
    }

    /**
     * Creates and configures the FIX initiator session.
     */
    private Session createInitiatorSession(final Settings settings) {
        final Version fixVersion = Version.getById(settings.getString("FixVersion"));
        final String senderCompId = settings.getString("SenderCompID");
        final String targetCompId = settings.getString("TargetCompID");
        final Session session = new Session(senderCompId, targetCompId, fixVersion, false);
        session.addStateChangeListener(stateChangeListener);
        return session;
    }

    /**
     * Creates and configures the scheduler instance.
     */
    private static SessionScheduler createAndStartScheduler() throws SessionSchedulerException {
        final SessionScheduler scheduler = new SessionScheduler()
                .addLogoutNotification(1)
                .addLogoutNotification(2);
        scheduler.getListenerManager()
                .addErrorListener(new DemoErrorListener())
                .addLogoutNotificationListener(new DemoLogoutNotificationListener());
        scheduler.start();
        return scheduler;
    }

    /**
     * Creates and configures the initiator connection settings.
     */
    private static InitiatorConnection createInitiatorSettings(final Settings settings) {
        final InitiatorConnection connection = new InitiatorConnection();
        final String host = settings.getString("CounterpartyHost");
        final int port = settings.getInteger("CounterpartyPort");
        final InetSocketAddress address = InetSocketAddress.createUnresolved(host, port);
        connection.addAddress(address);
        return connection;
    }

    /**
     * Creates and configures the simple session schedule.
     * Features:
     * <ul>
     * <li>logon and logout every day from Monday till Sunday</li>
     * <li>logon time is set to 5 seconds from now</li>
     * <li>logout time is set to 10 seconds from now</li>
     * </ul>
     */
    private static SessionSchedule createSchedule() {
        final SingleDayLengthSchedule schedule = new SingleDayLengthSchedule();
        final LocalTime now = LocalTime.now();
        schedule.setLogonTime(now.plusSeconds(5))
                .setLogoutTime(now.plusSeconds(15))
                .setFirstDay(DayOfWeek.MONDAY)
                .setLastDay(DayOfWeek.SUNDAY)
                .setResetPolicy(SequenceNumberResetPolicy.DAILY);
        return schedule;
    }

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

Program Generic Schedule Sample

Description

This sample demonstrates how to create custom session schedule programatically.

“ProgramGenericScheduleSample” can be run together with the “SimpleAcceptor” app. The “SimpleAcceptor” must be started first.

Directory Contents

Item Description
conf/sample/ProgramGenericScheduleSample.properties engine and application configuration file
conf/logback.xml logger configuration file

Usage

  • Run the sample:
    • win: 2-ProgramGenericScheduleSample.bat
    • linux: 2-ProgramGenericScheduleSample.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.scheduler.GenericWeeklySchedule;
import biz.onixs.fix.scheduler.InitiatorConnection;
import biz.onixs.fix.scheduler.ScheduleValidationException;
import biz.onixs.fix.scheduler.SessionSchedule;
import biz.onixs.fix.scheduler.SessionScheduler;
import biz.onixs.fix.scheduler.SessionSchedulerException;
import biz.onixs.fix.scheduler.WeeklyInterval;
import biz.onixs.util.settings.PropertyBasedSettings;
import biz.onixs.util.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalTime;

public class ProgramGenericScheduleSample {
    private static final Logger LOG = LoggerFactory.getLogger(ProgramGenericScheduleSample.class);
    private final DemoSessionStateChangeListener stateChangeListener = new DemoSessionStateChangeListener();

    private void run() {
        SessionScheduler scheduler = null;
        try {
            final Settings appSettings = new PropertyBasedSettings("sample/ProgramGenericScheduleSample.properties");
            //
            LOG.info("Starting Engine...");
            Engine.init(appSettings);
            //
            LOG.info("---! Please make sure 'SimpleAcceptor' app is started !---");
            //
            scheduler = createAndStartScheduler();
            final Session initiator = createInitiatorSession(appSettings);
            //
            final SessionSchedule schedule = createSchedule();
            //
            final InitiatorConnection connection = createInitiatorSettings(appSettings);
            scheduler.register(initiator, schedule, connection);
            LOG.info("Initiator session is registered in the scheduler.");
            //
            LOG.info("Waiting to connect...");
            stateChangeListener.waitEstablished();
            LOG.info("Connected.");
            //
            LOG.info("Waiting to disconnect...");
            stateChangeListener.waitDisconnected();
            LOG.info("Disconnected.");
            //
            scheduler.unregister(initiator);
        } catch (final Exception e) {
            LOG.error(e.getMessage(), e);
        } finally {
            if (null != scheduler) {
                try {
                    scheduler.stop();
                } catch (final SessionSchedulerException e) {
                    LOG.error("Scheduler stop error", e);
                }
            }
            LOG.info("Stopping Engine...");
            if (Engine.isInited()) {
                Engine.getInstance().shutdown();
            }
        }
    }

    /**
     * Creates and configures the FIX initiator session.
     */
    private Session createInitiatorSession(final Settings settings) {
        final Version fixVersion = Version.getByNumber(settings.getString("FixVersion"));
        final String senderCompId = settings.getString("SenderCompID");
        final String targetCompId = settings.getString("TargetCompID");
        final Session session = new Session(senderCompId, targetCompId, fixVersion, false);
        session.addStateChangeListener(stateChangeListener);
        return session;
    }

    /**
     * Creates and configures the scheduler instance.
     */
    private static SessionScheduler createAndStartScheduler() throws SessionSchedulerException {
        final SessionScheduler scheduler = new SessionScheduler()
                .addLogoutNotification(1)
                .addLogoutNotification(2);
        scheduler.getListenerManager()
                .addErrorListener(new DemoErrorListener())
                .addLogoutNotificationListener(new DemoLogoutNotificationListener());
        scheduler.start();
        return scheduler;
    }

    /**
     * Creates and configures the initiator connection settings.
     */
    private static InitiatorConnection createInitiatorSettings(final Settings settings) {
        final InitiatorConnection connection = new InitiatorConnection();
        final String host = settings.getString("CounterpartyHost");
        final int port = settings.getInteger("CounterpartyPort");
        final InetSocketAddress address = InetSocketAddress.createUnresolved(host, port);
        connection.addAddress(address);
        return connection;
    }

    /**
     * Creates and configures generic weekly session schedule which can consist of several activity intervals.
     */
    private static SessionSchedule createSchedule() throws ScheduleValidationException {
        final GenericWeeklySchedule schedule = new GenericWeeklySchedule();
        //
        final LocalTime now = LocalTime.now();
        final DayOfWeek todayDayOfWeek = LocalDate.now().getDayOfWeek();
        //
        final WeeklyInterval interval = new WeeklyInterval()
                .setLogonDay(todayDayOfWeek)
                .setLogonTime(now.plusSeconds(5))
                .setLogoutDay(todayDayOfWeek)
                .setLogoutTime(now.plusSeconds(10))
                .setResetOnLogout(false);
        schedule.addInterval(interval);
        //
        return schedule;
    }

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

File Schedule Sample

Description

The sample demonstrates how to configure session scheduler using configuration file.

This sample can be run together with the “SimpleAcceptor” app. The “SimpleAcceptor” must be started first.

Directory Contents

Item Description
conf/sample/FileScheduleSample.properties engine and application configuration file
conf/sample/SchedulerSettings.xml scheduler configuration file
conf/logback.xml logger configuration file

Usage

  • Run the sample:
    • win: 2-FileScheduleSample.bat
    • linux: 2-FileScheduleSample.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.scheduler.SchedulerSettings;
import biz.onixs.fix.scheduler.SchedulerSettingsLoader;
import biz.onixs.fix.scheduler.SchedulerSettingsLoaderException;
import biz.onixs.fix.scheduler.SessionScheduler;
import biz.onixs.fix.scheduler.SessionSchedulerException;
import biz.onixs.util.settings.PropertyBasedSettings;
import biz.onixs.util.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FileScheduleSample {
    private static final Logger LOG = LoggerFactory.getLogger(FileScheduleSample.class);
    private final DemoSessionStateChangeListener stateChangeListener = new DemoSessionStateChangeListener();

    private void run() {
        SessionScheduler scheduler = null;
        try {
            final Settings appSettings = new PropertyBasedSettings("sample/FileScheduleSample.properties");
            //
            LOG.info("Starting Engine...");
            Engine.init(appSettings);
            //
            LOG.info("---! Please make sure 'SimpleAcceptor' app is started !---");
            //
            scheduler = createAndStartScheduler();
            final SchedulerSettings schedulerSettings = loadSchedulerSettings("sample/SchedulerSettings.xml");
            final Session initiator = createInitiatorSession(appSettings);
            scheduler.register(initiator, schedulerSettings, "Schedule1", "Initiator1");
            LOG.info("Initiator session is registered in the scheduler.");
            //
            LOG.info("Waiting to connect...");
            stateChangeListener.waitEstablished();
            LOG.info("Connected.");
            //
            scheduler.unregister(initiator);
            //
            initiator.logout();
        } catch (final Exception e) {
            LOG.error(e.getMessage(), e);
        } finally {
            if (null != scheduler) {
                try {
                    scheduler.stop();
                } catch (final SessionSchedulerException e) {
                    LOG.error("Scheduler stop error", e);
                }
            }
            LOG.info("Stopping Engine...");
            if (Engine.isInited()) {
                Engine.getInstance().shutdown();
            }
        }
    }

    /**
     * Creates and configures the FIX initiator session.
     *
     * @return initiator session
     */
    private Session createInitiatorSession(final Settings settings) {
        final Version fixVersion = Version.getByNumber(settings.getString("FixVersion"));
        final String senderCompId = settings.getString("SenderCompID");
        final String targetCompId = settings.getString("TargetCompID");
        final Session session = new Session(senderCompId, targetCompId, fixVersion, false);
        session.addStateChangeListener(stateChangeListener);
        return session;
    }

    /**
     * Creates and configures the scheduler instance.
     *
     * @return scheduler
     */
    private static SessionScheduler createAndStartScheduler() throws SessionSchedulerException {
        final SessionScheduler scheduler = new SessionScheduler();
        scheduler.getListenerManager().addErrorListener(new DemoErrorListener());
        scheduler.start();
        return scheduler;
    }

    private static SchedulerSettings loadSchedulerSettings(final String resource)
            throws SchedulerSettingsLoaderException {
        final SchedulerSettingsLoader loader = new SchedulerSettingsLoader();
        return loader.load(resource);
    }

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

Source Codes Used In Samples

import biz.onixs.fix.scheduler.ErrorListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DemoErrorListener implements ErrorListener {
    private static final Logger LOG = LoggerFactory.getLogger(DemoErrorListener.class);

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

    /**
     * Logon error event callback.
     *
     * @param args event arguments
     */
    @Override
    public void onLogonError(final LogonErrorArgs args) {
        LOG.error("onLogonError(): {}", args);
    }
}
import biz.onixs.fix.scheduler.LogoutNotification;
import biz.onixs.fix.scheduler.LogoutNotificationListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Demo logout notification listener implementation.
 */
public class DemoLogoutNotificationListener implements LogoutNotificationListener {
    private static final Logger LOG = LoggerFactory.getLogger(DemoLogoutNotificationListener.class);

    @Override
    public void onLogoutNotification(final LogoutNotification notification) {
        LOG.info("{}: logout notification: {} seconds left", notification.getSession(), notification.getInterval());
    }
}
import biz.onixs.fix.engine.Session;
import biz.onixs.fix.engine.SessionState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Semaphore;

public class DemoSessionStateChangeListener implements Session.StateChangeListener {
    private static final Logger LOG = LoggerFactory.getLogger(DemoSessionStateChangeListener.class);
    private final Semaphore semaphoreIsEstablished = new Semaphore(0);
    private final Semaphore semaphoreIsDisconnected = new Semaphore(0);

    @Override
    public void onStateChange(final Object sender, final Session.StateChangeArgs args) {
        final SessionState prevState = args.getPrevState();
        final SessionState newState = args.getNewState();
        if ((prevState != SessionState.DISCONNECTED)
                && ((SessionState.DISCONNECTED == newState) || (SessionState.AWAIT_LOGON == newState))) {
            semaphoreIsDisconnected.release();
        } else if (SessionState.ESTABLISHED == newState) {
            semaphoreIsEstablished.release();
        }
    }

    public void waitEstablished() throws InterruptedException {
        semaphoreIsEstablished.acquire();
    }

    public void waitDisconnected() throws InterruptedException {
        semaphoreIsDisconnected.acquire();
    }
}