OnixS C++ B3 BOE Binary Order Entry  1.2.0
API Documentation
Gateway.h
Go to the documentation of this file.
1 // Copyright Onix Solutions Limited [OnixS]. All rights reserved.
2 //
3 // This software owned by Onix Solutions Limited [OnixS] and is
4 // protected by copyright law and international copyright treaties.
5 //
6 // Access to and use of the software is governed by the terms of the applicable
7 // OnixS Software Services Agreement (the Agreement) and Customer end user license
8 // agreements granting a non-assignable, non-transferable and non-exclusive license
9 // to use the software for it's own data processing purposes under the terms defined
10 // in the Agreement.
11 //
12 // Except as otherwise granted within the terms of the Agreement, copying or
13 // reproduction of any part of this source code or associated reference material
14 // to any other location for further reproduction or redistribution, and any
15 // amendments to this copyright notice, are expressly prohibited.
16 //
17 // Any reproduction or redistribution for sale or hiring of the Software not in
18 // accordance with the terms of the Agreement is a violation of copyright law.
19 
20 #pragma once
21 
24 
25 #if defined(ONIXS_B3_BOE_HAS_GATEWAY_EMULATOR)
26 
27 #include <OnixS/B3/BOE/Messaging.h>
30 
31 #include <chrono>
32 #include <atomic>
33 
34 namespace OnixS {
35 namespace B3 {
36 namespace BOE {
37 namespace Testing {
38 
39 // Assume NegotiateResponse2::credentials is empty
40 constexpr
42 {
43  using Message = NegotiateResponse2;
44 
45  return
46  Message::blockLength(Message::Schema::Version)
48  + Message::getMinimalVariableFieldsSize(Message::Schema::Version);
49 }
50 
51 // Type aliases
58 
64 
65 /// B3 BOE Gateway Emulator.
67 {
68 public:
69  /// Timeout alias.
70  using Timeout = std::chrono::milliseconds;
71 
72  Gateway(const SessionSettings::LicenseStores& licenseStores, int port, const char* host = "127.0.0.1",
73  const Timeout& acceptTimeout = defaultTimeout(),
74  const Timeout& sendReceiveTimeout = defaultTimeout());
75 
76  ///
77  virtual ~Gateway();
78 
79  /// Deleted.
80  Gateway(const Gateway&) = delete;
81  Gateway& operator=(const Gateway&) = delete;
82 
83  /// Move semantic.
84  Gateway(Gateway&&) noexcept;
85  Gateway& operator=(Gateway&&) noexcept;
86 
87  /// Swap with other.
88  void swap(Gateway&) noexcept;
89 
90  /// Accepts an incoming connection.
91  /// If the `acceptTimeout` is zero, the `acceptTimeout` provided in the constructor is used.
92  Gateway& acceptConnection(const Timeout& acceptTimeout = defaultTimeout());
93 
94  /// Accepts an incoming connection.
95  /// If the operation is timed out, `false` is returned.
96  bool tryAcceptConnection(const Timeout& acceptTimeout = defaultTimeout());
97 
98  /// Accepts an incoming FIXP session.
99  Gateway& acceptSession(SeqNumber outgoingSequenceNumber = 1);
100 
101  /// Waits until the Terminate7 message is received.
102  ///
103  /// If the listener is provided, then receives and reports application-level messages via the corresponding callback.
104  /// Responds to the Sequence9 message if received.
105  /// \note actual `outSeqNum` must be provided before invocation
106  Terminate7Ptr waitUntilTerminate(
107  ClientMessageListener* listener = nullptr, ClientSessionMessageListener* sessionMessageListener = nullptr,
108  std::atomic<bool>* stopRequested = nullptr);
109 
110  /// Sends the Sequence9 message.
111  Gateway& sendSequence(UInt32 nextSeqNo);
112 
113  /// Closes the accepted connection.
114  Gateway& disconnect();
115 
116  /// @return listen host.
117  const char * host() const noexcept;
118 
119  /// \return the listen port.
121  int port() const noexcept;
122 
123  /// Enables logging.
124  Gateway& enableLogger(const std::string& logFileName, unsigned int logLevel = 3);
125 
126  /// Sends the given message.
127  /// \note does not update `outSeqNum`.
128  template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
129  Gateway& send(BOE::Messaging::MessageHolder<SbeMessageType, MaxMessageSize, MessageInitializer>& msg);
130 
131  /// Sends the given message.
132  /// \note does not update `outSeqNum`.
133  template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
134  Gateway& send(BOE::Messaging::MessageHolder<SbeMessageType, MaxMessageSize, MessageInitializer>&& msg);
135 
136  /// Sets the given sequence number and sends the message.
137  /// \note does not update `outSeqNum`.
138  template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
139  Gateway& send(BOE::Messaging::MessageHolder<SbeMessageType, MaxMessageSize, MessageInitializer>& msg, SeqNumber num);
140 
141  /// Sets the given sequence number and sends the message.
142  /// \note does not update `outSeqNum`.
143  template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
144  Gateway& send(BOE::Messaging::MessageHolder<SbeMessageType, MaxMessageSize, MessageInitializer>&& msg, SeqNumber num);
145 
146  /// Sets the given sequence numbers and sends the messages.
147  /// \note does not update `outSeqNum`.
148  template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
149  Gateway& send(BOE::Messaging::MessageHolder<SbeMessageType, MaxMessageSize, MessageInitializer>& msg, std::initializer_list<SeqNumber> numbers);
150 
151  /// Sets the given sequence numbers and sends the messages.
152  /// \note does not update `outSeqNum`.
153  template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
154  Gateway& send(BOE::Messaging::MessageHolder<SbeMessageType, MaxMessageSize, MessageInitializer>&& msg, std::initializer_list<SeqNumber> numbers);
155 
156 
157  /// Receives the message of the particular type.
158  ///
159  /// \throw std::logic_error if an unexpected type is received.
160  template <typename TMsg>
161  MessagePtr<TMsg> receiveTypedMessage();
162 
163  /// Accepts an incoming connection and establishes the session.
164  ///
165  /// - Receives and reports application-level messages via the corresponding callback.
166  /// - Sends Sequence messages in response to the received ones.
167  Gateway& run(ClientMessageListener& listener);
168 
169  /// Accepts an incoming connection and establishes the session.
170  ///
171  /// - Receives and reports application-level messages via the corresponding callback.
172  /// - Receives and reports session-level messages via the corresponding callback.
173  /// - Sends Sequence messages.
174  Gateway& run(ClientMessageListener& appMsgListener, ClientSessionMessageListener& sessionMsgListener);
175 
176  /// \return the sequence number of the next outgoing message.
178  SeqNumber outSeqNum() const noexcept;
179 
180  /// Sets the sequence number of the next outgoing message.
181  Gateway& outSeqNum(SeqNumber nextOutSeqNum) noexcept;
182 
183  /// \return sessionVerId.
185  UInt64 sessionVerId() const noexcept
186  {
187  return uId_;
188  }
189 
190  /// \return session Id.
192  SessionID sessionId() const noexcept
193  {
194  return sessionId_;
195  }
196 
197  /// Sets the value of the option to improve latency at the expense of message throughput (the `TCP_NODELAY` socket option).
198  Gateway& tcpNoDelayOption(bool noDelay);
199 
200  /// \return the value of the option to improve latency at the expense of message throughput (the `TCP_NODELAY` socket option).
201  ///
202  /// The default value is SessionSettings::Default::TcpNoDelayOption.
204  bool tcpNoDelayOption() const noexcept ;
205 
206  /// \return the socket receive buffer size.
207  ///
208  /// The default value is SessionSettings::Default::SocketReceiveBufferSize.
210  int socketReceiveBufferSize() const;
211 
212  /// Sets the socket receive buffer size.
213  ///
214  /// \param bufferSize the size of the socket receive buffer size.
215  /// If SessionSettings::UseOsDefaultSocketBufferSize then the default operating system value is used.
216  Gateway& socketReceiveBufferSize(int bufferSize);
217 
218  /// \return the size of the socket send buffer size.
219  ///
220  /// The default value is SessionSettings::Default::SocketSedndBufferSize.
222  int socketSendBufferSize() const noexcept;
223 
224  /// Sets the size of the socket send buffer size.
225  ///
226  /// \param bufferSize the size of the socket send buffer size.
227  /// If SessionSettings::UseOsDefaultSocketBufferSize then the default operating system value is used.
228  Gateway& socketSendBufferSize(int bufferSize);
229 
230 protected:
231  /// Checks whether the connection is closed by the counterparty.
233  bool isConnectionClosed(const Timeout& timeout) const;
234 
235  /// Checks whether the connection is closed by the counterparty
236  /// using the default timeout (provided in the constructor).
238  bool isConnectionClosed() const;
239 
240  /// Receives a message.
241  MessageBasePtr receive() const;
242 
243  /// Receives a message using the provided timeout.
244  /// If the operation is timed out, an empty message is returned.
245  MessageBasePtr tryReceive(const Timeout& timeout = defaultTimeout()) const;
246 
247  /// Receives the Negotiate1 message.
248  ///
249  /// \throw std::logic_error if an unexpected type is received.
250  Negotiate1Ptr receiveNegotiate();
251 
252  /// Receives the Negotiate1 and responds with the NegotiateResponse2 message.
253  ///
254  /// \throw std::logic_error if an unexpected type is received.
255  Negotiate1Ptr acceptNegotiate();
256 
257  /// Receives the Negotiate1 message and responds with the NegotiateReject3 message.
258  ///
259  /// \throw std::logic_error if an unexpected type is received.
261 
262  /// Receives the Establish4 message.
263  ///
264  /// \throw std::logic_error if an unexpected type is received.
265  Establish4Ptr receiveEstablish();
266 
267  /// Receive the Establish4 message and respond with the EstablishAck5 message.
268  ///
269  /// \throw std::logic_error if an unexpected type is received.
270  Establish4Ptr acceptEstablish(UInt32 outgoingSequenceNumber = 1, unsigned gatewayKeepAliveInterval = 0);
271 
272  /// Receives the Establish4 message and responds with the EstablishReject6 message.
273  ///
274  /// \throw std::logic_error if an unexpected type is received.
275  Establish4Ptr rejectEstablish(UInt32 outgoingSequenceNumber = 1, EstablishRejectCode::Enum errorCodes = EstablishRejectCode::Enum());
276 
277  /// Receive the Terminate7 message.
278  ///
279  /// \throw std::logic_error if an unexpected type is received.
280  Terminate7Ptr receiveTerminate();
281 
282  /// Receive the Terminate7 message and responds with the Terminate7 message.
283  ///
284  /// \throw std::logic_error if an unexpected type is received.
285  Terminate7Ptr acceptTerminate();
286 
287  /// Sends the Terminate7 message.
288  Gateway& sendTerminate(TerminationCode::Enum errCode = TerminationCode::Finished);
289 
290  /// Sends the Terminate7 message and waits until the response is received.
292 
293  /// Creates a NegotiateResponse2 message
294  NegotiateResponse2Container createNegotiationResponse(const Negotiate1Ptr& request);
295 
296  /// Creates a NegotiateReject3 message.
297  NegotiateReject3Container createNegotiateReject(const Negotiate1Ptr& request, NegotiationRejectCode::Enum errorCodes);
298 
299  /// Creates a EstablishAck5 message.
300  EstablishAck5Container createEstablishmentAck(const Establish4Ptr& request, UInt32 outgoingSequenceNumber, unsigned gatewayKeepAliveInterval = 0);
301 
302  /// Creates a EstablishReject6 message.
303  EstablishReject6Container createEstablishReject(const Establish4Ptr& request, UInt32 outgoingSequenceNumber, EstablishRejectCode::Enum errorCodes);
304 
305  /// Creates a Terminate7 message.
306  Terminate7Container createTerminate(const Terminate7Ptr& request);
307 
308  /// Creates a Terminate7 message.
309  Terminate7Container createTerminate(TerminationCode::Enum errCode);
310 
311  /// Creates a Sequence9 message.
312  Sequence9Container createSequence(UInt32 nextSeqNo);
313 
314  /// Sends the given message.
316 
317  /// Sends the given data
318  Gateway& sendData(const void* data, size_t size);
319 
320  /// Close the listening socket
321  Gateway& close();
322 
323  /// Default timeout
325  {
326  return Timeout(30000);
327  }
328 
329  /// sessionVerId.
330  UInt64 uId_{0};
331 
332  /// sessionId.
334 
335 private:
336 
337  class Impl;
338  Impl* impl_;
339 };
340 
341 
342 template <typename TMsg>
344 {
345  return cast<TMsg>(receive());
346 }
347 
348 template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
350 {
351  const auto messageSize = msg.setHeader();
352  auto* const header = msg.header();
353  assert(header);
354 
355  return send(Messaging::SbeMessage(header + 1, messageSize), *header);
356 }
357 
358 template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
360 {
361  return send(msg);
362 }
363 
364 template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
366 {
367  auto & header = msg->businessHeader();
368  header.setMsgSeqNum(num);
369  return send(msg);
370 }
371 
372 template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
374 {
375  auto & header = msg->businessHeader();
376  header.setMsgSeqNum(num);
377  return send(msg);
378 }
379 
380 template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
382  BOE::Messaging::MessageHolder<SbeMessageType, MaxMessageSize, MessageInitializer>& msg, std::initializer_list<SeqNumber> numbers)
383 {
384  for(auto seqNum : numbers)
385  {
386  send(msg, seqNum);
387  }
388 
389  return *this;
390 }
391 
392 template <typename SbeMessageType, size_t MaxMessageSize, typename MessageInitializer>
394  BOE::Messaging::MessageHolder<SbeMessageType, MaxMessageSize, MessageInitializer>&& msg, std::initializer_list<SeqNumber> numbers)
395 {
396  for(auto seqNum : numbers)
397  {
398  send(msg, seqNum);
399  }
400 
401  return *this;
402 }
403 
404 
405 }}}}
406 
407 
408 #endif
Enum
Identifies the code of reject establishment.
Definition: Fields.h:1236
constexpr UInt16 calculateNegotiateResponse2MaxSize()
Definition: Gateway.h:41
Contains the SimpleOpenFramingHeader, the SBE message, and the data buffer.
SessionID sessionId() const noexcept
Definition: Gateway.h:192
B3 BOE Gateway Emulator.
Definition: Gateway.h:66
Gateway & send(BOE::Messaging::MessageHolder< SbeMessageType, MaxMessageSize, MessageInitializer > &msg)
Sends the given message.
Definition: Gateway.h:349
#define ONIXS_B3_BOE_EXPORTED
Definition: Compiler.h:181
STL namespace.
Enum
Identifies the code of termination.
Definition: Fields.h:1300
Enum
Identifies the code of reject negotiation.
Definition: Fields.h:1178
UInt32 SessionID
Client connection identification on the gateway assigned by B3.
Definition: Fields.h:103
SessionID sessionId_
sessionId.
Definition: Gateway.h:333
Definition: Defines.h:40
#define ONIXS_B3_BOE_NODISCARD
Definition: Compiler.h:191
MessageSize setHeader() noexcept
Calculates the binary size of the message and updates the Simple Open Framing Header accordingly...
MessagePtr< TMsg > receiveTypedMessage()
Receives the message of the particular type.
Definition: Gateway.h:343
Messaging::UInt32 SeqNumber
Definition: Messaging.h:52
The NegotiationResponse message is sent when a Negotiate message from the client is accepted by B3...
Definition: Messages.h:590
std::vector< std::string > LicenseStores
Folders that contain license file(s).
const SimpleOpenFramingHeader * header() const noexcept
static Timeout defaultTimeout()
Default timeout.
Definition: Gateway.h:324
std::chrono::milliseconds Timeout
Timeout alias.
Definition: Gateway.h:70