OnixS C++ ICE Binary Order Entry Handler 1.0.0
API Documentation
Loading...
Searching...
No Matches
Gateway Emulator

To simplify development and testing, the Handler's SDK includes the Gateway Emulator. The Emulator simulates the Gateway. It can accept a connection, establish a session, and send/receive session-level/application-level messages. To receive notifications about incoming message, there are corresponding callbacks declared in OnixS::ICE::BOE::Testing::ClientMessageListener and OnixS::ICE::BOE::Testing::ClientSessionMessageListener classes. One can inherit from the corresponding class, override corresponding virtual methods, and implement the necessary logic.

To simplify running and testing, most of the samples from the distribution package use the Gateway Emulator by default. Therefore, one can see in detail how to use the Gateway Emulator.

Example

using namespace OnixS::ICE::BOE;
// The listener class for the session.
class MyListener : public SessionListener
{
public:
void onExecutionReport_New(const ExecutionReport_New msg, Session* /*sn*/) override
{
std::clog << msg << std::endl;
}
};
// The listener class for the gateway emulator.
class GatewayListener : public Testing::ClientMessageListener
{
public:
// Receive and process NewOrderRequest messages from the session.
void onNewOrderRequest(const NewOrderRequest& order, Testing::Gateway* gateway) override
{
updateReport(order);
// Send the ExecutionReportNew message to the session.
gateway->send(report_, ++reportsCounter_);
// Maintain the sequence numbers.
gateway->outSeqNum(reportsCounter_ + 1);
}
private:
void updateReport(const NewOrderRequest& order)
{
const auto sinchEpoch = UtcWatch::now().sinceEpoch();
constexpr static auto sid = 123;
const OrderExecID id{sid, reportsCounter_, sinchEpoch};
report_->clOrdId(order.clOrdId()).execId(id);
}
MessageHolder<ExecutionReport_New> report_;
Int32 reportsCounter_{ 0 };
};
const std::string CounterpartyHost = "Localhost";
const int CounterpartyPort = 64124;
const SessionSettings::LicenseStores licenseStores {"."};
// Create the gateway emulator using the same host and port to which the session will connect.
Testing::Gateway gateway(licenseStores, CounterpartyPort, CounterpartyHost.c_str());
std::promise<void> emulatorTaskPromise;
std::future<void> emulatorTaskDone = emulatorTaskPromise.get_future();
// Create and run a separate thread to accept the connection and handle the emulator's events
// since the emulator works in a synchronous way.
// This is not necessary in case you use a separate application for the emulator.
std::thread(
std::bind(
[&](std::promise<void>& p)
{
try
{
// Create the emulator listener object.
GatewayListener clientMessageListener;
// Run the event loop of the gateway emulator and provide the listener object.
// The method will work until the Terminate message is received from the session.
gateway.run(clientMessageListener);
p.set_value();
}
catch (...)
{
std::cerr << "Exception in Emulator's thread." << std::endl;
p.set_exception(
std::current_exception());
}
},
std::move(emulatorTaskPromise)))
.detach();
SessionSettings settings;
settings.licenseStore("../../license")
.userId("SessionId")
.rawData("rawData")
.ipSessionToken("ipSessionToken")
.clientId(1);
MyListener listener;
Session session(SessionType::BGW, settings, &listener);
// Connect the session to the gateway emulator.
session.connect(host, port);
typedef MessageHolder<NewOrderRequest> NewOrderSingle;
NewOrderSingle order;
// Send an order to the gateway emulator and disconnect the session.
session.send(order).disconnect();
// Wait for the completion of the thread of the gateway emulator.
emulatorTaskDone.get();