quickfix_ruby 1.14.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +7 -0
  2. data/ext/quickfix/Acceptor.cpp +248 -0
  3. data/ext/quickfix/Acceptor.h +127 -0
  4. data/ext/quickfix/Allocator.h +9 -0
  5. data/ext/quickfix/Application.h +127 -0
  6. data/ext/quickfix/AtomicCount.h +109 -0
  7. data/ext/quickfix/DOMDocument.h +74 -0
  8. data/ext/quickfix/DataDictionary.cpp +618 -0
  9. data/ext/quickfix/DataDictionary.h +539 -0
  10. data/ext/quickfix/DataDictionaryProvider.cpp +71 -0
  11. data/ext/quickfix/DataDictionaryProvider.h +70 -0
  12. data/ext/quickfix/DatabaseConnectionID.h +105 -0
  13. data/ext/quickfix/DatabaseConnectionPool.h +91 -0
  14. data/ext/quickfix/Dictionary.cpp +162 -0
  15. data/ext/quickfix/Dictionary.h +94 -0
  16. data/ext/quickfix/Event.h +95 -0
  17. data/ext/quickfix/Exceptions.h +299 -0
  18. data/ext/quickfix/Field.h +672 -0
  19. data/ext/quickfix/FieldConvertors.h +863 -0
  20. data/ext/quickfix/FieldMap.cpp +238 -0
  21. data/ext/quickfix/FieldMap.h +244 -0
  22. data/ext/quickfix/FieldNumbers.h +46 -0
  23. data/ext/quickfix/FieldTypes.cpp +64 -0
  24. data/ext/quickfix/FieldTypes.h +698 -0
  25. data/ext/quickfix/Fields.h +31 -0
  26. data/ext/quickfix/FileLog.cpp +200 -0
  27. data/ext/quickfix/FileLog.h +112 -0
  28. data/ext/quickfix/FileStore.cpp +332 -0
  29. data/ext/quickfix/FileStore.h +129 -0
  30. data/ext/quickfix/FixFieldNumbers.h +1537 -0
  31. data/ext/quickfix/FixFields.h +1538 -0
  32. data/ext/quickfix/FixValues.h +3281 -0
  33. data/ext/quickfix/FlexLexer.h +188 -0
  34. data/ext/quickfix/Group.cpp +64 -0
  35. data/ext/quickfix/Group.h +73 -0
  36. data/ext/quickfix/HtmlBuilder.h +186 -0
  37. data/ext/quickfix/HttpConnection.cpp +739 -0
  38. data/ext/quickfix/HttpConnection.h +78 -0
  39. data/ext/quickfix/HttpMessage.cpp +149 -0
  40. data/ext/quickfix/HttpMessage.h +133 -0
  41. data/ext/quickfix/HttpParser.cpp +49 -0
  42. data/ext/quickfix/HttpParser.h +54 -0
  43. data/ext/quickfix/HttpServer.cpp +169 -0
  44. data/ext/quickfix/HttpServer.h +78 -0
  45. data/ext/quickfix/Initiator.cpp +289 -0
  46. data/ext/quickfix/Initiator.h +149 -0
  47. data/ext/quickfix/Log.cpp +77 -0
  48. data/ext/quickfix/Log.h +179 -0
  49. data/ext/quickfix/Message.cpp +580 -0
  50. data/ext/quickfix/Message.h +370 -0
  51. data/ext/quickfix/MessageCracker.h +188 -0
  52. data/ext/quickfix/MessageSorters.cpp +105 -0
  53. data/ext/quickfix/MessageSorters.h +156 -0
  54. data/ext/quickfix/MessageStore.cpp +146 -0
  55. data/ext/quickfix/MessageStore.h +174 -0
  56. data/ext/quickfix/Mutex.h +131 -0
  57. data/ext/quickfix/MySQLConnection.h +194 -0
  58. data/ext/quickfix/MySQLLog.cpp +275 -0
  59. data/ext/quickfix/MySQLLog.h +145 -0
  60. data/ext/quickfix/MySQLStore.cpp +331 -0
  61. data/ext/quickfix/MySQLStore.h +142 -0
  62. data/ext/quickfix/NullStore.cpp +54 -0
  63. data/ext/quickfix/NullStore.h +99 -0
  64. data/ext/quickfix/OdbcConnection.h +266 -0
  65. data/ext/quickfix/OdbcLog.cpp +252 -0
  66. data/ext/quickfix/OdbcLog.h +117 -0
  67. data/ext/quickfix/OdbcStore.cpp +338 -0
  68. data/ext/quickfix/OdbcStore.h +113 -0
  69. data/ext/quickfix/PUGIXML_DOMDocument.cpp +112 -0
  70. data/ext/quickfix/PUGIXML_DOMDocument.h +81 -0
  71. data/ext/quickfix/Parser.cpp +103 -0
  72. data/ext/quickfix/Parser.h +57 -0
  73. data/ext/quickfix/PostgreSQLConnection.h +176 -0
  74. data/ext/quickfix/PostgreSQLLog.cpp +276 -0
  75. data/ext/quickfix/PostgreSQLLog.h +144 -0
  76. data/ext/quickfix/PostgreSQLStore.cpp +334 -0
  77. data/ext/quickfix/PostgreSQLStore.h +141 -0
  78. data/ext/quickfix/Queue.h +75 -0
  79. data/ext/quickfix/QuickfixRuby.cpp +252066 -0
  80. data/ext/quickfix/QuickfixRuby.h +34 -0
  81. data/ext/quickfix/Responder.h +43 -0
  82. data/ext/quickfix/Session.cpp +1487 -0
  83. data/ext/quickfix/Session.h +335 -0
  84. data/ext/quickfix/SessionFactory.cpp +274 -0
  85. data/ext/quickfix/SessionFactory.h +86 -0
  86. data/ext/quickfix/SessionID.h +170 -0
  87. data/ext/quickfix/SessionSettings.cpp +189 -0
  88. data/ext/quickfix/SessionSettings.h +171 -0
  89. data/ext/quickfix/SessionState.h +231 -0
  90. data/ext/quickfix/Settings.cpp +100 -0
  91. data/ext/quickfix/Settings.h +53 -0
  92. data/ext/quickfix/SharedArray.h +150 -0
  93. data/ext/quickfix/SocketAcceptor.cpp +222 -0
  94. data/ext/quickfix/SocketAcceptor.h +75 -0
  95. data/ext/quickfix/SocketConnection.cpp +238 -0
  96. data/ext/quickfix/SocketConnection.h +103 -0
  97. data/ext/quickfix/SocketConnector.cpp +116 -0
  98. data/ext/quickfix/SocketConnector.h +67 -0
  99. data/ext/quickfix/SocketInitiator.cpp +260 -0
  100. data/ext/quickfix/SocketInitiator.h +81 -0
  101. data/ext/quickfix/SocketMonitor.cpp +335 -0
  102. data/ext/quickfix/SocketMonitor.h +111 -0
  103. data/ext/quickfix/SocketServer.cpp +177 -0
  104. data/ext/quickfix/SocketServer.h +100 -0
  105. data/ext/quickfix/ThreadedSocketAcceptor.cpp +258 -0
  106. data/ext/quickfix/ThreadedSocketAcceptor.h +98 -0
  107. data/ext/quickfix/ThreadedSocketConnection.cpp +209 -0
  108. data/ext/quickfix/ThreadedSocketConnection.h +82 -0
  109. data/ext/quickfix/ThreadedSocketInitiator.cpp +268 -0
  110. data/ext/quickfix/ThreadedSocketInitiator.h +84 -0
  111. data/ext/quickfix/TimeRange.cpp +173 -0
  112. data/ext/quickfix/TimeRange.h +258 -0
  113. data/ext/quickfix/Utility.cpp +537 -0
  114. data/ext/quickfix/Utility.h +219 -0
  115. data/ext/quickfix/Values.h +62 -0
  116. data/ext/quickfix/config.h +0 -0
  117. data/ext/quickfix/config_windows.h +0 -0
  118. data/ext/quickfix/extconf.rb +12 -0
  119. data/ext/quickfix/index.h +37 -0
  120. data/ext/quickfix/pugiconfig.hpp +72 -0
  121. data/ext/quickfix/pugixml.cpp +10765 -0
  122. data/ext/quickfix/pugixml.hpp +1341 -0
  123. data/ext/quickfix/strptime.h +7 -0
  124. data/lib/quickfix40.rb +274 -0
  125. data/lib/quickfix41.rb +351 -0
  126. data/lib/quickfix42.rb +1184 -0
  127. data/lib/quickfix43.rb +3504 -0
  128. data/lib/quickfix44.rb +10721 -0
  129. data/lib/quickfix50.rb +13426 -0
  130. data/lib/quickfix50sp1.rb +15629 -0
  131. data/lib/quickfix50sp2.rb +17068 -0
  132. data/lib/quickfix_fields.rb +19853 -0
  133. data/lib/quickfix_ruby.rb +82 -0
  134. data/lib/quickfixt11.rb +70 -0
  135. data/spec/FIX40.xml +862 -0
  136. data/spec/FIX41.xml +1285 -0
  137. data/spec/FIX42.xml +2746 -0
  138. data/spec/FIX43.xml +4229 -0
  139. data/spec/FIX44.xml +6596 -0
  140. data/spec/FIX50.xml +8137 -0
  141. data/spec/FIX50SP1.xml +9496 -0
  142. data/spec/FIX50SP2.xml +10011 -0
  143. data/spec/FIXT11.xml +313 -0
  144. data/test/test_DataDictionaryTestCase.rb +268 -0
  145. data/test/test_DictionaryTestCase.rb +112 -0
  146. data/test/test_FieldBaseTestCase.rb +24 -0
  147. data/test/test_MessageTestCase.rb +368 -0
  148. data/test/test_SessionSettingsTestCase.rb +41 -0
  149. metadata +193 -0
