SessionFactory.cpp
Go to the documentation of this file.
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 {
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  {
97  ( settings.getString( START_TIME ) );
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  SmartPtr<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  {
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->setTimestampPrecision(3);
193  if ( settings.has( TIMESTAMP_PRECISION ) )
194  pSession->setTimestampPrecision(settings.getInt( TIMESTAMP_PRECISION ) );
195  if ( settings.has( PERSIST_MESSAGES ) )
196  pSession->setPersistMessages( settings.getBool( PERSIST_MESSAGES ) );
197  if ( settings.has( VALIDATE_LENGTH_AND_CHECKSUM ) )
198  pSession->setValidateLengthAndChecksum( settings.getBool( VALIDATE_LENGTH_AND_CHECKSUM ) );
199 
200  return pSession.release();
201 }
202 
203 void SessionFactory::destroy( Session* pSession )
204 {
205  delete pSession;
206 }
207 
208 ptr::shared_ptr<DataDictionary> SessionFactory::createDataDictionary(const SessionID& sessionID,
209  const Dictionary& settings,
210  const std::string& settingsKey) throw(ConfigError)
211 {
212  ptr::shared_ptr<DataDictionary> pDD;
213  std::string path = settings.getString( settingsKey );
214  Dictionaries::iterator i = m_dictionaries.find( path );
215  if ( i != m_dictionaries.end() )
216  {
217  pDD = i->second;
218  }
219  else
220  {
221  bool preserveMsgFldsOrder = false;
222  if( settings.has( PRESERVE_MESSAGE_FIELDS_ORDER ) )
223  preserveMsgFldsOrder = settings.getBool( PRESERVE_MESSAGE_FIELDS_ORDER );
224  pDD = ptr::shared_ptr<DataDictionary>(new DataDictionary( path, preserveMsgFldsOrder ));
225  m_dictionaries[ path ] = pDD;
226  }
227 
228  ptr::shared_ptr<DataDictionary> pCopyOfDD = ptr::shared_ptr<DataDictionary>(new DataDictionary(*pDD));
229 
230  if( settings.has( VALIDATE_FIELDS_OUT_OF_ORDER ) )
231  pCopyOfDD->checkFieldsOutOfOrder( settings.getBool( VALIDATE_FIELDS_OUT_OF_ORDER ) );
232  if( settings.has( VALIDATE_FIELDS_HAVE_VALUES ) )
233  pCopyOfDD->checkFieldsHaveValues( settings.getBool( VALIDATE_FIELDS_HAVE_VALUES ) );
234  if( settings.has( VALIDATE_USER_DEFINED_FIELDS ) )
235  pCopyOfDD->checkUserDefinedFields( settings.getBool( VALIDATE_USER_DEFINED_FIELDS ) );
236  if( settings.has( ALLOW_UNKNOWN_MSG_FIELDS ) )
237  pCopyOfDD->allowUnknownMsgFields( settings.getBool( ALLOW_UNKNOWN_MSG_FIELDS ) );
238 
239  return pCopyOfDD;
240 }
241 
242 void SessionFactory::processFixtDataDictionaries(const SessionID& sessionID,
243  const Dictionary& settings,
244  DataDictionaryProvider& provider) throw(ConfigError)
245 {
246  ptr::shared_ptr<DataDictionary> pDataDictionary = createDataDictionary(sessionID, settings, TRANSPORT_DATA_DICTIONARY);
247  provider.addTransportDataDictionary(sessionID.getBeginString(), pDataDictionary);
248 
249  for(Dictionary::const_iterator data = settings.begin(); data != settings.end(); ++data)
250  {
251  const std::string& key = data->first;
252  const std::string frontKey = key.substr(0, strlen(APP_DATA_DICTIONARY));
253  if( frontKey == string_toUpper(APP_DATA_DICTIONARY) )
254  {
255  if( key == string_toUpper(APP_DATA_DICTIONARY) )
256  {
257  provider.addApplicationDataDictionary(Message::toApplVerID(settings.getString(DEFAULT_APPLVERID)),
258  createDataDictionary(sessionID, settings, APP_DATA_DICTIONARY));
259  }
260  else
261  {
262  std::string::size_type offset = key.find('.');
263  if( offset == std::string::npos )
264  throw ConfigError(std::string("Malformed ") + APP_DATA_DICTIONARY + ": " + key);
265  std::string beginStringQualifier = key.substr(offset+1);
266  provider.addApplicationDataDictionary(Message::toApplVerID(beginStringQualifier),
267  createDataDictionary(sessionID, settings, key));
268  }
269  }
270  }
271 }
272 
273 void SessionFactory::processFixDataDictionary(const SessionID& sessionID,
274  const Dictionary& settings,
275  DataDictionaryProvider& provider) throw(ConfigError)
276 {
277  ptr::shared_ptr<DataDictionary> pDataDictionary = createDataDictionary(sessionID, settings, DATA_DICTIONARY);
278  provider.addTransportDataDictionary(sessionID.getBeginString(), pDataDictionary);
279  provider.addApplicationDataDictionary(Message::toApplVerID(sessionID.getBeginString()), pDataDictionary);
280 }
281 }
FIX::SessionFactory::processFixDataDictionary
void processFixDataDictionary(const SessionID &sessionID, const Dictionary &settings, DataDictionaryProvider &provider)
Definition: SessionFactory.cpp:290
FIX::USE_DATA_DICTIONARY
const char USE_DATA_DICTIONARY[]
Definition: SessionSettings.h:60
FIX::RESET_ON_LOGOUT
const char RESET_ON_LOGOUT[]
Definition: SessionSettings.h:143
FIX::RESET_ON_LOGON
const char RESET_ON_LOGON[]
Definition: SessionSettings.h:142
FIX::LOGOUT_TIMEOUT
const char LOGOUT_TIMEOUT[]
Definition: SessionSettings.h:96
FIX::LOGON_TIME
const char LOGON_TIME[]
Definition: SessionSettings.h:71
FIX::Message::toApplVerID
static ApplVerID toApplVerID(const BeginString &value)
Definition: Message.h:324
FIX::LOGON_TIMEOUT
const char LOGON_TIMEOUT[]
Definition: SessionSettings.h:95
FIX::PRESERVE_MESSAGE_FIELDS_ORDER
const char PRESERVE_MESSAGE_FIELDS_ORDER[]
Definition: SessionSettings.h:94
SessionSettings.h
SessionFactory.h
FIX::string_toUpper
std::string string_toUpper(const std::string &value)
Definition: Utility.cpp:70
FIX::PERSIST_MESSAGES
const char PERSIST_MESSAGES[]
Definition: SessionSettings.h:149
FIX::CONNECTION_TYPE
const char CONNECTION_TYPE[]
Definition: SessionSettings.h:59
FIX::SESSION_QUALIFIER
const char SESSION_QUALIFIER[]
Definition: SessionSettings.h:57
FIX::START_DAY
const char START_DAY[]
Definition: SessionSettings.h:69
FIX::VALIDATE_FIELDS_HAVE_VALUES
const char VALIDATE_FIELDS_HAVE_VALUES[]
Definition: SessionSettings.h:91
Values.h
FIX::CHECK_LATENCY
const char CHECK_LATENCY[]
Definition: SessionSettings.h:76
FIX::ConfigError
Application is not configured correctly
Definition: Exceptions.h:104
FIX::SessionFactory::destroy
void destroy(Session *pSession)
Definition: SessionFactory.cpp:220
FIX::VALIDATE_LENGTH_AND_CHECKSUM
const char VALIDATE_LENGTH_AND_CHECKSUM[]
Definition: SessionSettings.h:89
FIX::VALIDATE_USER_DEFINED_FIELDS
const char VALIDATE_USER_DEFINED_FIELDS[]
Definition: SessionSettings.h:92
FIX::SEND_REDUNDANT_RESENDREQUESTS
const char SEND_REDUNDANT_RESENDREQUESTS[]
Definition: SessionSettings.h:62
FIX::MAX_LATENCY
const char MAX_LATENCY[]
Definition: SessionSettings.h:77
FIX::MILLISECONDS_IN_TIMESTAMP
const char MILLISECONDS_IN_TIMESTAMP[]
Definition: SessionSettings.h:146
FIX::LOGOUT_TIME
const char LOGOUT_TIME[]
Definition: SessionSettings.h:72
FIX::END_DAY
const char END_DAY[]
Definition: SessionSettings.h:70
DataDictionaryProvider.h
FIX::TYPE::UtcTimeOnly
@ UtcTimeOnly
Definition: FieldTypes.h:950
FIX::ALLOW_UNKNOWN_MSG_FIELDS
const char ALLOW_UNKNOWN_MSG_FIELDS[]
Definition: SessionSettings.h:93
FIX::SessionFactory::~SessionFactory
~SessionFactory()
Definition: SessionFactory.cpp:54
FIX
Definition: Acceptor.cpp:34
FIX::APP_DATA_DICTIONARY
const char APP_DATA_DICTIONARY[]
Definition: SessionSettings.h:65
FIX::HEARTBTINT
const char HEARTBTINT[]
Definition: SessionSettings.h:78
FIX::CHECK_COMPID
const char CHECK_COMPID[]
Definition: SessionSettings.h:75
FIX::DataDictionary
Represents a data dictionary for a version of FIX.
Definition: DataDictionary.h:66
FIX::END_TIME
const char END_TIME[]
Definition: SessionSettings.h:68
FIX::REFRESH_ON_LOGON
const char REFRESH_ON_LOGON[]
Definition: SessionSettings.h:145
Session.h
FIX::RESET_ON_DISCONNECT
const char RESET_ON_DISCONNECT[]
Definition: SessionSettings.h:144
FIX::TRANSPORT_DATA_DICTIONARY
const char TRANSPORT_DATA_DICTIONARY[]
Definition: SessionSettings.h:64
FIX::DATA_DICTIONARY
const char DATA_DICTIONARY[]
Definition: SessionSettings.h:63
FIX::DEFAULT_APPLVERID
const char DEFAULT_APPLVERID[]
Definition: SessionSettings.h:58
FIX::SessionFactory::processFixtDataDictionaries
void processFixtDataDictionaries(const SessionID &sessionID, const Dictionary &settings, DataDictionaryProvider &provider)
Definition: SessionFactory.cpp:259
FIX::SessionFactory::create
Session * create(const SessionID &sessionID, const Dictionary &settings)
Definition: SessionFactory.cpp:58
FIX::START_TIME
const char START_TIME[]
Definition: SessionSettings.h:67
FIX::LOGON_DAY
const char LOGON_DAY[]
Definition: SessionSettings.h:73
FIX::TIMESTAMP_PRECISION
const char TIMESTAMP_PRECISION[]
Definition: SessionSettings.h:147
FIX::VALIDATE_FIELDS_OUT_OF_ORDER
const char VALIDATE_FIELDS_OUT_OF_ORDER[]
Definition: SessionSettings.h:90
FIX::SessionFactory::createDataDictionary
ptr::shared_ptr< DataDictionary > createDataDictionary(const SessionID &sessionID, const Dictionary &settings, const std::string &settingsKey)
Definition: SessionFactory.cpp:225
Utility.h
FIX::Dictionary::const_iterator
iterator const_iterator
Definition: Dictionary.h:79
FIX::UtcTimeOnlyConvertor::convert
static std::string convert(const UtcTimeOnly &value, int precision=0)
Definition: FieldConvertors.h:565
FIX::USE_LOCAL_TIME
const char USE_LOCAL_TIME[]
Definition: SessionSettings.h:66
FIX::LOGOUT_DAY
const char LOGOUT_DAY[]
Definition: SessionSettings.h:74

Generated on Wed Apr 29 2020 19:41:30 for QuickFIX by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2001