00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "config.h"
00034
00035 #include <string>
00036 #include <sstream>
00037 #include <iostream>
00038
00039 #if HAVE_UNISTD_H
00040 #include <unistd.h>
00041 #endif
00042
00043 using std::string;
00044 using std::ostringstream;
00045 using std::bad_alloc;
00046 using std::cout;
00047
00048 #include "BESInterface.h"
00049
00050 #include "TheBESKeys.h"
00051 #include "BESResponseHandler.h"
00052 #include "BESAggFactory.h"
00053 #include "BESAggregationServer.h"
00054 #include "BESReporterList.h"
00055
00056 #include "BESExceptionManager.h"
00057
00058 #include "BESDataNames.h"
00059
00060 #include "BESDebug.h"
00061 #include "BESInternalError.h"
00062 #include "BESInternalFatalError.h"
00063
00064 #include "BESLog.h"
00065
00066 list < p_bes_init > BESInterface::_init_list;
00067 list < p_bes_end > BESInterface::_end_list;
00068
00069 BESInterface::BESInterface( ostream *output_stream )
00070 : _transmitter(0)
00071 {
00072 if( !output_stream )
00073 {
00074 string err = "output stream must be set in order to output responses" ;
00075 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00076 }
00077 _dhi.set_output_stream( output_stream ) ;
00078 }
00079
00080 BESInterface::~BESInterface()
00081 {
00082 }
00083
00116 int
00117 BESInterface::execute_request( const string &from )
00118 {
00119 _dhi.data[REQUEST_FROM] = from ;
00120
00121 pid_t thepid = getpid() ;
00122 ostringstream ss ;
00123 ss << thepid ;
00124 _dhi.data[SERVER_PID] = ss.str() ;
00125
00126 *(BESLog::TheLog()) << _dhi.data[SERVER_PID]
00127 << " from " << _dhi.data[REQUEST_FROM]
00128 << " [" << _dhi.data[DATA_REQUEST] << "]"
00129 << endl ;
00130
00131 int status = 0;
00132
00133
00134
00135
00136
00137 try {
00138 initialize();
00139 validate_data_request();
00140 build_data_request_plan();
00141 execute_data_request_plan();
00142 invoke_aggregation();
00143 transmit_data();
00144 }
00145 catch( BESError & ex )
00146 {
00147 return exception_manager( ex ) ;
00148 }
00149 catch( bad_alloc & )
00150 {
00151 string serr = "BES out of memory" ;
00152 BESInternalFatalError ex( serr, __FILE__, __LINE__ ) ;
00153 return exception_manager( ex ) ;
00154 }
00155 catch(...) {
00156 string serr = "An undefined exception has been thrown" ;
00157 BESInternalError ex( serr, __FILE__, __LINE__ ) ;
00158 return exception_manager( ex ) ;
00159 }
00160
00161 return finish( status ) ;
00162 }
00163
00164 int
00165 BESInterface::finish( int status )
00166 {
00167 try
00168 {
00169
00170
00171
00172 if( _dhi.error_info )
00173 {
00174 transmit_data();
00175 delete _dhi.error_info ;
00176 _dhi.error_info = 0 ;
00177 }
00178 }
00179 catch( BESError &ex )
00180 {
00181 status = exception_manager( ex ) ;
00182 }
00183 catch( bad_alloc & )
00184 {
00185 string serr = "BES out of memory" ;
00186 BESInternalFatalError ex( serr, __FILE__, __LINE__ ) ;
00187 status = exception_manager( ex ) ;
00188 }
00189 catch(...)
00190 {
00191 string serr = "An undefined exception has been thrown" ;
00192 BESInternalError ex( serr, __FILE__, __LINE__ ) ;
00193 status = exception_manager( ex ) ;
00194 }
00195
00196
00197
00198 if( _dhi.error_info )
00199 {
00200 _dhi.error_info->print( cout ) ;
00201 delete _dhi.error_info ;
00202 _dhi.error_info = 0 ;
00203 }
00204
00205
00206
00207
00208 try
00209 {
00210 log_status();
00211 }
00212 catch( BESError &ex )
00213 {
00214 (*BESLog::TheLog()) << "Problem logging status: " << ex.get_message()
00215 << endl ;
00216 }
00217 catch( ... )
00218 {
00219 (*BESLog::TheLog()) << "Unknown problem logging status" << endl ;
00220 }
00221
00222 try
00223 {
00224 report_request();
00225 }
00226 catch( BESError &ex )
00227 {
00228 (*BESLog::TheLog()) << "Problem reporting request: " << ex.get_message()
00229 << endl ;
00230 }
00231 catch( ... )
00232 {
00233 (*BESLog::TheLog()) << "Unknown problem reporting request" << endl ;
00234 }
00235
00236 try
00237 {
00238 end_request();
00239 }
00240 catch( BESError &ex )
00241 {
00242 (*BESLog::TheLog()) << "Problem ending request: " << ex.get_message()
00243 << endl ;
00244 }
00245 catch( ... )
00246 {
00247 (*BESLog::TheLog()) << "Unknown problem ending request" << endl ;
00248 }
00249
00250 return status ;
00251 }
00252
00253 int
00254 BESInterface::finish_with_error( int status )
00255 {
00256 if( !_dhi.error_info )
00257 {
00258
00259 string serr = "Finish_with_error called with no error object" ;
00260 BESInternalError ex( serr, __FILE__, __LINE__ ) ;
00261 status = exception_manager( ex ) ;
00262 }
00263
00264 return finish( status ) ;
00265 }
00266
00267 void
00268 BESInterface::add_init_callback(p_bes_init init)
00269 {
00270 _init_list.push_back(init);
00271 }
00272
00278 void
00279 BESInterface::initialize()
00280 {
00281 BESDEBUG("bes", "Initializing request: " << _dhi.data[DATA_REQUEST] << " ... ")
00282 bool do_continue = true;
00283 init_iter i = _init_list.begin();
00284
00285 for( ; i != _init_list.end() && do_continue == true; i++ )
00286 {
00287 p_bes_init p = *i ;
00288 do_continue = p( _dhi ) ;
00289 }
00290
00291 if( !do_continue )
00292 {
00293 BESDEBUG("bes", "FAILED" << endl)
00294 string se = "Initialization callback failed, exiting";
00295 throw BESInternalError( se, __FILE__, __LINE__ ) ;
00296 }
00297 else
00298 {
00299 BESDEBUG("bes", "OK" << endl)
00300 }
00301 }
00302
00305 void
00306 BESInterface::validate_data_request()
00307 {
00308 }
00309
00318 void
00319 BESInterface::build_data_request_plan()
00320 {
00321 }
00322
00336 void
00337 BESInterface::execute_data_request_plan()
00338 {
00339 BESDEBUG("bes", "Executing request: " << _dhi.data[DATA_REQUEST] << " ... ")
00340 BESResponseHandler *rh = _dhi.response_handler ;
00341 if( rh )
00342 {
00343 rh->execute( _dhi ) ;
00344 }
00345 else
00346 {
00347 BESDEBUG("bes", "FAILED" << endl)
00348 string se = "The response handler \"" + _dhi.action
00349 + "\" does not exist" ;
00350 throw BESInternalError( se, __FILE__, __LINE__ ) ;
00351 }
00352 BESDEBUG("bes", "OK" << endl)
00353 }
00354
00357 void
00358 BESInterface::invoke_aggregation()
00359 {
00360 if( _dhi.data[AGG_CMD] != "" )
00361 {
00362 BESDEBUG("bes", "aggregating with: " << _dhi.data[AGG_CMD] << " ... ")
00363 BESAggregationServer *agg =
00364 BESAggFactory::TheFactory()->find_handler(_dhi.
00365 data[AGG_HANDLER]);
00366 if( agg )
00367 {
00368 agg->aggregate( _dhi ) ;
00369 }
00370 else
00371 {
00372 BESDEBUG("bes", "FAILED" << endl)
00373 string se = "The aggregation handler " + _dhi.data[AGG_HANDLER]
00374 + "does not exist" ;
00375 throw BESInternalError( se, __FILE__, __LINE__ ) ;
00376 }
00377 BESDEBUG("bes", "OK" << endl)
00378 }
00379 }
00380
00394 void
00395 BESInterface::transmit_data()
00396 {
00397 BESDEBUG("bes", "Transmitting request: " << _dhi.data[DATA_REQUEST] << endl)
00398 if (_transmitter)
00399 {
00400 if( _dhi.error_info )
00401 {
00402 BESDEBUG( "bes", " transmitting error info using transmitter ... " )
00403 _dhi.error_info->transmit( _transmitter, _dhi ) ;
00404 }
00405 else if( _dhi.response_handler )
00406 {
00407 BESDEBUG( "bes", " transmitting response using transmitter ... " )
00408 _dhi.response_handler->transmit( _transmitter, _dhi ) ;
00409 }
00410 }
00411 else
00412 {
00413 if( _dhi.error_info )
00414 {
00415 BESDEBUG( "bes", " transmitting error info using cout ... " )
00416 _dhi.error_info->print( cout ) ;
00417 }
00418 else
00419 {
00420 BESDEBUG( "bes", " Unable to transmit the response ... FAILED " )
00421 string err = "Unable to transmit the response, no transmitter" ;
00422 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00423 }
00424 }
00425 BESDEBUG("bes", "OK" << endl)
00426 }
00427
00430 void
00431 BESInterface::log_status()
00432 {
00433 }
00434
00446 void
00447 BESInterface::report_request()
00448 {
00449 BESDEBUG("bes", "Reporting on request: " << _dhi.
00450 data[DATA_REQUEST] << " ... ")
00451 BESReporterList::TheList()->report(_dhi);
00452 BESDEBUG("bes", "OK" << endl)
00453 }
00454
00455 void
00456 BESInterface::add_end_callback(p_bes_end end)
00457 {
00458 _end_list.push_back(end);
00459 }
00460
00466 void
00467 BESInterface::end_request()
00468 {
00469 BESDEBUG("bes", "Ending request: " << _dhi.data[DATA_REQUEST] << " ... ")
00470 end_iter i = _end_list.begin();
00471 for (; i != _end_list.end(); i++) {
00472 p_bes_end p = *i;
00473 p(_dhi);
00474 }
00475
00476
00477
00478 _dhi.first_container() ;
00479 while( _dhi.container )
00480 {
00481 _dhi.container->release() ;
00482 _dhi.next_container() ;
00483 }
00484
00485 BESDEBUG("bes", "OK" << endl)
00486 }
00487
00490 void
00491 BESInterface::clean()
00492 {
00493 if (_dhi.response_handler)
00494 delete _dhi.response_handler;
00495 _dhi.response_handler = 0;
00496 }
00497
00510 int
00511 BESInterface::exception_manager( BESError &e )
00512 {
00513 return BESExceptionManager::TheEHM()->handle_exception( e, _dhi ) ;
00514 }
00515
00524 void
00525 BESInterface::dump(ostream & strm) const
00526 {
00527 strm << BESIndent::LMarg << "BESInterface::dump - ("
00528 << (void *) this << ")" << endl;
00529 BESIndent::Indent();
00530
00531 if (_init_list.size()) {
00532 strm << BESIndent::LMarg << "termination functions:" << endl;
00533 BESIndent::Indent();
00534 init_iter i = _init_list.begin();
00535 for (; i != _init_list.end(); i++) {
00536 strm << BESIndent::LMarg << (void *) (*i) << endl;
00537 }
00538 BESIndent::UnIndent();
00539 } else {
00540 strm << BESIndent::LMarg << "termination functions: none" << endl;
00541 }
00542
00543 if (_end_list.size()) {
00544 strm << BESIndent::LMarg << "termination functions:" << endl;
00545 BESIndent::Indent();
00546 end_iter i = _end_list.begin();
00547 for (; i != _end_list.end(); i++) {
00548 strm << BESIndent::LMarg << (void *) (*i) << endl;
00549 }
00550 BESIndent::UnIndent();
00551 } else {
00552 strm << BESIndent::LMarg << "termination functions: none" << endl;
00553 }
00554
00555 strm << BESIndent::LMarg << "data handler interface:" << endl;
00556 BESIndent::Indent();
00557 _dhi.dump(strm);
00558 BESIndent::UnIndent();
00559
00560 if (_transmitter) {
00561 strm << BESIndent::LMarg << "transmitter:" << endl;
00562 BESIndent::Indent();
00563 _transmitter->dump(strm);
00564 BESIndent::UnIndent();
00565 } else {
00566 strm << BESIndent::LMarg << "transmitter: not set" << endl;
00567 }
00568 BESIndent::UnIndent();
00569 }