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 BESDEBUG( "bes", " transmitting error info using transmitter ... " << endl ) ;
00408 _dhi->error_info->transmit( _transmitter, *_dhi ) ;
00409 }
00410 else if( _dhi->response_handler )
00411 {
00412 BESDEBUG( "bes", " transmitting response using transmitter ... " << endl ) ;
00413 _dhi->response_handler->transmit( _transmitter, *_dhi ) ;
00414 }
00415 }
00416 else
00417 {
00418 if( _dhi->error_info )
00419 {
00420 BESDEBUG( "bes", " transmitting error info using cout ... " << endl ) ;
00421 _dhi->error_info->print( cout ) ;
00422 }
00423 else
00424 {
00425 BESDEBUG( "bes", " Unable to transmit the response ... FAILED " << endl ) ;
00426 string err = "Unable to transmit the response, no transmitter" ;
00427 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00428 }
00429 }
00430 BESDEBUG("bes", "OK" << endl) ;
00431 }
00432
00435 void
00436 BESInterface::log_status()
00437 {
00438 }
00439
00451 void
00452 BESInterface::report_request()
00453 {
00454 BESDEBUG( "bes", "Reporting on request: " << _dhi->data[DATA_REQUEST]
00455 << " ... " << endl ) ;
00456
00457 BESReporterList::TheList()->report( *_dhi ) ;
00458
00459 BESDEBUG( "bes", "OK" << endl ) ;
00460 }
00461
00462 void
00463 BESInterface::add_end_callback( p_bes_end end )
00464 {
00465 _end_list.push_back( end ) ;
00466 }
00467
00473 void
00474 BESInterface::end_request()
00475 {
00476 BESDEBUG("bes", "Ending request: " << _dhi->data[DATA_REQUEST] << " ... " << endl ) ;
00477 end_iter i = _end_list.begin();
00478 for( ; i != _end_list.end(); i++ )
00479 {
00480 p_bes_end p = *i ;
00481 p( *_dhi ) ;
00482 }
00483
00484
00485
00486 _dhi->first_container() ;
00487 while( _dhi->container )
00488 {
00489 _dhi->container->release() ;
00490 _dhi->next_container() ;
00491 }
00492
00493 BESDEBUG("bes", "OK" << endl) ;
00494 }
00495
00498 void
00499 BESInterface::clean()
00500 {
00501 if( _dhi )
00502 _dhi->clean() ;
00503 }
00504
00517 int
00518 BESInterface::exception_manager( BESError &e )
00519 {
00520 return BESExceptionManager::TheEHM()->handle_exception( e, *_dhi ) ;
00521 }
00522
00531 void
00532 BESInterface::dump(ostream & strm) const
00533 {
00534 strm << BESIndent::LMarg << "BESInterface::dump - ("
00535 << (void *) this << ")" << endl;
00536 BESIndent::Indent();
00537
00538 if (_init_list.size()) {
00539 strm << BESIndent::LMarg << "termination functions:" << endl;
00540 BESIndent::Indent();
00541 init_iter i = _init_list.begin();
00542 for (; i != _init_list.end(); i++) {
00543 strm << BESIndent::LMarg << (void *) (*i) << endl;
00544 }
00545 BESIndent::UnIndent();
00546 } else {
00547 strm << BESIndent::LMarg << "termination functions: none" << endl;
00548 }
00549
00550 if (_end_list.size()) {
00551 strm << BESIndent::LMarg << "termination functions:" << endl;
00552 BESIndent::Indent();
00553 end_iter i = _end_list.begin();
00554 for (; i != _end_list.end(); i++) {
00555 strm << BESIndent::LMarg << (void *) (*i) << endl;
00556 }
00557 BESIndent::UnIndent();
00558 } else {
00559 strm << BESIndent::LMarg << "termination functions: none" << endl;
00560 }
00561
00562 strm << BESIndent::LMarg << "data handler interface:" << endl;
00563 BESIndent::Indent();
00564 _dhi->dump(strm);
00565 BESIndent::UnIndent();
00566
00567 if (_transmitter) {
00568 strm << BESIndent::LMarg << "transmitter:" << endl;
00569 BESIndent::Indent();
00570 _transmitter->dump(strm);
00571 BESIndent::UnIndent();
00572 } else {
00573 strm << BESIndent::LMarg << "transmitter: not set" << endl;
00574 }
00575 BESIndent::UnIndent();
00576 }