@@ -0,0 +1,335 @@
1
+ /* -*- C++ -*- */
2
+
3
+ /****************************************************************************
4
+ ** Copyright (c) 2001-2014
5
+ **
6
+ ** This file is part of the QuickFIX FIX Engine
7
+ **
8
+ ** This file may be distributed under the terms of the quickfixengine.org
9
+ ** license as defined by quickfixengine.org and appearing in the file
10
+ ** LICENSE included in the packaging of this file.
11
+ **
12
+ ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13
+ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14
+ **
15
+ ** See http://www.quickfixengine.org/LICENSE for licensing information.
16
+ **
17
+ ** Contact ask@quickfixengine.org if any conditions of this licensing are
18
+ ** not clear to you.
19
+ **
20
+ ****************************************************************************/
21
+
22
+ #ifndef FIX_SESSION_H
23
+ #define FIX_SESSION_H
24
+
25
+ #ifdef _MSC_VER
26
+ #pragma warning( disable : 4503 4355 4786 4290 )
27
+ #endif
28
+
29
+ #include "SessionState.h"
30
+ #include "TimeRange.h"
31
+ #include "SessionID.h"
32
+ #include "Responder.h"
33
+ #include "Fields.h"
34
+ #include "DataDictionaryProvider.h"
35
+ #include "Application.h"
36
+ #include "Mutex.h"
37
+ #include "Log.h"
38
+ #include <utility>
39
+ #include <map>
40
+ #include <queue>
41
+
42
+ namespace FIX
43
+ {
44
+ /// Maintains the state and implements the logic of a %FIX %session.
45
+ class Session
46
+ {
47
+ public:
48
+ Session( Application&, MessageStoreFactory&,
49
+ const SessionID&,
50
+ const DataDictionaryProvider&,
51
+ const TimeRange&,
52
+ int heartBtInt, LogFactory* pLogFactory );
53
+ virtual ~Session();
54
+
55
+ void logon()
56
+ { m_state.enabled( true ); m_state.logoutReason( "" ); }
57
+ void logout( const std::string& reason = "" )
58
+ { m_state.enabled( false ); m_state.logoutReason( reason ); }
59
+ bool isEnabled()
60
+ { return m_state.enabled(); }
61
+
62
+ bool sentLogon() { return m_state.sentLogon(); }
63
+ bool sentLogout() { return m_state.sentLogout(); }
64
+ bool receivedLogon() { return m_state.receivedLogon(); }
65
+ bool isLoggedOn() { return receivedLogon() && sentLogon(); }
66
+ void reset() throw( IOException )
67
+ { generateLogout(); disconnect(); m_state.reset(); }
68
+ void refresh() throw( IOException )
69
+ { m_state.refresh(); }
70
+ void setNextSenderMsgSeqNum( int num ) throw( IOException )
71
+ { m_state.setNextSenderMsgSeqNum( num ); }
72
+ void setNextTargetMsgSeqNum( int num ) throw( IOException )
73
+ { m_state.setNextTargetMsgSeqNum( num ); }
74
+
75
+ const SessionID& getSessionID() const
76
+ { return m_sessionID; }
77
+ void setDataDictionaryProvider( const DataDictionaryProvider& dataDictionaryProvider )
78
+ { m_dataDictionaryProvider = dataDictionaryProvider; }
79
+ const DataDictionaryProvider& getDataDictionaryProvider() const
80
+ { return m_dataDictionaryProvider; }
81
+
82
+ static bool sendToTarget( Message& message,
83
+ const std::string& qualifier = "" )
84
+ throw( SessionNotFound );
85
+ static bool sendToTarget( Message& message, const SessionID& sessionID )
86
+ throw( SessionNotFound );
87
+ static bool sendToTarget( Message&,
88
+ const SenderCompID& senderCompID,
89
+ const TargetCompID& targetCompID,
90
+ const std::string& qualifier = "" )
91
+ throw( SessionNotFound );
92
+ static bool sendToTarget( Message& message,
93
+ const std::string& senderCompID,
94
+ const std::string& targetCompID,
95
+ const std::string& qualifier = "" )
96
+ throw( SessionNotFound );
97
+
98
+ static std::set<SessionID> getSessions();
99
+ static bool doesSessionExist( const SessionID& );
100
+ static Session* lookupSession( const SessionID& );
101
+ static Session* lookupSession( const std::string&, bool reverse = false );
102
+ static bool isSessionRegistered( const SessionID& );
103
+ static Session* registerSession( const SessionID& );
104
+ static void unregisterSession( const SessionID& );
105
+
106
+ static size_t numSessions();
107
+
108
+ bool isSessionTime(const UtcTimeStamp& time)
109
+ { return m_sessionTime.isInRange(time); }
110
+ bool isLogonTime(const UtcTimeStamp& time)
111
+ { return m_logonTime.isInRange(time); }
112
+ bool isInitiator()
113
+ { return m_state.initiate(); }
114
+ bool isAcceptor()
115
+ { return !m_state.initiate(); }
116
+
117
+ const TimeRange& getLogonTime()
118
+ { return m_logonTime; }
119
+ void setLogonTime( const TimeRange& value )
120
+ { m_logonTime = value; }
121
+
122
+ const std::string& getSenderDefaultApplVerID()
123
+ { return m_senderDefaultApplVerID; }
124
+ void setSenderDefaultApplVerID( const std::string& senderDefaultApplVerID )
125
+ { m_senderDefaultApplVerID = senderDefaultApplVerID; }
126
+
127
+ const std::string& getTargetDefaultApplVerID()
128
+ { return m_targetDefaultApplVerID; }
129
+ void setTargetDefaultApplVerID( const std::string& targetDefaultApplVerID )
130
+ { m_targetDefaultApplVerID = targetDefaultApplVerID; }
131
+
132
+ bool getSendRedundantResendRequests()
133
+ { return m_sendRedundantResendRequests; }
134
+ void setSendRedundantResendRequests ( bool value )
135
+ { m_sendRedundantResendRequests = value; }
136
+
137
+ bool getCheckCompId()
138
+ { return m_checkCompId; }
139
+ void setCheckCompId ( bool value )
140
+ { m_checkCompId = value; }
141
+
142
+ bool getCheckLatency()
143
+ { return m_checkLatency; }
144
+ void setCheckLatency ( bool value )
145
+ { m_checkLatency = value; }
146
+
147
+ int getMaxLatency()
148
+ { return m_maxLatency; }
149
+ void setMaxLatency ( int value )
150
+ { m_maxLatency = value; }
151
+
152
+ int getLogonTimeout()
153
+ { return m_state.logonTimeout(); }
154
+ void setLogonTimeout ( int value )
155
+ { m_state.logonTimeout( value ); }
156
+
157
+ int getLogoutTimeout()
158
+ { return m_state.logoutTimeout(); }
159
+ void setLogoutTimeout ( int value )
160
+ { m_state.logoutTimeout( value ); }
161
+
162
+ bool getResetOnLogon()
163
+ { return m_resetOnLogon; }
164
+ void setResetOnLogon ( bool value )
165
+ { m_resetOnLogon = value; }
166
+
167
+ bool getResetOnLogout()
168
+ { return m_resetOnLogout; }
169
+ void setResetOnLogout ( bool value )
170
+ { m_resetOnLogout = value; }
171
+
172
+ bool getResetOnDisconnect()
173
+ { return m_resetOnDisconnect; }
174
+ void setResetOnDisconnect( bool value )
175
+ { m_resetOnDisconnect = value; }
176
+
177
+ bool getRefreshOnLogon()
178
+ { return m_refreshOnLogon; }
179
+ void setRefreshOnLogon( bool value )
180
+ { m_refreshOnLogon = value; }
181
+
182
+ bool getMillisecondsInTimeStamp()
183
+ { return m_millisecondsInTimeStamp; }
184
+ void setMillisecondsInTimeStamp ( bool value )
185
+ { m_millisecondsInTimeStamp = value; }
186
+
187
+ bool getPersistMessages()
188
+ { return m_persistMessages; }
189
+ void setPersistMessages ( bool value )
190
+ { m_persistMessages = value; }
191
+
192
+ bool getValidateLengthAndChecksum()
193
+ { return m_validateLengthAndChecksum; }
194
+ void setValidateLengthAndChecksum ( bool value )
195
+ { m_validateLengthAndChecksum = value; }
196
+
197
+ void setResponder( Responder* pR )
198
+ {
199
+ if( !checkSessionTime(UtcTimeStamp()) )
200
+ reset();
201
+ m_pResponder = pR;
202
+ }
203
+
204
+ bool send( Message& );
205
+ void next();
206
+ void next( const UtcTimeStamp& timeStamp );
207
+ void next( const std::string&, const UtcTimeStamp& timeStamp, bool queued = false );
208
+ void next( const Message&, const UtcTimeStamp& timeStamp, bool queued = false );
209
+ void disconnect();
210
+
211
+ int getExpectedSenderNum() { return m_state.getNextSenderMsgSeqNum(); }
212
+ int getExpectedTargetNum() { return m_state.getNextTargetMsgSeqNum(); }
213
+
214
+ Log* getLog() { return &m_state; }
215
+ const MessageStore* getStore() { return &m_state; }
216
+
217
+ private:
218
+ typedef std::map < SessionID, Session* > Sessions;
219
+ typedef std::set < SessionID > SessionIDs;
220
+
221
+ static bool addSession( Session& );
222
+ static void removeSession( Session& );
223
+
224
+ bool send( const std::string& );
225
+ bool sendRaw( Message&, int msgSeqNum = 0 );
226
+ bool resend( Message& message );
227
+ void persist( const Message&, const std::string& ) throw ( IOException );
228
+
229
+ void insertSendingTime( Header& );
230
+ void insertOrigSendingTime( Header&,
231
+ const UtcTimeStamp& when = UtcTimeStamp () );
232
+ void fill( Header& );
233
+
234
+ bool isGoodTime( const SendingTime& sendingTime )
235
+ {
236
+ if ( !m_checkLatency ) return true;
237
+ UtcTimeStamp now;
238
+ return labs( now - sendingTime ) <= m_maxLatency;
239
+ }
240
+ bool checkSessionTime( const UtcTimeStamp& timeStamp )
241
+ {
242
+ UtcTimeStamp creationTime = m_state.getCreationTime();
243
+ return m_sessionTime.isInSameRange( timeStamp, creationTime );
244
+ }
245
+ bool isTargetTooHigh( const MsgSeqNum& msgSeqNum )
246
+ { return msgSeqNum > ( m_state.getNextTargetMsgSeqNum() ); }
247
+ bool isTargetTooLow( const MsgSeqNum& msgSeqNum )
248
+ { return msgSeqNum < ( m_state.getNextTargetMsgSeqNum() ); }
249
+ bool isCorrectCompID( const SenderCompID& senderCompID,
250
+ const TargetCompID& targetCompID )
251
+ {
252
+ if( !m_checkCompId ) return true;
253
+
254
+ return
255
+ m_sessionID.getSenderCompID().getValue() == targetCompID.getValue()
256
+ && m_sessionID.getTargetCompID().getValue() == senderCompID.getValue();
257
+ }
258
+ bool shouldSendReset();
259
+
260
+ bool validLogonState( const MsgType& msgType );
261
+ void fromCallback( const MsgType& msgType, const Message& msg,
262
+ const SessionID& sessionID );
263
+
264
+ void doBadTime( const Message& msg );
265
+ void doBadCompID( const Message& msg );
266
+ bool doPossDup( const Message& msg );
267
+ bool doTargetTooLow( const Message& msg );
268
+ void doTargetTooHigh( const Message& msg );
269
+ void nextQueued( const UtcTimeStamp& timeStamp );
270
+ bool nextQueued( int num, const UtcTimeStamp& timeStamp );
271
+
272
+ void nextLogon( const Message&, const UtcTimeStamp& timeStamp );
273
+ void nextHeartbeat( const Message&, const UtcTimeStamp& timeStamp );
274
+ void nextTestRequest( const Message&, const UtcTimeStamp& timeStamp );
275
+ void nextLogout( const Message&, const UtcTimeStamp& timeStamp );
276
+ void nextReject( const Message&, const UtcTimeStamp& timeStamp );
277
+ void nextSequenceReset( const Message&, const UtcTimeStamp& timeStamp );
278
+ void nextResendRequest( const Message&, const UtcTimeStamp& timeStamp );
279
+
280
+ void generateLogon();
281
+ void generateLogon( const Message& );
282
+ void generateResendRequest( const BeginString&, const MsgSeqNum& );
283
+ void generateSequenceReset( int, int );
284
+ void generateHeartbeat();
285
+ void generateHeartbeat( const Message& );
286
+ void generateTestRequest( const std::string& );
287
+ void generateReject( const Message&, int err, int field = 0 );
288
+ void generateReject( const Message&, const std::string& );
289
+ void generateBusinessReject( const Message&, int err, int field = 0 );
290
+ void generateLogout( const std::string& text = "" );
291
+
292
+ void populateRejectReason( Message&, int field, const std::string& );
293
+ void populateRejectReason( Message&, const std::string& );
294
+
295
+ bool verify( const Message& msg,
296
+ bool checkTooHigh = true, bool checkTooLow = true );
297
+
298
+ bool set( int s, const Message& m );
299
+ bool get( int s, Message& m ) const;
300
+
301
+ Application& m_application;
302
+ SessionID m_sessionID;
303
+ TimeRange m_sessionTime;
304
+ TimeRange m_logonTime;
305
+
306
+ std::string m_senderDefaultApplVerID;
307
+ std::string m_targetDefaultApplVerID;
308
+ bool m_sendRedundantResendRequests;
309
+ bool m_checkCompId;
310
+ bool m_checkLatency;
311
+ int m_maxLatency;
312
+ bool m_resetOnLogon;
313
+ bool m_resetOnLogout;
314
+ bool m_resetOnDisconnect;
315
+ bool m_refreshOnLogon;
316
+ bool m_millisecondsInTimeStamp;
317
+ bool m_persistMessages;
318
+ bool m_validateLengthAndChecksum;
319
+
320
+ SessionState m_state;
321
+ DataDictionaryProvider m_dataDictionaryProvider;
322
+ MessageStoreFactory& m_messageStoreFactory;
323
+ LogFactory* m_pLogFactory;
324
+ Responder* m_pResponder;
325
+ Mutex m_mutex;
326
+
327
+ static Sessions s_sessions;
328
+ static SessionIDs s_sessionIDs;
329
+ static Sessions s_registered;
330
+ static Mutex s_mutex;
331
+
332
+ };
333
+ }
334
+
335
+ #endif //FIX_SESSION_H
@@ -0,0 +1,274 @@
1
+ /****************************************************************************
2
+ ** Copyright (c) 2001-2014
3
+ **
4
+ ** This file is part of the QuickFIX FIX Engine
5
+ **
6
+ ** This file may be distributed under the terms of the quickfixengine.org
7
+ ** license as defined by quickfixengine.org and appearing in the file
8
+ ** LICENSE included in the packaging of this file.
9
+ **
10
+ ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11
+ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12
+ **
13
+ ** See http://www.quickfixengine.org/LICENSE for licensing information.
14
+ **
15
+ ** Contact ask@quickfixengine.org if any conditions of this licensing are
16
+ ** not clear to you.
17
+ **
18
+ ****************************************************************************/
19
+
20
+ #ifdef _MSC_VER
21
+ #include "stdafx.h"
22
+ #else
23
+ #include "config.h"
24
+ #endif
25
+
26
+ #include "Utility.h"
27
+ #include "Values.h"
28
+ #include "DataDictionaryProvider.h"
29
+ #include "SessionFactory.h"
30
+ #include "SessionSettings.h"
31
+ #include "Session.h"
32
+
33
+ #include <memory>
34
+
35
+ namespace FIX
36
+ {
37
+ SessionFactory::~SessionFactory()
38
+ {
39
+ }
40
+
41
+ Session* SessionFactory::create( const SessionID& sessionID,
42
+ const Dictionary& settings ) throw( ConfigError )
43
+ {
44
+ std::string connectionType = settings.getString( CONNECTION_TYPE );
45
+ if ( connectionType != "acceptor" && connectionType != "initiator" )
46
+ throw ConfigError( "Invalid ConnectionType" );
47
+
48
+ if( connectionType == "acceptor" && settings.has(SESSION_QUALIFIER) )
49
+ throw ConfigError( "SessionQualifier cannot be used with acceptor." );
50
+
51
+ bool useDataDictionary = true;
52
+ if ( settings.has( USE_DATA_DICTIONARY ) )
53
+ useDataDictionary = settings.getBool( USE_DATA_DICTIONARY );
54
+
55
+ std::string defaultApplVerID;
56
+ if( sessionID.isFIXT() )
57
+ {
58
+ if( !settings.has(DEFAULT_APPLVERID) )
59
+ {
60
+ throw ConfigError("ApplVerID is required for FIXT transport");
61
+ }
62
+ defaultApplVerID = Message::toApplVerID( settings.getString(DEFAULT_APPLVERID) );
63
+ }
64
+
65
+ DataDictionaryProvider dataDictionaryProvider;
66
+ if( useDataDictionary )
67
+ {
68
+ if( sessionID.isFIXT() )
69
+ {
70
+ processFixtDataDictionaries(sessionID, settings, dataDictionaryProvider);
71
+ }
72
+ else
73
+ {
74
+ processFixDataDictionary(sessionID, settings, dataDictionaryProvider);
75
+ }
76
+ }
77
+
78
+ bool useLocalTime = false;
79
+ if( settings.has(USE_LOCAL_TIME) )
80
+ useLocalTime = settings.getBool( USE_LOCAL_TIME );
81
+
82
+ int startDay = -1;
83
+ int endDay = -1;
84
+ try
85
+ {
86
+ startDay = settings.getDay( START_DAY );
87
+ endDay = settings.getDay( END_DAY );
88
+ }
89
+ catch( ConfigError & ) {}
90
+ catch( FieldConvertError & e ) { throw ConfigError( e.what() ); }
91
+
92
+ UtcTimeOnly startTime;
93
+ UtcTimeOnly endTime;
94
+ try
95
+ {
96
+ startTime = UtcTimeOnlyConvertor::convert
97
+ ( settings.getString( START_TIME ) );
98
+ endTime = UtcTimeOnlyConvertor::convert
99
+ ( settings.getString( END_TIME ) );
100
+ }
101
+ catch ( FieldConvertError & e ) { throw ConfigError( e.what() ); }
102
+
103
+ TimeRange utcSessionTime
104
+ ( startTime, endTime, startDay, endDay );
105
+ TimeRange localSessionTime
106
+ ( LocalTimeOnly(startTime.getHour(), startTime.getMinute(), startTime.getSecond()),
107
+ LocalTimeOnly(endTime.getHour(), endTime.getMinute(), endTime.getSecond()),
108
+ startDay, endDay );
109
+ TimeRange sessionTimeRange = useLocalTime ? localSessionTime : utcSessionTime;
110
+
111
+ if( startDay >= 0 && endDay < 0 )
112
+ throw ConfigError( "StartDay used without EndDay" );
113
+ if( endDay >= 0 && startDay < 0 )
114
+ throw ConfigError( "EndDay used without StartDay" );
115
+
116
+ HeartBtInt heartBtInt( 0 );
117
+ if ( connectionType == "initiator" )
118
+ {
119
+ heartBtInt = HeartBtInt( settings.getInt( HEARTBTINT ) );
120
+ if ( heartBtInt <= 0 ) throw ConfigError( "Heartbeat must be greater than zero" );
121
+ }
122
+
123
+ std::auto_ptr<Session> pSession;
124
+ pSession.reset( new Session( m_application, m_messageStoreFactory,
125
+ sessionID, dataDictionaryProvider, sessionTimeRange,
126
+ heartBtInt, m_pLogFactory ) );
127
+
128
+ pSession->setSenderDefaultApplVerID(defaultApplVerID);
129
+
130
+ int logonDay = startDay;
131
+ int logoutDay = endDay;
132
+ try
133
+ {
134
+ logonDay = settings.getDay( LOGON_DAY );
135
+ logoutDay = settings.getDay( LOGOUT_DAY );
136
+ }
137
+ catch( ConfigError & ) {}
138
+ catch( FieldConvertError & e ) { throw ConfigError( e.what() ); }
139
+
140
+ UtcTimeOnly logonTime( startTime );
141
+ UtcTimeOnly logoutTime( endTime );
142
+ try
143
+ {
144
+ logonTime = UtcTimeOnlyConvertor::convert
145
+ ( settings.getString( LOGON_TIME ) );
146
+ }
147
+ catch( ConfigError & ) {}
148
+ catch( FieldConvertError & e ) { throw ConfigError( e.what() ); }
149
+ try
150
+ {
151
+ logoutTime = UtcTimeOnlyConvertor::convert
152
+ ( settings.getString( LOGOUT_TIME ) );
153
+ }
154
+ catch( ConfigError & ) {}
155
+ catch( FieldConvertError & e ) { throw ConfigError( e.what() ); }
156
+
157
+ TimeRange utcLogonTime
158
+ ( logonTime, logoutTime, logonDay, logoutDay );
159
+ TimeRange localLogonTime
160
+ ( LocalTimeOnly(logonTime.getHour(), logonTime.getMinute(), logonTime.getSecond()),
161
+ LocalTimeOnly(logoutTime.getHour(), logoutTime.getMinute(), logoutTime.getSecond()),
162
+ logonDay, logoutDay );
163
+ TimeRange logonTimeRange = useLocalTime ? localLogonTime : utcLogonTime;
164
+
165
+ if( !sessionTimeRange.isInRange(logonTime, logonDay) )
166
+ throw ConfigError( "LogonTime must be between StartTime and EndTime" );
167
+ if( !sessionTimeRange.isInRange(logoutTime, logoutDay) )
168
+ throw ConfigError( "LogoutTime must be between StartTime and EndTime" );
169
+ pSession->setLogonTime( logonTimeRange );
170
+
171
+ if ( settings.has( SEND_REDUNDANT_RESENDREQUESTS ) )
172
+ pSession->setSendRedundantResendRequests( settings.getBool( SEND_REDUNDANT_RESENDREQUESTS ) );
173
+ if ( settings.has( CHECK_COMPID ) )
174
+ pSession->setCheckCompId( settings.getBool( CHECK_COMPID ) );
175
+ if ( settings.has( CHECK_LATENCY ) )
176
+ pSession->setCheckLatency( settings.getBool( CHECK_LATENCY ) );
177
+ if ( settings.has( MAX_LATENCY ) )
178
+ pSession->setMaxLatency( settings.getInt( MAX_LATENCY ) );
179
+ if ( settings.has( LOGON_TIMEOUT ) )
180
+ pSession->setLogonTimeout( settings.getInt( LOGON_TIMEOUT ) );
181
+ if ( settings.has( LOGOUT_TIMEOUT ) )
182
+ pSession->setLogoutTimeout( settings.getInt( LOGOUT_TIMEOUT ) );
183
+ if ( settings.has( RESET_ON_LOGON ) )
184
+ pSession->setResetOnLogon( settings.getBool( RESET_ON_LOGON ) );
185
+ if ( settings.has( RESET_ON_LOGOUT ) )
186
+ pSession->setResetOnLogout( settings.getBool( RESET_ON_LOGOUT ) );
187
+ if ( settings.has( RESET_ON_DISCONNECT ) )
188
+ pSession->setResetOnDisconnect( settings.getBool( RESET_ON_DISCONNECT ) );
189
+ if ( settings.has( REFRESH_ON_LOGON ) )
190
+ pSession->setRefreshOnLogon( settings.getBool( REFRESH_ON_LOGON ) );
191
+ if ( settings.has( MILLISECONDS_IN_TIMESTAMP ) )
192
+ pSession->setMillisecondsInTimeStamp( settings.getBool( MILLISECONDS_IN_TIMESTAMP ) );
193
+ if ( settings.has( PERSIST_MESSAGES ) )
194
+ pSession->setPersistMessages( settings.getBool( PERSIST_MESSAGES ) );
195
+ if ( settings.has( VALIDATE_LENGTH_AND_CHECKSUM ) )
196
+ pSession->setValidateLengthAndChecksum( settings.getBool( VALIDATE_LENGTH_AND_CHECKSUM ) );
197
+
198
+ return pSession.release();
199
+ }
200
+
201
+ void SessionFactory::destroy( Session* pSession )
202
+ {
203
+ delete pSession;
204
+ }
205
+
206
+ ptr::shared_ptr<DataDictionary> SessionFactory::createDataDictionary(const SessionID& sessionID,
207
+ const Dictionary& settings,
208
+ const std::string& settingsKey) throw(ConfigError)
209
+ {
210
+ ptr::shared_ptr<DataDictionary> pDD;
211
+ std::string path = settings.getString( settingsKey );
212
+ Dictionaries::iterator i = m_dictionaries.find( path );
213
+ if ( i != m_dictionaries.end() )
214
+ {
215
+ pDD = i->second;
216
+ }
217
+ else
218
+ {
219
+ pDD = ptr::shared_ptr<DataDictionary>(new DataDictionary( path ));
220
+ m_dictionaries[ path ] = pDD;
221
+ }
222
+
223
+ ptr::shared_ptr<DataDictionary> pCopyOfDD = ptr::shared_ptr<DataDictionary>(new DataDictionary(*pDD));
224
+
225
+ if( settings.has( VALIDATE_FIELDS_OUT_OF_ORDER ) )
226
+ pCopyOfDD->checkFieldsOutOfOrder( settings.getBool( VALIDATE_FIELDS_OUT_OF_ORDER ) );
227
+ if( settings.has( VALIDATE_FIELDS_HAVE_VALUES ) )
228
+ pCopyOfDD->checkFieldsHaveValues( settings.getBool( VALIDATE_FIELDS_HAVE_VALUES ) );
229
+ if( settings.has( VALIDATE_USER_DEFINED_FIELDS ) )
230
+ pCopyOfDD->checkUserDefinedFields( settings.getBool( VALIDATE_USER_DEFINED_FIELDS ) );
231
+
232
+ return pCopyOfDD;
233
+ }
234
+
235
+ void SessionFactory::processFixtDataDictionaries(const SessionID& sessionID,
236
+ const Dictionary& settings,
237
+ DataDictionaryProvider& provider) throw(ConfigError)
238
+ {
239
+ ptr::shared_ptr<DataDictionary> pDataDictionary = createDataDictionary(sessionID, settings, TRANSPORT_DATA_DICTIONARY);
240
+ provider.addTransportDataDictionary(sessionID.getBeginString(), pDataDictionary);
241
+
242
+ for(Dictionary::const_iterator data = settings.begin(); data != settings.end(); ++data)
243
+ {
244
+ const std::string& key = data->first;
245
+ const std::string frontKey = key.substr(0, strlen(APP_DATA_DICTIONARY));
246
+ if( frontKey == string_toUpper(APP_DATA_DICTIONARY) )
247
+ {
248
+ if( key == string_toUpper(APP_DATA_DICTIONARY) )
249
+ {
250
+ provider.addApplicationDataDictionary(Message::toApplVerID(settings.getString(DEFAULT_APPLVERID)),
251
+ createDataDictionary(sessionID, settings, APP_DATA_DICTIONARY));
252
+ }
253
+ else
254
+ {
255
+ std::string::size_type offset = key.find('.');
256
+ if( offset == std::string::npos )
257
+ throw ConfigError(std::string("Malformed ") + APP_DATA_DICTIONARY + ": " + key);
258
+ std::string beginStringQualifier = key.substr(offset+1);
259
+ provider.addApplicationDataDictionary(Message::toApplVerID(beginStringQualifier),
260
+ createDataDictionary(sessionID, settings, key));
261
+ }
262
+ }
263
+ }
264
+ }
265
+
266
+ void SessionFactory::processFixDataDictionary(const SessionID& sessionID,
267
+ const Dictionary& settings,
268
+ DataDictionaryProvider& provider) throw(ConfigError)
269
+ {
270
+ ptr::shared_ptr<DataDictionary> pDataDictionary = createDataDictionary(sessionID, settings, DATA_DICTIONARY);
271
+ provider.addTransportDataDictionary(sessionID.getBeginString(), pDataDictionary);
272
+ provider.addApplicationDataDictionary(Message::toApplVerID(sessionID.getBeginString()), pDataDictionary);
273
+ }
274
+ }
@@ -0,0 +1,86 @@
1
+ /* -*- C++ -*- */
2
+
3
+ /****************************************************************************
4
+ ** Copyright (c) 2001-2014
5
+ **
6
+ ** This file is part of the QuickFIX FIX Engine
7
+ **
8
+ ** This file may be distributed under the terms of the quickfixengine.org
9
+ ** license as defined by quickfixengine.org and appearing in the file
10
+ ** LICENSE included in the packaging of this file.
11
+ **
12
+ ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13
+ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14
+ **
15
+ ** See http://www.quickfixengine.org/LICENSE for licensing information.
16
+ **
17
+ ** Contact ask@quickfixengine.org if any conditions of this licensing are
18
+ ** not clear to you.
19
+ **
20
+ ****************************************************************************/
21
+
22
+ #ifndef FIX_SESSIONFACTORY_H
23
+ #define FIX_SESSIONFACTORY_H
24
+
25
+ #ifdef _MSC_VER
26
+ #pragma warning( disable : 4503 4355 4786 4290 )
27
+ #endif
28
+
29
+ #include "Log.h"
30
+ #include "Exceptions.h"
31
+ #include "Dictionary.h"
32
+
33
+ namespace FIX
34
+ {
35
+ class SessionID;
36
+ class Session;
37
+ class Application;
38
+ class MessageStoreFactory;
39
+ class DataDictionaryProvider;
40
+
41
+ /** Responsible for creating Session objects. This factory will use
42
+ * QuickFIX SessionID, Dictionary settings, MessageStoreFactory, and
43
+ * optional LogFactory to create all the required sessions for an
44
+ * Application.
45
+ */
46
+ class SessionFactory
47
+ {
48
+ public:
49
+ SessionFactory( Application& application,
50
+ MessageStoreFactory& messageStoreFactory,
51
+ LogFactory* pLogFactory )
52
+ : m_application( application ),
53
+ m_messageStoreFactory( messageStoreFactory ),
54
+ m_pLogFactory( pLogFactory ) {}
55
+
56
+ ~SessionFactory();
57
+
58
+ Session* create( const SessionID& sessionID,
59
+ const Dictionary& settings ) throw( ConfigError );
60
+ void destroy( Session* pSession );
61
+
62
+ private:
63
+ typedef std::map < std::string, ptr::shared_ptr<DataDictionary> > Dictionaries;
64
+
65
+ ptr::shared_ptr<DataDictionary> createDataDictionary(const SessionID& sessionID,
66
+ const Dictionary& settings,
67
+ const std::string& settingsKey) throw(ConfigError);
68
+
69
+ void processFixtDataDictionaries(const SessionID& sessionID,
70
+ const Dictionary& settings,
71
+ DataDictionaryProvider& provider) throw(ConfigError);
72
+
73
+ void processFixDataDictionary(const SessionID& sessionID,
74
+ const Dictionary& settings,
75
+ DataDictionaryProvider& provider) throw(ConfigError);
76
+
77
+ std::string toApplVerID(const std::string& value);
78
+
79
+ Application& m_application;
80
+ MessageStoreFactory& m_messageStoreFactory;
81
+ LogFactory* m_pLogFactory;
82
+ Dictionaries m_dictionaries;
83
+ };
84
+ }
85
+
86
+ #endif