SimCRS Logo  1.01.8
C++ Simulated Travel-Oriented Distribution System Library
Loading...
Searching...
No Matches
simcrs.cpp
Go to the documentation of this file.
1// STL
2#include <sstream>
3#include <fstream>
4#include <string>
5// Boost (Extended STL)
6#include <boost/program_options.hpp>
7// StdAir
8#include <stdair/stdair_basic_types.hpp>
9#include <stdair/basic/BasLogParams.hpp>
10#include <stdair/basic/BasDBParams.hpp>
11#include <stdair/basic/BasFileMgr.hpp>
12#include <stdair/bom/TravelSolutionStruct.hpp>
13#include <stdair/bom/BookingRequestStruct.hpp>
14#include <stdair/service/Logger.hpp>
15// SimFQT
16#include <simfqt/SIMFQT_Types.hpp>
17// SimCRS
19#include <simcrs/config/simcrs-paths.hpp>
20
21// //////// Constants //////
25const std::string K_SIMCRS_DEFAULT_LOG_FILENAME ("simcrs.log");
26
30const std::string K_SIMCRS_DEFAULT_SCHEDULE_INPUT_FILENAME (STDAIR_SAMPLE_DIR
31 "/schedule01.csv");
32
36const std::string K_SIMCRS_DEFAULT_OND_INPUT_FILENAME (STDAIR_SAMPLE_DIR
37 "/ond01.csv");
38
42const std::string K_SIMCRS_DEFAULT_FRAT5_INPUT_FILENAME (STDAIR_SAMPLE_DIR
43 "/frat5.csv");
47const std::string K_SIMCRS_DEFAULT_FF_DISUTILITY_INPUT_FILENAME (STDAIR_SAMPLE_DIR
48 "/ffDisutility.csv");
49
53const std::string K_SIMCRS_DEFAULT_YIELD_INPUT_FILENAME (STDAIR_SAMPLE_DIR
54 "/yieldstore01.csv");
55
59const std::string K_SIMCRS_DEFAULT_FARE_INPUT_FILENAME (STDAIR_SAMPLE_DIR
60 "/fare01.csv");
61
68
72const std::string K_SIMCRS_DEFAULT_DB_USER ("dsim");
73const std::string K_SIMCRS_DEFAULT_DB_PASSWD ("dsim");
74const std::string K_SIMCRS_DEFAULT_DB_DBNAME ("sim_dsim");
75const std::string K_SIMCRS_DEFAULT_DB_HOST ("localhost");
76const std::string K_SIMCRS_DEFAULT_DB_PORT ("3306");
77
78// ///////// Parsing of Options & Configuration /////////
79// A helper function to simplify the main part.
80template<class T> std::ostream& operator<< (std::ostream& os,
81 const std::vector<T>& v) {
82 std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " "));
83 return os;
84}
85
88
90int readConfiguration (int argc, char* argv[],
91 bool& ioIsBuiltin,
92 stdair::Filename_T& ioScheduleInputFilename,
93 stdair::Filename_T& ioOnDInputFilename,
94 stdair::Filename_T& ioFRAT5Filename,
95 stdair::Filename_T& ioFFDisutilityFilename,
96 stdair::Filename_T& ioYieldInputFilename,
97 stdair::Filename_T& ioFareInputFilename,
98 stdair::Filename_T& ioLogFilename,
99 std::string& ioDBUser, std::string& ioDBPasswd,
100 std::string& ioDBHost, std::string& ioDBPort,
101 std::string& ioDBDBName) {
102 // Default for the built-in input
104
105 // Declare a group of options that will be allowed only on command line
106 boost::program_options::options_description generic ("Generic options");
107 generic.add_options()
108 ("prefix", "print installation prefix")
109 ("version,v", "print version string")
110 ("help,h", "produce help message");
111
112 // Declare a group of options that will be allowed both on command
113 // line and in config file
114 boost::program_options::options_description config ("Configuration");
115 config.add_options()
116 ("builtin,b",
117 "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., -s/--schedule, -o/--ond, -f/--fare, -y/--yield)")
118 ("schedule,s",
119 boost::program_options::value< std::string >(&ioScheduleInputFilename)->default_value(K_SIMCRS_DEFAULT_SCHEDULE_INPUT_FILENAME),
120 "(CVS) input file for the schedules")
121 ("ond,o",
122 boost::program_options::value< std::string >(&ioOnDInputFilename)->default_value(K_SIMCRS_DEFAULT_OND_INPUT_FILENAME),
123 "(CVS) input file for the O&D definitions")
124 ("frat5,F",
125 boost::program_options::value< std::string >(&ioFRAT5Filename)->default_value(K_SIMCRS_DEFAULT_FRAT5_INPUT_FILENAME),
126 "(CSV) input file for the FRAT5 Curve")
127 ("ff_disutility,D",
128 boost::program_options::value< std::string >(&ioFFDisutilityFilename)->default_value(K_SIMCRS_DEFAULT_FF_DISUTILITY_INPUT_FILENAME),
129 "(CSV) input file for the FF disutility Curve")
130 ("yield,y",
131 boost::program_options::value< std::string >(&ioYieldInputFilename)->default_value(K_SIMCRS_DEFAULT_YIELD_INPUT_FILENAME),
132 "(CVS) input file for the yields")
133 ("fare,f",
134 boost::program_options::value< std::string >(&ioFareInputFilename)->default_value(K_SIMCRS_DEFAULT_FARE_INPUT_FILENAME),
135 "(CVS) input file for the fares")
136 ("log,l",
137 boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_SIMCRS_DEFAULT_LOG_FILENAME),
138 "Filepath for the logs")
139 ("user,u",
140 boost::program_options::value< std::string >(&ioDBUser)->default_value(K_SIMCRS_DEFAULT_DB_USER),
141 "SQL database username")
142 ("passwd,p",
143 boost::program_options::value< std::string >(&ioDBPasswd)->default_value(K_SIMCRS_DEFAULT_DB_PASSWD),
144 "SQL database password")
145 ("host,H",
146 boost::program_options::value< std::string >(&ioDBHost)->default_value(K_SIMCRS_DEFAULT_DB_HOST),
147 "SQL database hostname")
148 ("port,P",
149 boost::program_options::value< std::string >(&ioDBPort)->default_value(K_SIMCRS_DEFAULT_DB_PORT),
150 "SQL database port")
151 ("dbname,m",
152 boost::program_options::value< std::string >(&ioDBDBName)->default_value(K_SIMCRS_DEFAULT_DB_DBNAME),
153 "SQL database name")
154 ;
155
156 // Hidden options, will be allowed both on command line and
157 // in config file, but will not be shown to the user.
158 boost::program_options::options_description hidden ("Hidden options");
159 hidden.add_options()
160 ("copyright",
161 boost::program_options::value< std::vector<std::string> >(),
162 "Show the copyright (license)");
163
164 boost::program_options::options_description cmdline_options;
165 cmdline_options.add(generic).add(config).add(hidden);
166
167 boost::program_options::options_description config_file_options;
168 config_file_options.add(config).add(hidden);
169
170 boost::program_options::options_description visible ("Allowed options");
171 visible.add(generic).add(config);
172
173 boost::program_options::positional_options_description p;
174 p.add ("copyright", -1);
175
176 boost::program_options::variables_map vm;
177 boost::program_options::
178 store (boost::program_options::command_line_parser (argc, argv).
179 options (cmdline_options).positional(p).run(), vm);
180
181 std::ifstream ifs ("simcrs.cfg");
182 boost::program_options::store (parse_config_file (ifs, config_file_options),
183 vm);
184 boost::program_options::notify (vm);
185
186 if (vm.count ("help")) {
187 std::cout << visible << std::endl;
189 }
190
191 if (vm.count ("version")) {
192 std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
194 }
195
196 if (vm.count ("prefix")) {
197 std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
199 }
200
201 if (vm.count ("builtin")) {
202 ioIsBuiltin = true;
203 }
204 const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no";
205 std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl;
206
207 //
208 std::ostringstream oErrorMessageStr;
209 oErrorMessageStr << "Either the -b/--builtin option, or the combination of "
210 << "the -s/--schedule, -o/--ond, -f/--fare and -y/--yield "
211 << "options must be specified";
212
213 if (ioIsBuiltin == false) {
214 if (vm.count ("schedule")) {
215 ioScheduleInputFilename = vm["schedule"].as< std::string >();
216 std::cout << "Schedule input filename is: " << ioScheduleInputFilename
217 << std::endl;
218
219 } else {
220 // The built-in option is not selected. However, no schedule input file
221 // is specified
222 std::cerr << oErrorMessageStr.str() << std::endl;
223 }
224
225 if (vm.count ("ond")) {
226 ioOnDInputFilename = vm["ond"].as< std::string >();
227 std::cout << "O&D input filename is: " << ioOnDInputFilename << std::endl;
228
229 } else {
230 // The built-in option is not selected. However, no schedule input file
231 // is specified
232 std::cerr << oErrorMessageStr.str() << std::endl;
233 }
234
235 if (vm.count ("frat5")) {
236 ioFRAT5Filename = vm["frat5"].as< std::string >();
237 std::cout << "FRAT5 input filename is: " << ioFRAT5Filename << std::endl;
238
239 } else {
240 // The built-in option is not selected. However, no frat5 input file
241 // is specified
242 std::cerr << oErrorMessageStr.str() << std::endl;
243 }
244
245 if (vm.count ("ff_disutility")) {
246 ioFFDisutilityFilename = vm["ff_disutility"].as< std::string >();
247 std::cout << "FF disutility input filename is: "
248 << ioFFDisutilityFilename << std::endl;
249
250 } else {
251 // The built-in option is not selected. However, no ff
252 // disutility input file is specified
253 std::cerr << oErrorMessageStr.str() << std::endl;
254 }
255
256 if (vm.count ("yield")) {
257 ioYieldInputFilename = vm["yield"].as< std::string >();
258 std::cout << "Yield input filename is: " << ioYieldInputFilename
259 << std::endl;
260
261 } else {
262 // The built-in option is not selected. However, no schedule input file
263 // is specified
264 std::cerr << oErrorMessageStr.str() << std::endl;
265 }
266
267 if (vm.count ("fare")) {
268 ioFareInputFilename = vm["fare"].as< std::string >();
269 std::cout << "Fare input filename is: " << ioFareInputFilename
270 << std::endl;
271
272 } else {
273 // The built-in option is not selected. However, no schedule input file
274 // is specified
275 std::cerr << oErrorMessageStr.str() << std::endl;
276 }
277 }
278
279 if (vm.count ("log")) {
280 ioLogFilename = vm["log"].as< std::string >();
281 std::cout << "Log filename is: " << ioLogFilename << std::endl;
282 }
283
284 if (vm.count ("user")) {
285 ioDBUser = vm["user"].as< std::string >();
286 std::cout << "SQL database user name is: " << ioDBUser << std::endl;
287 }
288
289 if (vm.count ("passwd")) {
290 ioDBPasswd = vm["passwd"].as< std::string >();
291 //std::cout << "SQL database user password is: " << ioDBPasswd << std::endl;
292 }
293
294 if (vm.count ("host")) {
295 ioDBHost = vm["host"].as< std::string >();
296 std::cout << "SQL database host name is: " << ioDBHost << std::endl;
297 }
298
299 if (vm.count ("port")) {
300 ioDBPort = vm["port"].as< std::string >();
301 std::cout << "SQL database port number is: " << ioDBPort << std::endl;
302 }
303
304 if (vm.count ("dbname")) {
305 ioDBDBName = vm["dbname"].as< std::string >();
306 std::cout << "SQL database name is: " << ioDBDBName << std::endl;
307 }
308
309 return 0;
310}
311
312// ///////// M A I N ////////////
313int main (int argc, char* argv[]) {
314
315 // State whether the BOM tree should be built-in or parsed from an
316 // input file
317 bool isBuiltin;
318
319 // Schedule input filename
320 stdair::Filename_T lScheduleInputFilename;
321
322 // O&D input filename
323 stdair::Filename_T lOnDInputFilename;
324
325 // FRAT5 input filename
326 std::string lFRAT5InputFilename;
327
328 // FF disutility input filename
329 std::string lFFDisutilityInputFilename;
330
331 // Yield input filename
332 stdair::Filename_T lYieldInputFilename;
333
334 // Fare input filename
335 stdair::Filename_T lFareInputFilename;
336
337 // Output log File
338 stdair::Filename_T lLogFilename;
339
340 // SQL database parameters
341 std::string lDBUser;
342 std::string lDBPasswd;
343 std::string lDBHost;
344 std::string lDBPort;
345 std::string lDBDBName;
346
347 // CRS code
348 const SIMCRS::CRSCode_T lCRSCode ("1P");
349
350 // Call the command-line option parser
351 const int lOptionParserStatus =
352 readConfiguration (argc, argv, isBuiltin,
353 lScheduleInputFilename, lOnDInputFilename,
354 lFRAT5InputFilename, lFFDisutilityInputFilename,
355 lYieldInputFilename, lFareInputFilename, lLogFilename,
356 lDBUser, lDBPasswd, lDBHost, lDBPort, lDBDBName);
357
358 if (lOptionParserStatus == K_SIMCRS_EARLY_RETURN_STATUS) {
359 return 0;
360 }
361
362 // Set the database parameters
363 const stdair::BasDBParams lDBParams (lDBUser, lDBPasswd, lDBHost, lDBPort,
364 lDBDBName);
365
366 // Set the log parameters
367 std::ofstream logOutputFile;
368 // Open and clean the log outputfile
369 logOutputFile.open (lLogFilename.c_str());
370 logOutputFile.clear();
371
372 // Initialise the list of classes/buckets
373 const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
374 SIMCRS::SIMCRS_Service simcrsService (lLogParams, lCRSCode);
375
376 // Check wether or not (CSV) input files should be read
377 if (isBuiltin == true) {
378
379 // Build the sample BOM tree
380 simcrsService.buildSampleBom();
381
382 } else {
383 // Build the BOM tree from parsing input files
384 stdair::ScheduleFilePath lScheduleFilePath (lScheduleInputFilename);
385 stdair::ODFilePath lODFilePath (lOnDInputFilename);
386 stdair::FRAT5FilePath lFRAT5FilePath (lFRAT5InputFilename);
387 stdair::FFDisutilityFilePath lFFDisutilityFilePath (lFFDisutilityInputFilename);
388 const SIMFQT::FareFilePath lFareFilePath (lFareInputFilename);
389 const AIRRAC::YieldFilePath lYieldFilePath (lYieldInputFilename);
390 simcrsService.parseAndLoad (lScheduleFilePath, lODFilePath,
391 lFRAT5FilePath, lFFDisutilityFilePath,
392 lYieldFilePath, lFareFilePath);
393 }
394
395 // TODO (issue #37707): instead of building a sample, read the parameters
396 // from the command-line options, and build the corresponding
397 // booking request
398 const bool isForCRS = true;
399 const stdair::BookingRequestStruct& lBookingRequest =
400 simcrsService.buildSampleBookingRequest (isForCRS);
401
402 // Calculate the travel solutions corresponding to the given booking request
403 stdair::TravelSolutionList_T lTravelSolutionList =
404 simcrsService.calculateSegmentPathList (lBookingRequest);
405
406 // Check whether everything was fine
407 if (lTravelSolutionList.empty() == true) {
408 STDAIR_LOG_ERROR ("No travel solution has been found for: "
409 << lBookingRequest.display());
410 return -1;
411 }
412
413 // Price the travel solution
414 simcrsService.fareQuote (lBookingRequest, lTravelSolutionList);
415
416 // Choose a random travel solution: the first one.
417 stdair::TravelSolutionStruct& lChosenTravelSolution =
418 lTravelSolutionList.front();
419
420 // Get the segment path of the travel solution.
421 const stdair::KeyList_T& lsegmentDateKeyList =
422 lChosenTravelSolution.getSegmentPath();
423
424 const stdair::FareOptionList_T& lFareOptionList =
425 lChosenTravelSolution.getFareOptionList();
426
427 // Check whether everything was fine
428 if (lFareOptionList.empty() == true) {
429 STDAIR_LOG_ERROR ("No fare option for the chosen travel solution: "
430 << lChosenTravelSolution.display());
431 return -1;
432 }
433
434 //
435 const stdair::FareOptionStruct& lFareOption = lFareOptionList.front();
436 lChosenTravelSolution.setChosenFareOption (lFareOption);
437
438 // DEBUG
439 const std::string& lSegmentDateKey = lsegmentDateKeyList.front();
440 STDAIR_LOG_DEBUG ("The chosen travel solution is: " << lSegmentDateKey
441 << ", the fare is: " << lFareOption.getFare() << " Euros.");
442
443 // Make a booking (reminder: party size is 3)
444 const stdair::PartySize_T lPartySize (3);
445 const bool isSellSuccessful =
446 simcrsService.sell (lChosenTravelSolution, lPartySize);
447
448 // DEBUG
449 STDAIR_LOG_DEBUG ("Sale ('" << lBookingRequest << "'): "
450 << " successful? " << isSellSuccessful);
451
452 // DEBUG: Display the whole BOM tree
453 const std::string& lCSVDump = simcrsService.csvDisplay();
454 STDAIR_LOG_DEBUG (lCSVDump);
455
456 // Close the Log outputFile
457 logOutputFile.close();
458
459 /*
460 Note: as that program is not intended to be run on a server in
461 production, it is better not to catch the exceptions. When it
462 happens (that an exception is throwned), that way we get the
463 call stack.
464 */
465
466 return 0;
467}
void parseAndLoad(const stdair::ScheduleFilePath &, const stdair::ODFilePath &, const stdair::FRAT5FilePath &, const stdair::FFDisutilityFilePath &, const AIRRAC::YieldFilePath &, const SIMFQT::FareFilePath &)
bool sell(const stdair::TravelSolutionStruct &, const stdair::PartySize_T &)
std::string csvDisplay() const
stdair::TravelSolutionList_T calculateSegmentPathList(const stdair::BookingRequestStruct &)
void fareQuote(const stdair::BookingRequestStruct &, stdair::TravelSolutionList_T &)
stdair::BookingRequestStruct buildSampleBookingRequest(const bool isForCRS=false)
std::string CRSCode_T
int readConfiguration(int argc, char *argv[], bool &ioIsBuiltin, 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 &ioLogFilename, std::string &ioDBUser, std::string &ioDBPasswd, std::string &ioDBHost, std::string &ioDBPort, std::string &ioDBDBName)
Definition simcrs.cpp:90
int main(int argc, char *argv[])
Definition simcrs.cpp:313
const std::string K_SIMCRS_DEFAULT_DB_USER("dsim")
const std::string K_SIMCRS_DEFAULT_YIELD_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/yieldstore01.csv")
const std::string K_SIMCRS_DEFAULT_LOG_FILENAME("simcrs.log")
const std::string K_SIMCRS_DEFAULT_DB_PORT("3306")
const int K_SIMCRS_EARLY_RETURN_STATUS
Definition simcrs.cpp:87
const std::string K_SIMCRS_DEFAULT_DB_DBNAME("sim_dsim")
const std::string K_SIMCRS_DEFAULT_DB_HOST("localhost")
const std::string K_SIMCRS_DEFAULT_FRAT5_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/frat5.csv")
const std::string K_SIMCRS_DEFAULT_OND_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/ond01.csv")
const std::string K_SIMCRS_DEFAULT_FARE_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/fare01.csv")
const std::string K_SIMCRS_DEFAULT_SCHEDULE_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/schedule01.csv")
const bool K_SIMCRS_DEFAULT_BUILT_IN_INPUT
Definition simcrs.cpp:67
std::ostream & operator<<(std::ostream &os, const std::vector< T > &v)
Definition simcrs.cpp:80
const std::string K_SIMCRS_DEFAULT_FF_DISUTILITY_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/ffDisutility.csv")
const std::string K_SIMCRS_DEFAULT_DB_PASSWD("dsim")