SessionFactory.cpp
Go to the documentation of this file.
/****************************************************************************
** Copyright (c) 2001-2014
**
** This file is part of the QuickFIX FIX Engine
**
** This file may be distributed under the terms of the quickfixengine.org
** license as defined by quickfixengine.org and appearing in the file
** LICENSE included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.quickfixengine.org/LICENSE for licensing information.
**
** Contact ask@quickfixengine.org if any conditions of this licensing are
** not clear to you.
**
****************************************************************************/
#ifdef _MSC_VER
#include "stdafx.h"
#else
#include "config.h"
#endif
#include "Utility.h"
#include "Values.h"
#include "DataDictionaryProvider.h"
#include "SessionFactory.h"
#include "SessionSettings.h"
#include "Session.h"
#include <memory>
namespace FIX
{
SessionFactory::~SessionFactory()
{
}
Session* SessionFactory::create( const SessionID& sessionID,
const Dictionary& settings ) throw( ConfigError )
{
std::string connectionType = settings.getString( CONNECTION_TYPE );
if ( connectionType != "acceptor" && connectionType != "initiator" )
throw ConfigError( "Invalid ConnectionType" );
if( connectionType == "acceptor" && settings.has(SESSION_QUALIFIER) )
throw ConfigError( "SessionQualifier cannot be used with acceptor." );
bool useDataDictionary = true;
if ( settings.has( USE_DATA_DICTIONARY ) )
useDataDictionary = settings.getBool( USE_DATA_DICTIONARY );
std::string defaultApplVerID;
if( sessionID.isFIXT() )
{
if( !settings.has(DEFAULT_APPLVERID) )
{
throw ConfigError("ApplVerID is required for FIXT transport");
}
defaultApplVerID = Message::toApplVerID( settings.getString(DEFAULT_APPLVERID) );
}
DataDictionaryProvider dataDictionaryProvider;
if( useDataDictionary )
{
if( sessionID.isFIXT() )
{
processFixtDataDictionaries(sessionID, settings, dataDictionaryProvider);
}
else
{
processFixDataDictionary(sessionID, settings, dataDictionaryProvider);
}
}
bool useLocalTime = false;
if( settings.has(USE_LOCAL_TIME) )
useLocalTime = settings.getBool( USE_LOCAL_TIME );
int startDay = -1;
int endDay = -1;
try
{
startDay = settings.getDay( START_DAY );
endDay = settings.getDay( END_DAY );
}
catch( ConfigError & ) {}
catch( FieldConvertError & e ) { throw ConfigError( e.what() ); }
UtcTimeOnly startTime;
UtcTimeOnly endTime;
try
{
startTime = UtcTimeOnlyConvertor::convert
( settings.getString( START_TIME ) );
endTime = UtcTimeOnlyConvertor::convert
( settings.getString( END_TIME ) );
}
catch ( FieldConvertError & e ) { throw ConfigError( e.what() ); }
TimeRange utcSessionTime
( startTime, endTime, startDay, endDay );
TimeRange localSessionTime
( LocalTimeOnly(startTime.getHour(), startTime.getMinute(), startTime.getSecond()),
LocalTimeOnly(endTime.getHour(), endTime.getMinute(), endTime.getSecond()),
startDay, endDay );
TimeRange sessionTimeRange = useLocalTime ? localSessionTime : utcSessionTime;
if( startDay >= 0 && endDay < 0 )
throw ConfigError( "StartDay used without EndDay" );
if( endDay >= 0 && startDay < 0 )
throw ConfigError( "EndDay used without StartDay" );
HeartBtInt heartBtInt( 0 );
if ( connectionType == "initiator" )
{
heartBtInt = HeartBtInt( settings.getInt( HEARTBTINT ) );
if ( heartBtInt <= 0 ) throw ConfigError( "Heartbeat must be greater than zero" );
}
SmartPtr<Session> pSession;
pSession.reset( new Session( m_application, m_messageStoreFactory,
sessionID, dataDictionaryProvider, sessionTimeRange,
heartBtInt, m_pLogFactory ) );
pSession->setSenderDefaultApplVerID(defaultApplVerID);
int logonDay = startDay;
int logoutDay = endDay;
try
{
logonDay = settings.getDay( LOGON_DAY );
logoutDay = settings.getDay( LOGOUT_DAY );
}
catch( ConfigError & ) {}
catch( FieldConvertError & e ) { throw ConfigError( e.what() ); }
UtcTimeOnly logonTime( startTime );
UtcTimeOnly logoutTime( endTime );
try
{
logonTime = UtcTimeOnlyConvertor::convert
( settings.getString( LOGON_TIME ) );
}
catch( ConfigError & ) {}
catch( FieldConvertError & e ) { throw ConfigError( e.what() ); }
try
{
logoutTime = UtcTimeOnlyConvertor::convert
( settings.getString( LOGOUT_TIME ) );
}
catch( ConfigError & ) {}
catch( FieldConvertError & e ) { throw ConfigError( e.what() ); }
TimeRange utcLogonTime
( logonTime, logoutTime, logonDay, logoutDay );
TimeRange localLogonTime
( LocalTimeOnly(logonTime.getHour(), logonTime.getMinute(), logonTime.getSecond()),
LocalTimeOnly(logoutTime.getHour(), logoutTime.getMinute(), logoutTime.getSecond()),
logonDay, logoutDay );
TimeRange logonTimeRange = useLocalTime ? localLogonTime : utcLogonTime;
if( !sessionTimeRange.isInRange(logonTime, logonDay) )
throw ConfigError( "LogonTime must be between StartTime and EndTime" );
if( !sessionTimeRange.isInRange(logoutTime, logoutDay) )
throw ConfigError( "LogoutTime must be between StartTime and EndTime" );
pSession->setLogonTime( logonTimeRange );
if ( settings.has( SEND_REDUNDANT_RESENDREQUESTS ) )
pSession->setSendRedundantResendRequests( settings.getBool( SEND_REDUNDANT_RESENDREQUESTS ) );
if ( settings.has( CHECK_COMPID ) )
pSession->setCheckCompId( settings.getBool( CHECK_COMPID ) );
if ( settings.has( CHECK_LATENCY ) )
pSession->setCheckLatency( settings.getBool( CHECK_LATENCY ) );
if ( settings.has( MAX_LATENCY ) )
pSession->setMaxLatency( settings.getInt( MAX_LATENCY ) );
if ( settings.has( LOGON_TIMEOUT ) )
pSession->setLogonTimeout( settings.getInt( LOGON_TIMEOUT ) );
if ( settings.has( LOGOUT_TIMEOUT ) )
pSession->setLogoutTimeout( settings.getInt( LOGOUT_TIMEOUT ) );
if ( settings.has( RESET_ON_LOGON ) )
pSession->setResetOnLogon( settings.getBool( RESET_ON_LOGON ) );
if ( settings.has( RESET_ON_LOGOUT ) )
pSession->setResetOnLogout( settings.getBool( RESET_ON_LOGOUT ) );
if ( settings.has( RESET_ON_DISCONNECT ) )
pSession->setResetOnDisconnect( settings.getBool( RESET_ON_DISCONNECT ) );
if ( settings.has( REFRESH_ON_LOGON ) )
pSession->setRefreshOnLogon( settings.getBool( REFRESH_ON_LOGON ) );
if ( settings.has( MILLISECONDS_IN_TIMESTAMP ) )
pSession->setTimestampPrecision(3);
if ( settings.has( TIMESTAMP_PRECISION ) )
pSession->setTimestampPrecision(settings.getInt( TIMESTAMP_PRECISION ) );
if ( settings.has( PERSIST_MESSAGES ) )
pSession->setPersistMessages( settings.getBool( PERSIST_MESSAGES ) );
if ( settings.has( VALIDATE_LENGTH_AND_CHECKSUM ) )
pSession->setValidateLengthAndChecksum( settings.getBool( VALIDATE_LENGTH_AND_CHECKSUM ) );
return pSession.release();
}
void SessionFactory::destroy( Session* pSession )
{
delete pSession;
}
ptr::shared_ptr<DataDictionary> SessionFactory::createDataDictionary(const SessionID& sessionID,
const Dictionary& settings,
const std::string& settingsKey) throw(ConfigError)
{
ptr::shared_ptr<DataDictionary> pDD;
std::string path = settings.getString( settingsKey );
Dictionaries::iterator i = m_dictionaries.find( path );
if ( i != m_dictionaries.end() )
{
pDD = i->second;
}
else
{
bool preserveMsgFldsOrder = false;
if( settings.has( PRESERVE_MESSAGE_FIELDS_ORDER ) )
preserveMsgFldsOrder = settings.getBool( PRESERVE_MESSAGE_FIELDS_ORDER );
pDD = ptr::shared_ptr<DataDictionary>(new DataDictionary( path, preserveMsgFldsOrder ));
m_dictionaries[ path ] = pDD;
}
ptr::shared_ptr<DataDictionary> pCopyOfDD = ptr::shared_ptr<DataDictionary>(new DataDictionary(*pDD));
if( settings.has( VALIDATE_FIELDS_OUT_OF_ORDER ) )
pCopyOfDD->checkFieldsOutOfOrder( settings.getBool( VALIDATE_FIELDS_OUT_OF_ORDER ) );
if( settings.has( VALIDATE_FIELDS_HAVE_VALUES ) )
pCopyOfDD->checkFieldsHaveValues( settings.getBool( VALIDATE_FIELDS_HAVE_VALUES ) );
if( settings.has( VALIDATE_USER_DEFINED_FIELDS ) )
pCopyOfDD->checkUserDefinedFields( settings.getBool( VALIDATE_USER_DEFINED_FIELDS ) );
if( settings.has( ALLOW_UNKNOWN_MSG_FIELDS ) )
pCopyOfDD->allowUnknownMsgFields( settings.getBool( ALLOW_UNKNOWN_MSG_FIELDS ) );
return pCopyOfDD;
}
void SessionFactory::processFixtDataDictionaries(const SessionID& sessionID,
const Dictionary& settings,
DataDictionaryProvider& provider) throw(ConfigError)
{
ptr::shared_ptr<DataDictionary> pDataDictionary = createDataDictionary(sessionID, settings, TRANSPORT_DATA_DICTIONARY);
provider.addTransportDataDictionary(sessionID.getBeginString(), pDataDictionary);
for(Dictionary::const_iterator data = settings.begin(); data != settings.end(); ++data)
{
const std::string& key = data->first;
const std::string frontKey = key.substr(0, strlen(APP_DATA_DICTIONARY));
if( frontKey == string_toUpper(APP_DATA_DICTIONARY) )
{
if( key == string_toUpper(APP_DATA_DICTIONARY) )
{
provider.addApplicationDataDictionary(Message::toApplVerID(settings.getString(DEFAULT_APPLVERID)),
createDataDictionary(sessionID, settings, APP_DATA_DICTIONARY));
}
else
{
std::string::size_type offset = key.find('.');
if( offset == std::string::npos )
throw ConfigError(std::string("Malformed ") + APP_DATA_DICTIONARY + ": " + key);
std::string beginStringQualifier = key.substr(offset+1);
provider.addApplicationDataDictionary(Message::toApplVerID(beginStringQualifier),
createDataDictionary(sessionID, settings, key));
}
}
}
}
void SessionFactory::processFixDataDictionary(const SessionID& sessionID,
const Dictionary& settings,
DataDictionaryProvider& provider) throw(ConfigError)
{
ptr::shared_ptr<DataDictionary> pDataDictionary = createDataDictionary(sessionID, settings, DATA_DICTIONARY);
provider.addTransportDataDictionary(sessionID.getBeginString(), pDataDictionary);
provider.addApplicationDataDictionary(Message::toApplVerID(sessionID.getBeginString()), pDataDictionary);
}
}
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