15#include <boost/program_options.hpp>
16#include <boost/tokenizer.hpp>
20#include <stdair/stdair_basic_types.hpp>
21#include <stdair/stdair_json.hpp>
22#include <stdair/basic/BasConst_General.hpp>
23#include <stdair/basic/BasLogParams.hpp>
24#include <stdair/basic/BasDBParams.hpp>
25#include <stdair/basic/DemandGenerationMethod.hpp>
26#include <stdair/service/Logger.hpp>
28#include <tvlsim/config/tvlsim-paths.hpp>
45typedef unsigned int ServerPort_T;
56const std::string K_TVLSIM_DEFAULT_SERVER_PROTOCOL (
"tcp://");
61const std::string K_TVLSIM_DEFAULT_SERVER_ADDRESS (
"*");
66const ServerPort_T K_TVLSIM_DEFAULT_SERVER_PORT (5555);
72 "/rds01/schedule05.csv");
107 "/rds01/demand05.csv");
118 stdair::DEFAULT_RANDOM_SEED;
158 typedef boost::tokenizer<boost::char_separator<char> > Tokeniser_T;
161 const boost::char_separator<char> lSepatorList(
" .,;:|+-*/_=!@#$%`~^&(){}[]?'<>\"");
164 Tokeniser_T lTokens (iPhrase, lSepatorList);
165 for (Tokeniser_T::const_iterator tok_iter = lTokens.begin();
166 tok_iter != lTokens.end(); ++tok_iter) {
167 const std::string& lTerm = *tok_iter;
168 ioWordList.push_back (lTerm);
175 std::ostringstream oStr;
177 unsigned short idx = iWordList.size();
178 for (WordList_T::const_iterator itWord = iWordList.begin();
179 itWord != iWordList.end(); ++itWord, --idx) {
180 const std::string& lWord = *itWord;
192template<
class T> std::ostream&
operator<< (std::ostream& os,
193 const std::vector<T>& v) {
194 std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout,
" "));
201 std::string& ioServerAddress, ServerPort_T& ioServerPort,
202 bool& ioIsBuiltin, stdair::RandomSeed_T& ioRandomSeed,
203 NbOfRuns_T& ioRandomRuns, std::string& ioQueryString,
204 stdair::Filename_T& ioScheduleInputFilename,
205 stdair::Filename_T& ioOnDInputFilename,
206 stdair::Filename_T& ioFRAT5Filename,
207 stdair::Filename_T& ioFFDisutilityFilename,
208 stdair::Filename_T& ioYieldInputFilename,
209 stdair::Filename_T& ioFareInputFilename,
210 stdair::Filename_T& ioDemandInputFilename,
211 std::string& ioLogFilename,
212 stdair::DemandGenerationMethod& ioDemandGenerationMethod,
213 std::string& ioDBUser, std::string& ioDBPasswd,
214 std::string& ioDBHost, std::string& ioDBPort,
215 std::string& ioDBDBName) {
218 char lDemandGenerationMethodChar;
224 if (ioQueryString.empty() ==
true) {
233 boost::program_options::options_description generic (
"Generic options");
234 generic.add_options()
235 (
"prefix",
"print installation prefix")
236 (
"version,v",
"print version string")
237 (
"help,h",
"produce help message");
242 boost::program_options::options_description config (
"Configuration");
245 "The sample BOM tree can be either built-in or parsed from input files. In that latter case, the input files must be specified as well (e.g., -d/--demand, -s/--schedule, -o/--ond, -f/--fare, -y/--yield)")
248 "Seed for the random generation")
251 "Number of simulation runs")
254 "(CSV) input file for the schedules")
257 "(CSV) input file for the O&D definitions")
260 "(CSV) input file for the FRAT5 Curve")
263 "(CSV) input file for the FF disutility Curve")
266 "(CSV) input file for the yields")
269 "(CSV) input file for the fares")
272 "(CSV) input file for the demand distributions")
274 boost::program_options::value< std::string >(&ioServerProtocol)->default_value(K_TVLSIM_DEFAULT_SERVER_PROTOCOL),
277 boost::program_options::value< std::string >(&ioServerAddress)->default_value(K_TVLSIM_DEFAULT_SERVER_ADDRESS),
280 boost::program_options::value< ServerPort_T >(&ioServerPort)->default_value(K_TVLSIM_DEFAULT_SERVER_PORT),
284 "Filepath for the logs")
285 (
"demandgeneration,G",
287 "Method used to generate the demand (i.e., booking requests): Poisson Process (e.g., P) or Statistics Order (e.g., S)")
290 "SQL database hostname (e.g., tvlsim)")
293 "SQL database hostname (e.g., tvlsim)")
296 "SQL database hostname (e.g., localhost)")
299 "SQL database port (e.g., 3306)")
302 "SQL database name (e.g., tvlsim)")
304 boost::program_options::value< WordList_T >(&lWordList)->multitoken(),
310 boost::program_options::options_description hidden (
"Hidden options");
313 boost::program_options::value< std::vector<std::string> >(),
314 "Show the copyright (license)");
316 boost::program_options::options_description cmdline_options;
317 cmdline_options.add(generic).add(config).add(hidden);
319 boost::program_options::options_description config_file_options;
320 config_file_options.add(config).add(hidden);
322 boost::program_options::options_description visible (
"Allowed options");
323 visible.add(generic).add(config);
325 boost::program_options::positional_options_description p;
326 p.add (
"copyright", -1);
328 boost::program_options::variables_map vm;
329 boost::program_options::
330 store (boost::program_options::command_line_parser (argc, argv).
331 options (cmdline_options).positional(p).run(), vm);
333 std::ifstream ifs (
"simulate.cfg");
334 boost::program_options::store (parse_config_file (ifs, config_file_options),
336 boost::program_options::notify (vm);
338 if (vm.count (
"help")) {
339 std::cout << visible << std::endl;
343 if (vm.count (
"version")) {
344 std::cout << PACKAGE_NAME <<
", version " << PACKAGE_VERSION << std::endl;
348 if (vm.count (
"prefix")) {
349 std::cout <<
"Installation prefix: " << PREFIXDIR << std::endl;
353 if (vm.count (
"protocol")) {
354 ioServerProtocol = vm[
"protocol"].as< std::string >();
355 std::cout <<
"Server protocol is: " << ioServerProtocol << std::endl;
358 if (vm.count (
"address")) {
359 ioServerAddress = vm[
"address"].as< std::string >();
360 std::cout <<
"Server address is: " << ioServerAddress << std::endl;
363 if (vm.count (
"port")) {
364 ioServerPort = vm[
"port"].as< ServerPort_T >();
365 std::cout <<
"Server port is: " << ioServerPort << std::endl;
368 if (vm.count (
"builtin")) {
371 const std::string isBuiltinStr = (ioIsBuiltin ==
true)?
"yes":
"no";
372 std::cout <<
"The BOM should be built-in? " << isBuiltinStr << std::endl;
375 std::ostringstream oErrorMessageStr;
376 oErrorMessageStr <<
"Either the -b/--builtin option, or the combination of "
377 <<
"the -d/--demand, -s/--schedule, -o/--ond, -f/--fare "
378 <<
"and -y/--yield options must be specified";
380 if (ioIsBuiltin ==
false) {
381 if (vm.count (
"schedule")) {
382 ioScheduleInputFilename = vm[
"schedule"].as< std::string >();
383 std::cout <<
"Schedule input filename is: " << ioScheduleInputFilename
389 std::cerr << oErrorMessageStr.str() << std::endl;
392 if (vm.count (
"ond")) {
393 ioOnDInputFilename = vm[
"ond"].as< std::string >();
394 std::cout <<
"O&D input filename is: " << ioOnDInputFilename << std::endl;
399 std::cerr << oErrorMessageStr.str() << std::endl;
402 if (vm.count (
"frat5")) {
403 ioFRAT5Filename = vm[
"frat5"].as< std::string >();
404 std::cout <<
"FRAT5 input filename is: " << ioFRAT5Filename << std::endl;
409 std::cerr << oErrorMessageStr.str() << std::endl;
412 if (vm.count (
"ff_disutility")) {
413 ioFFDisutilityFilename = vm[
"ff_disutility"].as< std::string >();
414 std::cout <<
"FF disutility input filename is: "
415 << ioFFDisutilityFilename << std::endl;
420 std::cerr << oErrorMessageStr.str() << std::endl;
423 if (vm.count (
"yield")) {
424 ioYieldInputFilename = vm[
"yield"].as< std::string >();
425 std::cout <<
"Yield input filename is: " << ioYieldInputFilename << std::endl;
430 std::cerr << oErrorMessageStr.str() << std::endl;
433 if (vm.count (
"fare")) {
434 ioFareInputFilename = vm[
"fare"].as< std::string >();
435 std::cout <<
"Fare input filename is: " << ioFareInputFilename << std::endl;
440 std::cerr << oErrorMessageStr.str() << std::endl;
443 if (vm.count (
"demand")) {
444 ioDemandInputFilename = vm[
"demand"].as< std::string >();
445 std::cout <<
"Demand input filename is: " << ioDemandInputFilename
450 std::cerr << oErrorMessageStr.str() << std::endl;
454 if (vm.count (
"log")) {
455 ioLogFilename = vm[
"log"].as< std::string >();
456 std::cout <<
"Log filename is: " << ioLogFilename << std::endl;
460 if (vm.count (
"demandgeneration")) {
461 ioDemandGenerationMethod =
462 stdair::DemandGenerationMethod (lDemandGenerationMethodChar);
463 std::cout <<
"Demand generation method is: "
464 << ioDemandGenerationMethod.describe() << std::endl;
468 std::cout <<
"The random generation seed is: " << ioRandomSeed << std::endl;
471 std::cout <<
"The number of simulation runs is: " << ioRandomRuns
475 if (vm.count (
"user")) {
476 ioDBUser = vm[
"user"].as< std::string >();
477 std::cout <<
"SQL database user name is: " << ioDBUser << std::endl;
480 if (vm.count (
"passwd")) {
481 ioDBPasswd = vm[
"passwd"].as< std::string >();
485 if (vm.count (
"host")) {
486 ioDBHost = vm[
"host"].as< std::string >();
487 std::cout <<
"SQL database host name is: " << ioDBHost << std::endl;
490 if (vm.count (
"dbport")) {
491 ioDBPort = vm[
"dbport"].as< std::string >();
492 std::cout <<
"SQL database port number is: " << ioDBPort << std::endl;
495 if (vm.count (
"dbname")) {
496 ioDBDBName = vm[
"dbname"].as< std::string >();
497 std::cout <<
"SQL database name is: " << ioDBDBName << std::endl;
502 std::cout <<
"The query string is: " << ioQueryString << std::endl;
512static std::string s_recv (zmq::socket_t& socket) {
513 zmq::message_t message;
514 zmq::recv_result_t rc = socket.recv (message);
517 if (rc.has_value()) {
518 const unsigned int rc_val = rc.value();
519 std::cout <<
"Receive status: " << rc_val << std::endl;
522 return std::string (
static_cast<char*
> (message.data()), message.size());
528static zmq::send_result_t s_send (zmq::socket_t& socket,
const std::string&
string) {
529 zmq::message_t message (
string.size());
530 memcpy (message.data(),
string.data(),
string.size());
532 zmq::send_result_t rc = socket.send (message, zmq::send_flags::dontwait);
538int main (
int argc,
char* argv[]) {
541 std::string ioServerProtocol;
542 std::string ioServerAddress;
543 ServerPort_T ioServerPort;
550 stdair::RandomSeed_T lRandomSeed;
559 stdair::Date_T lStartDate (2011, boost::gregorian::Apr, 27);
562 stdair::Date_T lEndDate (2013, boost::gregorian::Jan, 02);
565 stdair::Filename_T lScheduleInputFilename;
568 std::string lOnDInputFilename;
571 std::string lFRAT5InputFilename;
574 std::string lFFDisutilityInputFilename;
577 std::string lYieldInputFilename;
580 std::string lFareInputFilename;
583 stdair::Filename_T lDemandInputFilename;
586 std::string lLogFilename;
589 stdair::DemandGenerationMethod
594 std::string lDBPasswd;
597 std::string lDBDBName;
600 const int lOptionParserStatus =
602 ioServerPort, isBuiltin, lRandomSeed, lNbOfRuns, lQuery,
603 lScheduleInputFilename, lOnDInputFilename,
604 lFRAT5InputFilename, lFFDisutilityInputFilename,
605 lYieldInputFilename, lFareInputFilename,
606 lDemandInputFilename, lLogFilename,
607 lDemandGenerationMethod,
608 lDBUser, lDBPasswd, lDBHost, lDBPort, lDBDBName);
615 stdair::BasDBParams lDBParams (lDBUser, lDBPasswd, lDBHost, lDBPort,
619 std::ofstream logOutputFile;
621 logOutputFile.open (lLogFilename.c_str());
622 logOutputFile.clear();
625 const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
627 lRandomSeed, lDemandGenerationMethod,
631 STDAIR_LOG_DEBUG (
"Initialisation of the TvlSim server");
634 if (isBuiltin ==
true) {
637 tvlsimService.buildSampleBom();
642 stdair::ScheduleFilePath lScheduleFilePath (lScheduleInputFilename);
643 stdair::ODFilePath lODFilePath (lOnDInputFilename);
644 stdair::FRAT5FilePath lFRAT5FilePath (lFRAT5InputFilename);
645 stdair::FFDisutilityFilePath lFFDisutilityFilePath (lFFDisutilityInputFilename);
646 const SIMFQT::FareFilePath lFareFilePath (lFareInputFilename);
647 const AIRRAC::YieldFilePath lYieldFilePath (lYieldInputFilename);
648 const TRADEMGEN::DemandFilePath lDemandFilePath (lDemandInputFilename);
649 tvlsimService.setInputFiles (lScheduleFilePath, lODFilePath,
650 lFRAT5FilePath, lFFDisutilityFilePath,
651 lYieldFilePath, lFareFilePath,
653 tvlsimService.parseAndLoad ();
658 tvlsimService.initSnapshotAndRMEvents();
661 std::ostringstream oZeroMQBindStream;
662 oZeroMQBindStream << ioServerProtocol << ioServerAddress
663 <<
":" << ioServerPort;
664 const std::string lZeroMQBindString (oZeroMQBindStream.str());
667 zmq::context_t context (1);
668 zmq::socket_t socket (context, ZMQ_REP);
669 socket.bind (lZeroMQBindString.c_str());
672 STDAIR_LOG_DEBUG (
"The TvlSim server is ready to receive requests...");
678 const std::string& lReceivedString = s_recv (socket);
681 STDAIR_LOG_DEBUG (
"Received: '" << lReceivedString <<
"'");
683 const stdair::JSONString lJSONCommandString (lReceivedString);
684 const std::string& lJSONDump =
685 tvlsimService.jsonHandler (lJSONCommandString);
688 STDAIR_LOG_DEBUG (
"Send: '" << lJSONDump <<
"'");
691 zmq::send_result_t rc = s_send (socket, lJSONDump);
694 if (rc.has_value()) {
695 const unsigned int rc_val = rc.value();
696 std::cout <<
"Send status: " << rc_val << std::endl;
std::string createStringFromWordList(const WordList_T &iWordList)
const char K_TVLSIM_DEMAND_GENERATION_METHOD_CHAR('S')
const std::string K_TVLSIM_DEFAULT_LOG_FILENAME("simulate.log")
int main(int argc, char *argv[])
const std::string K_TVLSIM_DEFAULT_FF_DISUTILITY_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/ffDisutility.csv")
const std::string K_TVLSIM_DEFAULT_QUERY_STRING("my good old query")
const std::string K_TVLSIM_DEFAULT_DB_PASSWD("tvlsim")
const std::string K_TVLSIM_DEFAULT_YIELD_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/rds01/yield.csv")
const std::string K_TVLSIM_DEFAULT_SCHEDULE_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/rds01/schedule.csv")
const std::string K_TVLSIM_DEFAULT_DEMAND_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/rds01/demand.csv")
const std::string K_TVLSIM_DEFAULT_FRAT5_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/frat5.csv")
const std::string K_TVLSIM_DEFAULT_DB_DBNAME("sim_tvlsim")
const stdair::RandomSeed_T K_TRADEMGEN_DEFAULT_RANDOM_SEED
void tokeniseStringIntoWordList(const std::string &iPhrase, WordList_T &ioWordList)
const std::string K_TVLSIM_DEFAULT_OND_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/ond01.csv")
const std::string K_TVLSIM_DEFAULT_DB_HOST("localhost")
const NbOfRuns_T K_TRADEMGEN_DEFAULT_RANDOM_DRAWS
const std::string K_TVLSIM_DEFAULT_FARE_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/rds01/fare.csv")
std::vector< std::string > WordList_T
const std::string K_TVLSIM_DEFAULT_DB_PORT("3306")
const int K_TVLSIM_EARLY_RETURN_STATUS
int readConfiguration(int argc, char *argv[], bool &ioIsBuiltin, stdair::RandomSeed_T &ioRandomSeed, NbOfRuns_T &ioRandomRuns, std::string &ioQueryString, stdair::Filename_T &ioScheduleInputFilename, stdair::Filename_T &ioOnDInputFilename, stdair::Filename_T &ioFRAT5Filename, stdair::Filename_T &ioFFDisutilityFilename, stdair::Filename_T &ioYieldInputFilename, stdair::Filename_T &ioFareInputFilename, stdair::Filename_T &ioDemandInputFilename, std::string &ioLogFilename, stdair::DemandGenerationMethod &ioDemandGenerationMethod, std::string &ioDBUser, std::string &ioDBPasswd, std::string &ioDBHost, std::string &ioDBPort, std::string &ioDBDBName)
std::ostream & operator<<(std::ostream &os, const std::vector< T > &v)
const std::string K_TVLSIM_DEFAULT_DB_USER("tvlsim")
const bool K_TVLSIM_DEFAULT_BUILT_IN_INPUT