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 : _strm( output_stream ),
00071 _transmitter( 0 )
00072 {
00073 if( !output_stream )
00074 {
00075 string err = "output stream must be set in order to output responses" ;
00076 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00077 }
00078 }
00079
00080 BESInterface::~BESInterface()
00081 {
00082 }
00083
00116 int
00117 BESInterface::execute_request( const string &from )
00118 {
00119 if( !_dhi )
00120 {
00121 string err = "DataHandlerInterface can not be null" ;
00122 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00123 }
00124 _dhi->set_output_stream( _strm ) ;
00125 _dhi->data[REQUEST_FROM] = from ;
00126
00127 pid_t thepid = getpid() ;
00128 ostringstream ss ;
00129 ss << thepid ;
00130 _dhi->data[SERVER_PID] = ss.str() ;
00131
00132 int status = 0;
00133
00134
00135
00136
00137
00138 try {
00139 initialize();
00140
00141 *(BESLog::TheLog()) << _dhi->data[SERVER_PID]
00142 << " from " << _dhi->data[REQUEST_FROM]
00143 << " request received" << endl ;
00144
00145 validate_data_request();
00146 build_data_request_plan() ;
00147 execute_data_request_plan();
00148
00149
00150
00151
00152
00153
00154 _dhi->executed = true ;
00155 }
00156 catch( BESError & ex )
00157 {
00158 return exception_manager( ex ) ;
00159 }
00160 catch( bad_alloc & )
00161 {
00162 string serr = "BES out of memory" ;
00163 BESInternalFatalError ex( serr, __FILE__, __LINE__ ) ;
00164 return exception_manager( ex ) ;
00165 }
00166 catch(...) {
00167 string serr = "An undefined exception has been thrown" ;
00168 BESInternalError ex( serr, __FILE__, __LINE__ ) ;
00169 return exception_manager( ex ) ;
00170 }
00171
00172 return finish( status ) ;
00173 }
00174
00175 int
00176 BESInterface::finish( int status )
00177 {
00178 try
00179 {
00180
00181
00182
00183
00184 if( _dhi->error_info )
00185 {
00186 transmit_data();
00187 delete _dhi->error_info ;
00188 _dhi->error_info = 0 ;
00189 }
00190 }
00191 catch( BESError &ex )
00192 {
00193 status = exception_manager( ex ) ;
00194 }
00195 catch( bad_alloc & )
00196 {
00197 string serr = "BES out of memory" ;
00198 BESInternalFatalError ex( serr, __FILE__, __LINE__ ) ;
00199 status = exception_manager( ex ) ;
00200 }
00201 catch(...)
00202 {
00203 string serr = "An undefined exception has been thrown" ;
00204 BESInternalError ex( serr, __FILE__, __LINE__ ) ;
00205 status = exception_manager( ex ) ;
00206 }
00207
00208
00209
00210
00211 if( _dhi->error_info )
00212 {
00213 _dhi->error_info->print( cout ) ;
00214 delete _dhi->error_info ;
00215 _dhi->error_info = 0 ;
00216 }
00217
00218
00219
00220
00221 try
00222 {
00223 log_status();
00224 }
00225 catch( BESError &ex )
00226 {
00227 (*BESLog::TheLog()) << "Problem logging status: " << ex.get_message()
00228 << endl ;
00229 }
00230 catch( ... )
00231 {
00232 (*BESLog::TheLog()) << "Unknown problem logging status" << endl ;
00233 }
00234
00235 try
00236 {
00237 report_request();
00238 }
00239 catch( BESError &ex )
00240 {
00241 (*BESLog::TheLog()) << "Problem reporting request: " << ex.get_message()
00242 << endl ;
00243 }
00244 catch( ... )
00245 {
00246 (*BESLog::TheLog()) << "Unknown problem reporting request" << endl ;
00247 }
00248
00249 try
00250 {
00251 end_request();
00252 }
00253 catch( BESError &ex )
00254 {
00255 (*BESLog::TheLog()) << "Problem ending request: " << ex.get_message()
00256 << endl ;
00257 }
00258 catch( ... )
00259 {
00260 (*BESLog::TheLog()) << "Unknown problem ending request" << endl ;
00261 }
00262
00263 return status ;
00264 }
00265
00266 int
00267 BESInterface::finish_with_error( int status )
00268 {
00269 if( !_dhi->error_info )
00270 {
00271
00272 string serr = "Finish_with_error called with no error object" ;
00273 BESInternalError ex( serr, __FILE__, __LINE__ ) ;
00274 status = exception_manager( ex ) ;
00275 }
00276
00277 return finish( status ) ;
00278 }
00279
00280 void
00281 BESInterface::add_init_callback(p_bes_init init)
00282 {
00283 _init_list.push_back(init);
00284 }
00285
00291 void
00292 BESInterface::initialize()
00293 {
00294 BESDEBUG("bes", "Initializing request: " << _dhi->data[DATA_REQUEST] << " ... " << endl ) ;
00295 bool do_continue = true;
00296 init_iter i = _init_list.begin();
00297
00298 for( ; i != _init_list.end() && do_continue == true; i++ )
00299 {
00300 p_bes_init p = *i ;
00301 do_continue = p( *_dhi ) ;
00302 }
00303
00304 if( !do_continue )
00305 {
00306 BESDEBUG("bes", "FAILED" << endl) ;
00307 string se = "Initialization callback failed, exiting";
00308 throw BESInternalError( se, __FILE__, __LINE__ ) ;
00309 }
00310 else
00311 {
00312 BESDEBUG("bes", "OK" << endl) ;
00313 }
00314 }
00315
00318 void
00319 BESInterface::validate_data_request()
00320 {
00321 }
00322
00336 void
00337 BESInterface::execute_data_request_plan()
00338 {
00339 BESDEBUG("bes", "Executing request: " << _dhi->data[DATA_REQUEST] << " ... " << endl ) ;
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
00355 invoke_aggregation();
00356
00357
00358 transmit_data();
00359 }
00360
00363 void
00364 BESInterface::invoke_aggregation()
00365 {
00366 if( _dhi->data[AGG_CMD] != "" )
00367 {
00368 BESDEBUG("bes", "aggregating with: " << _dhi->data[AGG_CMD] << " ... "<< endl ) ;
00369 BESAggregationServer *agg =
00370 BESAggFactory::TheFactory()->find_handler( _dhi->data[AGG_HANDLER] );
00371 if( agg )
00372 {
00373 agg->aggregate( *_dhi ) ;
00374 }
00375 else
00376 {
00377 BESDEBUG("bes", "FAILED" << endl) ;
00378 string se = "The aggregation handler " + _dhi->data[AGG_HANDLER]
00379 + "does not exist" ;
00380 throw BESInternalError( se, __FILE__, __LINE__ ) ;
00381 }
00382 BESDEBUG("bes", "OK" << endl) ;
00383 }
00384 }
00385
00399 void
00400 BESInterface::transmit_data()
00401 {
00402 BESDEBUG("bes", "Transmitting request: " << _dhi->data[DATA_REQUEST] << endl) ;
00403 if (_transmitter)
00404 {
00405 if( _dhi->error_info )
00406 {
00407 ostringstream strm ;
00408 _dhi->error_info->print( strm ) ;
00409 (*BESLog::TheLog()) << strm.str() << endl ;
00410 BESDEBUG( "bes", " transmitting error info using transmitter ... "
00411 << endl << strm.str() << endl ) ;
00412 _dhi->error_info->transmit( _transmitter, *_dhi ) ;
00413 }
00414 else if( _dhi->response_handler )
00415 {
00416 BESDEBUG( "bes", " transmitting response using transmitter ... " << endl ) ;
00417 _dhi->response_handler->transmit( _transmitter, *_dhi ) ;
00418 }
00419 }
00420 else
00421 {
00422 if( _dhi->error_info )
00423 {
00424 BESDEBUG( "bes", " transmitting error info using cout ... " << endl ) ;
00425 _dhi->error_info->print( cout ) ;
00426 }
00427 else
00428 {
00429 BESDEBUG( "bes", " Unable to transmit the response ... FAILED " << endl ) ;
00430 string err = "Unable to transmit the response, no transmitter" ;
00431 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00432 }
00433 }
00434 BESDEBUG("bes", "OK" << endl) ;
00435 }
00436
00439 void
00440 BESInterface::log_status()
00441 {
00442 }
00443
00455 void
00456 BESInterface::report_request()
00457 {
00458 BESDEBUG( "bes", "Reporting on request: " << _dhi->data[DATA_REQUEST]
00459 << " ... " << endl ) ;
00460
00461 BESReporterList::TheList()->report( *_dhi ) ;
00462
00463 BESDEBUG( "bes", "OK" << endl ) ;
00464 }
00465
00466 void
00467 BESInterface::add_end_callback( p_bes_end end )
00468 {
00469 _end_list.push_back( end ) ;
00470 }
00471
00477 void
00478 BESInterface::end_request()
00479 {
00480 BESDEBUG("bes", "Ending request: " << _dhi->data[DATA_REQUEST] << " ... " << endl ) ;
00481 end_iter i = _end_list.begin();
00482 for( ; i != _end_list.end(); i++ )
00483 {
00484 p_bes_end p = *i ;
00485 p( *_dhi ) ;
00486 }
00487
00488
00489
00490 _dhi->first_container() ;
00491 while( _dhi->container )
00492 {
00493 _dhi->container->release() ;
00494 _dhi->next_container() ;
00495 }
00496
00497 BESDEBUG("bes", "OK" << endl) ;
00498 }
00499
00502 void
00503 BESInterface::clean()
00504 {
00505 if( _dhi )
00506 _dhi->clean() ;
00507 }
00508
00521 int
00522 BESInterface::exception_manager( BESError &e )
00523 {
00524 return BESExceptionManager::TheEHM()->handle_exception( e, *_dhi ) ;
00525 }
00526
00535 void
00536 BESInterface::dump(ostream & strm) const
00537 {
00538 strm << BESIndent::LMarg << "BESInterface::dump - ("
00539 << (void *) this << ")" << endl;
00540 BESIndent::Indent();
00541
00542 if (_init_list.size()) {
00543 strm << BESIndent::LMarg << "termination functions:" << endl;
00544 BESIndent::Indent();
00545 init_iter i = _init_list.begin();
00546 for (; i != _init_list.end(); i++) {
00547 strm << BESIndent::LMarg << (void *) (*i) << endl;
00548 }
00549 BESIndent::UnIndent();
00550 } else {
00551 strm << BESIndent::LMarg << "termination functions: none" << endl;
00552 }
00553
00554 if (_end_list.size()) {
00555 strm << BESIndent::LMarg << "termination functions:" << endl;
00556 BESIndent::Indent();
00557 end_iter i = _end_list.begin();
00558 for (; i != _end_list.end(); i++) {
00559 strm << BESIndent::LMarg << (void *) (*i) << endl;
00560 }
00561 BESIndent::UnIndent();
00562 } else {
00563 strm << BESIndent::LMarg << "termination functions: none" << endl;
00564 }
00565
00566 strm << BESIndent::LMarg << "data handler interface:" << endl;
00567 BESIndent::Indent();
00568 _dhi->dump(strm);
00569 BESIndent::UnIndent();
00570
00571 if (_transmitter) {
00572 strm << BESIndent::LMarg << "transmitter:" << endl;
00573 BESIndent::Indent();
00574 _transmitter->dump(strm);
00575 BESIndent::UnIndent();
00576 } else {
00577 strm << BESIndent::LMarg << "transmitter: not set" << endl;
00578 }
00579 BESIndent::UnIndent();
00580 }