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>
45 typedef unsigned int ServerPort_T;
56 const std::string K_TVLSIM_DEFAULT_SERVER_PROTOCOL (
"tcp://");
61 const std::string K_TVLSIM_DEFAULT_SERVER_ADDRESS (
"*");
66 const 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;
192 template<
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")) {
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;
512 static std::string s_recv (zmq::socket_t& socket) {
513 zmq::message_t message;
514 socket.recv (&message);
516 return std::string (static_cast<char*> (message.data()), message.size());
522 static bool s_send (zmq::socket_t& socket,
const std::string&
string) {
523 zmq::message_t message (
string.size());
524 memcpy (message.data(),
string.data(),
string.size());
526 bool rc = socket.send (message);
532 int main (
int argc,
char* argv[]) {
535 std::string ioServerProtocol;
536 std::string ioServerAddress;
537 ServerPort_T ioServerPort;
544 stdair::RandomSeed_T lRandomSeed;
553 stdair::Date_T lStartDate (2009, boost::gregorian::Feb, 01);
556 stdair::Date_T lEndDate (2012, boost::gregorian::Mar, 02);
559 stdair::Filename_T lScheduleInputFilename;
562 std::string lOnDInputFilename;
565 std::string lFRAT5InputFilename;
568 std::string lFFDisutilityInputFilename;
571 std::string lYieldInputFilename;
574 std::string lFareInputFilename;
577 stdair::Filename_T lDemandInputFilename;
580 std::string lLogFilename;
583 stdair::DemandGenerationMethod
588 std::string lDBPasswd;
591 std::string lDBDBName;
594 const int lOptionParserStatus =
596 ioServerPort, isBuiltin, lRandomSeed, lNbOfRuns, lQuery,
597 lScheduleInputFilename, lOnDInputFilename,
598 lFRAT5InputFilename, lFFDisutilityInputFilename,
599 lYieldInputFilename, lFareInputFilename,
600 lDemandInputFilename, lLogFilename,
601 lDemandGenerationMethod,
602 lDBUser, lDBPasswd, lDBHost, lDBPort, lDBDBName);
609 stdair::BasDBParams lDBParams (lDBUser, lDBPasswd, lDBHost, lDBPort,
613 std::ofstream logOutputFile;
615 logOutputFile.open (lLogFilename.c_str());
616 logOutputFile.clear();
619 const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
621 lRandomSeed, lDemandGenerationMethod,
625 STDAIR_LOG_DEBUG (
"Initialisation of the TvlSim server");
628 if (isBuiltin ==
true) {
631 tvlsimService.buildSampleBom();
636 stdair::ScheduleFilePath lScheduleFilePath (lScheduleInputFilename);
637 stdair::ODFilePath lODFilePath (lOnDInputFilename);
638 stdair::FRAT5FilePath lFRAT5FilePath (lFRAT5InputFilename);
639 stdair::FFDisutilityFilePath lFFDisutilityFilePath (lFFDisutilityInputFilename);
640 const SIMFQT::FareFilePath lFareFilePath (lFareInputFilename);
641 const AIRRAC::YieldFilePath lYieldFilePath (lYieldInputFilename);
642 const TRADEMGEN::DemandFilePath lDemandFilePath (lDemandInputFilename);
643 tvlsimService.setInputFiles (lScheduleFilePath, lODFilePath,
644 lFRAT5FilePath, lFFDisutilityFilePath,
645 lYieldFilePath, lFareFilePath,
647 tvlsimService.parseAndLoad ();
652 tvlsimService.initSnapshotAndRMEvents();
655 std::ostringstream oZeroMQBindStream;
656 oZeroMQBindStream << ioServerProtocol << ioServerAddress
657 <<
":" << ioServerPort;
658 const std::string lZeroMQBindString (oZeroMQBindStream.str());
661 zmq::context_t context (1);
662 zmq::socket_t socket (context, ZMQ_REP);
663 socket.bind (lZeroMQBindString.c_str());
666 STDAIR_LOG_DEBUG (
"The TvlSim server is ready to receive requests...");
672 const std::string& lReceivedString = s_recv (socket);
675 STDAIR_LOG_DEBUG (
"Received: '" << lReceivedString <<
"'");
677 const stdair::JSONString lJSONCommandString (lReceivedString);
678 const std::string& lJSONDump =
679 tvlsimService.jsonHandler (lJSONCommandString);
682 STDAIR_LOG_DEBUG (
"Send: '" << lJSONDump <<
"'");
685 s_send (socket, lJSONDump);