Samples :: Scheduler
- Samples :: Scheduler
This module contains four samples: a simple acceptor, a programmatic schedule sample, a generic schedule sample, and a file-based schedule sample.
Simple Acceptor
Description
This sample acts as a simple acceptor for the scheduler samples.
The “SimpleAcceptor” application must be started first.
Directory Contents
| Item | Description |
|---|---|
| conf | configuration directory |
| src | source code |
Usage
- Run the sample (scripts are under
src/main/script/):- win: 1-SimpleAcceptor.bat
- linux: 1-SimpleAcceptor.sh
- Clean everything (scripts are under
samples/src/main/script/at the repo root):- win: clean.bat
- linux: clean.sh
Source Code
import biz.onixs.cme.ilink3.testing.Emulator;
import biz.onixs.cme.ilink3.testing.TestUtility;
import biz.onixs.util.settings.PropertyBasedSettings;
import biz.onixs.util.settings.Settings;
import org.junit.jupiter.api.Assertions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SimpleAcceptor {
private static final Logger LOG = LoggerFactory.getLogger(SimpleAcceptor.class);
private static final String SETTINGS_RESOURCE = "sample/SimpleAcceptor.properties";
private void run() {
try {
//
LOG.info("Loading settings from: {}", SETTINGS_RESOURCE);
final Settings settings = new PropertyBasedSettings(SETTINGS_RESOURCE);
LOG.info("Creates an Emulator object configured as acceptor");
final Emulator emulator = new Emulator(new TestUtility());
emulator.setPort(settings.getInteger("ListenPort"));
LOG.info("Accepts an incoming TCP connection and prepares for message exchange");
emulator.acceptConnection();
LOG.info("Accepts a \"Negotiate\" message from the initiator");
emulator.acceptNegotiation();
LOG.info("Accepts an \"Establish\" message, finalizing the session setup");
emulator.acceptEstablishment(1);
LOG.info("Accepts a \"Terminate\" message, ending the session");
emulator.acceptTerminate();
// Asserts that the Emulator's connection is now closed.
Assertions.assertTrue(emulator.isConnectionClosed());
} catch (final Exception e) {
LOG.error(e.getMessage(), e);
}
}
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
This sample demonstrates configuring the Session Scheduler programmatically with a simple daily schedule.
The “SimpleAcceptor” application must be started first.
Directory Contents
| Item | Description |
|---|---|
| conf | configuration directory |
| src | source code |
Usage
- Run the sample (scripts are under
src/main/script/):- win: 2-ProgramScheduleSample.bat
- linux: 2-ProgramScheduleSample.sh
- Clean everything (scripts are under
samples/src/main/script/at the repo root):- win: clean.bat
- linux: clean.sh
Source Code
import biz.onixs.cme.ilink3.handler.Handler;
import biz.onixs.cme.ilink3.handler.Session;
import biz.onixs.cme.ilink3.handler.session.SessionSettings;
import biz.onixs.cme.ilink3.scheduler.*;
import biz.onixs.util.settings.PropertyBasedSettings;
import biz.onixs.util.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.time.DayOfWeek;
import java.time.LocalTime;
public class ProgramScheduleSample implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(ProgramScheduleSample.class);
private static final String SETTINGS_RESOURCE = "sample/ProgramScheduleSample.properties";
private final DemoSessionStateChangeListener stateChangeListener = new DemoSessionStateChangeListener();
private final int marketSegmentId;
private final String host;
private final int port;
private final Settings settings;
private Session session = null;
private SessionScheduler scheduler = null;
public ProgramScheduleSample(final int marketSegmentId, final String host, final int port,
final Settings settings) {
this.marketSegmentId = marketSegmentId;
this.host = host;
this.port = port;
this.settings = settings;
}
public void run() {
try {
LOG.info("Starting the Handler...");
Handler.init(settings);
//
LOG.info("---! Please make sure 'SimpleAcceptor' app is started !---");
//
createAndStartScheduler();
//
createInitiatorSession();
//
final SessionSchedule schedule = createSchedule();
final SessionConnection connection = createInitiatorSettings();
scheduler.register(session, 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(session);
} 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("Handler shutdown ...");
if (Handler.isInited()) {
Handler.getInstance().shutdown();
}
LOG.info("The application is stopped.");
}
}
private void createInitiatorSession() {
final SessionSettings sessionSettings = new SessionSettings();
sessionSettings.init(settings);
session = new Session(sessionSettings, marketSegmentId);
session.addStateChangeListener(stateChangeListener);
}
/**
* Creates and configures the scheduler instance.
*/
private void createAndStartScheduler() throws SessionSchedulerException {
scheduler = new SessionScheduler();
scheduler.addLogoutNotification(1);
scheduler.addLogoutNotification(2);
scheduler.getListenerManager().addErrorListener(new DemoErrorListener());
scheduler.getListenerManager().addLogoutNotificationListener(new DemoLogoutNotificationListener());
scheduler.start();
}
/**
* Creates and configures the initiator connection settings.
*/
private SessionConnection createInitiatorSettings() {
final SessionConnection connection = new SessionConnection();
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);
return schedule;
}
private static void configureSettings(final Settings settings) throws IOException {
settings.setString(SessionSettings.SESSION_PROP, "XXX");
settings.setString(SessionSettings.FIRM_PROP, "001");
settings.setString(SessionSettings.ACCESS_KEY_PROP, "dGVzdHRlc3R0ZXN0dA==");
settings.setString(SessionSettings.SECRET_KEY_PROP, "dGVzdHRlc3R0ZXN0dGVzdHRlc3R0");
settings.setInteger(SessionSettings.KEEP_ALIVE_INTERVAL_PROP, 50);
settings.setInteger(SessionSettings.RECONNECT_ATTEMPTS_PROP, 0);
settings.setString(SessionSettings.TRADING_SYSTEM_VERSION_PROP, "1.1.0");
settings.setString(SessionSettings.TRADING_SYSTEM_NAME_PROP, "Trading System");
settings.setString(SessionSettings.TRADING_SYSTEM_VENDOR_PROP, "OnixS");
}
public static void main(final String[] args) throws IOException {
LOG.info("Program Schedule Sample");
LOG.info("The application is starting...");
LOG.info("Loading settings from: {}", SETTINGS_RESOURCE);
final Settings settings = new PropertyBasedSettings(SETTINGS_RESOURCE);
//
int marketSegmentId;
String host;
int port;
//
if (3 > args.length) {
LOG.info("Emulator is used, remote usage: [MarketSegmentId] [Host] [Port]");
marketSegmentId = settings.getInteger("MarketSegmentId", 59);
host = settings.getString("CounterpartyHost");
port = settings.getInteger("CounterpartyPort");
configureSettings(settings);
} else {
marketSegmentId = Integer.parseInt(args[0]);
host = args[1];
port = Integer.parseInt(args[2]);
}
final ProgramScheduleSample sample = new ProgramScheduleSample(marketSegmentId, host, port, settings);
sample.run();
}
}
Program Generic Schedule Sample
Description
This sample demonstrates building a custom weekly schedule with explicit logon/logout intervals.
The “SimpleAcceptor” application must be started first.
Directory Contents
| Item | Description |
|---|---|
| conf | configuration directory |
| src | source code |
Usage
- Run the sample (scripts are under
src/main/script/):- win: 2-ProgramGenericScheduleSample.bat
- linux: 2-ProgramGenericScheduleSample.sh
- Clean everything (scripts are under
samples/src/main/script/at the repo root):- win: clean.bat
- linux: clean.sh
Source Code
import biz.onixs.cme.ilink3.handler.Handler;
import biz.onixs.cme.ilink3.handler.Session;
import biz.onixs.cme.ilink3.handler.session.SessionSettings;
import biz.onixs.cme.ilink3.scheduler.*;
import biz.onixs.util.settings.PropertyBasedSettings;
import biz.onixs.util.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalTime;
public class ProgramGenericScheduleSample implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(ProgramGenericScheduleSample.class);
private static final String SETTINGS_RESOURCE = "sample/ProgramGenericScheduleSample.properties";
private final DemoSessionStateChangeListener stateChangeListener = new DemoSessionStateChangeListener();
private final int marketSegmentId;
private final String host;
private final int port;
private final Settings settings;
private Session session = null;
private SessionScheduler scheduler = null;
public ProgramGenericScheduleSample(final int marketSegmentId, final String host, final int port,
final Settings settings) {
this.marketSegmentId = marketSegmentId;
this.host = host;
this.port = port;
this.settings = settings;
}
public void run() {
try {
LOG.info("Starting the Handler...");
Handler.init(settings);
//
LOG.info("---! Please make sure 'SimpleAcceptor' app is started !---");
//
scheduler = createAndStartScheduler();
//
createInitiatorSession();
//
final SessionSchedule schedule = createSchedule();
final SessionConnection connection = createInitiatorSettings();
scheduler.register(session, 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(session);
} 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("Handler shutdown ...");
if (Handler.isInited()) {
Handler.getInstance().shutdown();
}
LOG.info("The application is stopped.");
}
}
private void createInitiatorSession() {
final SessionSettings sessionSettings = new SessionSettings();
sessionSettings.init(settings);
session = new Session(sessionSettings, marketSegmentId);
session.addStateChangeListener(stateChangeListener);
}
/**
* 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 SessionConnection createInitiatorSettings() {
final SessionConnection connection = new SessionConnection();
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))
.setResetOnLogon(false);
schedule.addInterval(interval);
//
return schedule;
}
private static void configureSettings(final Settings settings) throws IOException {
settings.setString(SessionSettings.SESSION_PROP, "XXX");
settings.setString(SessionSettings.FIRM_PROP, "001");
settings.setString(SessionSettings.ACCESS_KEY_PROP, "dGVzdHRlc3R0ZXN0dA==");
settings.setString(SessionSettings.SECRET_KEY_PROP, "dGVzdHRlc3R0ZXN0dGVzdHRlc3R0");
settings.setInteger(SessionSettings.KEEP_ALIVE_INTERVAL_PROP, 50);
settings.setInteger(SessionSettings.RECONNECT_ATTEMPTS_PROP, 0);
settings.setString(SessionSettings.TRADING_SYSTEM_VERSION_PROP, "1.1.0");
settings.setString(SessionSettings.TRADING_SYSTEM_NAME_PROP, "Trading System");
settings.setString(SessionSettings.TRADING_SYSTEM_VENDOR_PROP, "OnixS");
}
public static void main(final String[] args) throws IOException {
LOG.info("Program Generic Schedule Sample");
LOG.info("The application is starting...");
LOG.info("Loading settings from: {}", SETTINGS_RESOURCE);
final Settings settings = new PropertyBasedSettings(SETTINGS_RESOURCE);
//
int marketSegmentId;
String host;
int port;
//
if (3 > args.length) {
LOG.info("Emulator is used, remote usage: [MarketSegmentId] [Host] [Port]");
marketSegmentId = settings.getInteger("MarketSegmentId", 59);
host = settings.getString("CounterpartyHost");
port = settings.getInteger("CounterpartyPort");
configureSettings(settings);
} else {
marketSegmentId = Integer.parseInt(args[0]);
host = args[1];
port = Integer.parseInt(args[2]);
}
final ProgramGenericScheduleSample sample =
new ProgramGenericScheduleSample(marketSegmentId, host, port, settings);
sample.run();
}
}
File Schedule Sample
Description
This sample loads scheduler settings from conf/sample/SchedulerSettings.xml and registers the session
using those settings.
The “SimpleAcceptor” application must be started first.
Directory Contents
| Item | Description |
|---|---|
| conf | configuration directory |
| src | source code |
Usage
- Run the sample (scripts are under
src/main/script/):- win: 2-FileScheduleSample.bat
- linux: 2-FileScheduleSample.sh
- Clean everything (scripts are under
samples/src/main/script/at the repo root):- win: clean.bat
- linux: clean.sh
Source Code
import biz.onixs.cme.ilink3.handler.Handler;
import biz.onixs.cme.ilink3.handler.Session;
import biz.onixs.cme.ilink3.handler.session.SessionSettings;
import biz.onixs.cme.ilink3.scheduler.*;
import biz.onixs.util.settings.PropertyBasedSettings;
import biz.onixs.util.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.InetSocketAddress;
public class FileScheduleSample {
private static final Logger LOG = LoggerFactory.getLogger(FileScheduleSample.class);
private static final String SETTINGS_RESOURCE = "sample/FileScheduleSample.properties";
private static final String SCHEDULER_SETTINGS_RESOURCE = "sample/SchedulerSettings.xml";
private final DemoSessionStateChangeListener stateChangeListener = new DemoSessionStateChangeListener();
private void run(final Settings settings, final int marketSegmentId, final SessionConnection connectionOverride) {
SessionScheduler scheduler = null;
try {
LOG.info("Starting the Handler...");
Handler.init(settings);
//
LOG.info("---! Please make sure 'SimpleAcceptor' app is started !---");
//
scheduler = createAndStartScheduler();
final SchedulerSettings schedulerSettings = loadSchedulerSettings(SCHEDULER_SETTINGS_RESOURCE);
final Session initiator = createInitiatorSession(settings, marketSegmentId);
if (null == connectionOverride) {
scheduler.register(initiator, schedulerSettings, "Schedule1", "Initiator1");
} else {
scheduler.register(initiator, schedulerSettings, "Schedule1", connectionOverride);
}
LOG.info("Initiator session is registered in the scheduler.");
//
LOG.info("Waiting to connect...");
stateChangeListener.waitEstablished();
LOG.info("Connected.");
//
scheduler.unregister(initiator);
//
initiator.terminate();
} 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("Handler shutdown ...");
if (Handler.isInited()) {
Handler.getInstance().shutdown();
}
LOG.info("The application is stopped.");
}
}
/**
* Creates and configures the initiator session.
*/
private Session createInitiatorSession(final Settings settings, final int marketSegmentId) {
final SessionSettings sessionSettings = new SessionSettings();
sessionSettings.init(settings);
final Session session = new Session(sessionSettings, marketSegmentId);
session.addStateChangeListener(stateChangeListener);
return session;
}
/**
* Creates and configures the scheduler instance.
*/
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);
}
private static void configureSettings(final Settings settings) throws IOException {
settings.setString(SessionSettings.SESSION_PROP, "XXX");
settings.setString(SessionSettings.FIRM_PROP, "001");
settings.setString(SessionSettings.ACCESS_KEY_PROP, "dGVzdHRlc3R0ZXN0dA==");
settings.setString(SessionSettings.SECRET_KEY_PROP, "dGVzdHRlc3R0ZXN0dGVzdHRlc3R0");
settings.setInteger(SessionSettings.KEEP_ALIVE_INTERVAL_PROP, 50);
settings.setInteger(SessionSettings.RECONNECT_ATTEMPTS_PROP, 0);
settings.setString(SessionSettings.TRADING_SYSTEM_VERSION_PROP, "1.1.0");
settings.setString(SessionSettings.TRADING_SYSTEM_NAME_PROP, "Trading System");
settings.setString(SessionSettings.TRADING_SYSTEM_VENDOR_PROP, "OnixS");
}
private static SessionConnection createInitiatorSettings(final String host, final int port) {
final SessionConnection connection = new SessionConnection();
final InetSocketAddress address = InetSocketAddress.createUnresolved(host, port);
connection.addAddress(address);
return connection;
}
public static void main(final String[] args) throws IOException {
LOG.info("File Schedule Sample");
LOG.info("The application is starting...");
LOG.info("Loading settings from: {}", SETTINGS_RESOURCE);
final Settings settings = new PropertyBasedSettings(SETTINGS_RESOURCE);
//
final int marketSegmentId;
final SessionConnection connectionOverride;
if (3 > args.length) {
LOG.info("Emulator is used, remote usage: [MarketSegmentId] [Host] [Port]");
marketSegmentId = settings.getInteger("MarketSegmentId", 59);
connectionOverride = null;
configureSettings(settings);
} else {
marketSegmentId = Integer.parseInt(args[0]);
connectionOverride = createInitiatorSettings(args[1], Integer.parseInt(args[2]));
}
final FileScheduleSample fileScheduleSample = new FileScheduleSample();
fileScheduleSample.run(settings, marketSegmentId, connectionOverride);
}
}
Source Codes Used In Samples
import biz.onixs.cme.ilink3.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.cme.ilink3.scheduler.LogoutNotification;
import biz.onixs.cme.ilink3.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.cme.ilink3.handler.SessionState;
import biz.onixs.cme.ilink3.handler.session.StateChangeArgs;
import biz.onixs.cme.ilink3.handler.session.StateChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Semaphore;
public class DemoSessionStateChangeListener implements 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 StateChangeArgs args) {
final SessionState prevState = args.getPrevState();
final SessionState newState = args.getNewState();
if (prevState != SessionState.TERMINATED && SessionState.TERMINATED == newState) {
semaphoreIsDisconnected.release();
} else if (SessionState.ESTABLISHED == newState) {
semaphoreIsEstablished.release();
}
}
public void waitEstablished() throws InterruptedException {
semaphoreIsEstablished.acquire();
}
public void waitDisconnected() throws InterruptedException {
semaphoreIsDisconnected.acquire();
}
}
Java CME iLink3 Handler