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 << " [" << _dhi->data[DATA_REQUEST] << "]"
00144 << endl ;
00145
00146 validate_data_request();
00147 build_data_request_plan() ;
00148 execute_data_request_plan();
00149
00150
00151
00152
00153
00154
00155 _dhi->executed = true ;
00156 }
00157 catch( BESError & ex )
00158 {
00159 return exception_manager( ex ) ;
00160 }
00161 catch( bad_alloc & )
00162 {
00163 string serr = "BES out of memory" ;
00164 BESInternalFatalError ex( serr, __FILE__, __LINE__ ) ;
00165 return exception_manager( ex ) ;
00166 }
00167 catch(...) {
00168 string serr = "An undefined exception has been thrown" ;
00169 BESInternalError ex( serr, __FILE__, __LINE__ ) ;
00170 return exception_manager( ex ) ;
00171 }
00172
00173 return finish( status ) ;
00174 }
00175
00176 int
00177 BESInterface::finish( int status )
00178 {
00179 try
00180 {
00181
00182
00183
00184
00185 if( _dhi->error_info )
00186 {
00187 transmit_data();
00188 delete _dhi->error_info ;
00189 _dhi->error_info = 0 ;
00190 }
00191 }
00192 catch( BESError &ex )
00193 {
00194 status = exception_manager( ex ) ;
00195 }
00196 catch( bad_alloc & )
00197 {
00198 string serr = "BES out of memory" ;
00199 BESInternalFatalError ex( serr, __FILE__, __LINE__ ) ;
00200 status = exception_manager( ex ) ;
00201 }
00202 catch(...)
00203 {
00204 string serr = "An undefined exception has been thrown" ;
00205 BESInternalError ex( serr, __FILE__, __LINE__ ) ;
00206 status = exception_manager( ex ) ;
00207 }
00208
00209
00210
00211
00212 if( _dhi->error_info )
00213 {
00214 _dhi->error_info->print( cout ) ;
00215 delete _dhi->error_info ;
00216 _dhi->error_info = 0 ;
00217 }
00218
00219
00220
00221
00222 try
00223 {
00224 log_status();
00225 }
00226 catch( BESError &ex )
00227 {
00228 (*BESLog::TheLog()) << "Problem logging status: " << ex.get_message()
00229 << endl ;
00230 }
00231 catch( ... )
00232 {
00233 (*BESLog::TheLog()) << "Unknown problem logging status" << endl ;
00234 }
00235
00236 try
00237 {
00238 report_request();
00239 }
00240 catch( BESError &ex )
00241 {
00242 (*BESLog::TheLog()) << "Problem reporting request: " << ex.get_message()
00243 << endl ;
00244 }
00245 catch( ... )
00246 {
00247 (*BESLog::TheLog()) << "Unknown problem reporting request" << endl ;
00248 }
00249
00250 try
00251 {
00252 end_request();
00253 }
00254 catch( BESError &ex )
00255 {
00256 (*BESLog::TheLog()) << "Problem ending request: " << ex.get_message()
00257 << endl ;
00258 }
00259 catch( ... )
00260 {
00261 (*BESLog::TheLog()) << "Unknown problem ending request" << endl ;
00262 }
00263
00264 return status ;
00265 }
00266
00267 int
00268 BESInterface::finish_with_error( int status )
00269 {
00270 if( !_dhi->error_info )
00271 {
00272
00273 string serr = "Finish_with_error called with no error object" ;
00274 BESInternalError ex( serr, __FILE__, __LINE__ ) ;
00275 status = exception_manager( ex ) ;
00276 }
00277
00278 return finish( status ) ;
00279 }
00280
00281 void
00282 BESInterface::add_init_callback(p_bes_init init)
00283 {
00284 _init_list.push_back(init);
00285 }
00286
00292 void
00293 BESInterface::initialize()
00294 {
00295 BESDEBUG("bes", "Initializing request: " << _dhi->data[DATA_REQUEST] << " ... " << endl )
00296 bool do_continue = true;
00297 init_iter i = _init_list.begin();
00298
00299 for( ; i != _init_list.end() && do_continue == true; i++ )
00300 {
00301 p_bes_init p = *i ;
00302 do_continue = p( *_dhi ) ;
00303 }
00304
00305 if( !do_continue )
00306 {
00307 BESDEBUG("bes", "FAILED" << endl)
00308 string se = "Initialization callback failed, exiting";
00309 throw BESInternalError( se, __FILE__, __LINE__ ) ;
00310 }
00311 else
00312 {
00313 BESDEBUG("bes", "OK" << endl)
00314 }
00315 }
00316
00319 void
00320 BESInterface::validate_data_request()
00321 {
00322 }
00323
00337 void
00338 BESInterface::execute_data_request_plan()
00339 {
00340 BESDEBUG("bes", "Executing request: " << _dhi->data[DATA_REQUEST] << " ... " << endl )
00341 BESResponseHandler *rh = _dhi->response_handler ;
00342 if( rh )
00343 {
00344 rh->execute( *_dhi ) ;
00345 }
00346 else
00347 {
00348 BESDEBUG("bes", "FAILED" << endl)
00349 string se = "The response handler \"" + _dhi->action
00350 + "\" does not exist" ;
00351 throw BESInternalError( se, __FILE__, __LINE__ ) ;
00352 }
00353 BESDEBUG("bes", "OK" << endl)
00354
00355
00356 invoke_aggregation();
00357
00358
00359 transmit_data();
00360 }
00361
00364 void
00365 BESInterface::invoke_aggregation()
00366 {
00367 if( _dhi->data[AGG_CMD] != "" )
00368 {
00369 BESDEBUG("bes", "aggregating with: " << _dhi->data[AGG_CMD] << " ... "<< endl )
00370 BESAggregationServer *agg =
00371 BESAggFactory::TheFactory()->find_handler( _dhi->data[AGG_HANDLER] );
00372 if( agg )
00373 {
00374 agg->aggregate( *_dhi ) ;
00375 }
00376 else
00377 {
00378 BESDEBUG("bes", "FAILED" << endl)
00379 string se = "The aggregation handler " + _dhi->data[AGG_HANDLER]
00380 + "does not exist" ;
00381 throw BESInternalError( se, __FILE__, __LINE__ ) ;
00382 }
00383 BESDEBUG("bes", "OK" << endl)
00384 }
00385 }
00386
00400 void
00401 BESInterface::transmit_data()
00402 {
00403 BESDEBUG("bes", "Transmitting request: " << _dhi->data[DATA_REQUEST] << endl)
00404 if (_transmitter)
00405 {
00406 if( _dhi->error_info )
00407 {
00408 BESDEBUG( "bes", " transmitting error info using transmitter ... " << endl )
00409 _dhi->error_info->transmit( _transmitter, *_dhi ) ;
00410 }
00411 else if( _dhi->response_handler )
00412 {
00413 BESDEBUG( "bes", " transmitting response using transmitter ... " << endl )
00414 _dhi->response_handler->transmit( _transmitter, *_dhi ) ;
00415 }
00416 }
00417 else
00418 {
00419 if( _dhi->error_info )
00420 {
00421 BESDEBUG( "bes", " transmitting error info using cout ... " << endl )
00422 _dhi->error_info->print( cout ) ;
00423 }
00424 else
00425 {
00426 BESDEBUG( "bes", " Unable to transmit the response ... FAILED " << endl )
00427 string err = "Unable to transmit the response, no transmitter" ;
00428 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00429 }
00430 }
00431 BESDEBUG("bes", "OK" << endl)
00432 }
00433
00436 void
00437 BESInterface::log_status()
00438 {
00439 }
00440
00452 void
00453 BESInterface::report_request()
00454 {
00455 BESDEBUG( "bes", "Reporting on request: " << _dhi->data[DATA_REQUEST]
00456 << " ... " << endl )
00457
00458 BESReporterList::TheList()->report( *_dhi ) ;
00459
00460 BESDEBUG( "bes", "OK" << endl )
00461 }
00462
00463 void
00464 BESInterface::add_end_callback( p_bes_end end )
00465 {
00466 _end_list.push_back( end ) ;
00467 }
00468
00474 void
00475 BESInterface::end_request()
00476 {
00477 BESDEBUG("bes", "Ending request: " << _dhi->data[DATA_REQUEST] << " ... " << endl )
00478 end_iter i = _end_list.begin();
00479 for( ; i != _end_list.end(); i++ )
00480 {
00481 p_bes_end p = *i ;
00482 p( *_dhi ) ;
00483 }
00484
00485
00486
00487 _dhi->first_container() ;
00488 while( _dhi->container )
00489 {
00490 _dhi->container->release() ;
00491 _dhi->next_container() ;
00492 }
00493
00494 BESDEBUG("bes", "OK" << endl)
00495 }
00496
00499 void
00500 BESInterface::clean()
00501 {
00502 if( _dhi )
00503 _dhi->clean() ;
00504 }
00505
00518 int
00519 BESInterface::exception_manager( BESError &e )
00520 {
00521 return BESExceptionManager::TheEHM()->handle_exception( e, *_dhi ) ;
00522 }
00523
00532 void
00533 BESInterface::dump(ostream & strm) const
00534 {
00535 strm << BESIndent::LMarg << "BESInterface::dump - ("
00536 << (void *) this << ")" << endl;
00537 BESIndent::Indent();
00538
00539 if (_init_list.size()) {
00540 strm << BESIndent::LMarg << "termination functions:" << endl;
00541 BESIndent::Indent();
00542 init_iter i = _init_list.begin();
00543 for (; i != _init_list.end(); i++) {
00544 strm << BESIndent::LMarg << (void *) (*i) << endl;
00545 }
00546 BESIndent::UnIndent();
00547 } else {
00548 strm << BESIndent::LMarg << "termination functions: none" << endl;
00549 }
00550
00551 if (_end_list.size()) {
00552 strm << BESIndent::LMarg << "termination functions:" << endl;
00553 BESIndent::Indent();
00554 end_iter i = _end_list.begin();
00555 for (; i != _end_list.end(); i++) {
00556 strm << BESIndent::LMarg << (void *) (*i) << endl;
00557 }
00558 BESIndent::UnIndent();
00559 } else {
00560 strm << BESIndent::LMarg << "termination functions: none" << endl;
00561 }
00562
00563 strm << BESIndent::LMarg << "data handler interface:" << endl;
00564 BESIndent::Indent();
00565 _dhi->dump(strm);
00566 BESIndent::UnIndent();
00567
00568 if (_transmitter) {
00569 strm << BESIndent::LMarg << "transmitter:" << endl;
00570 BESIndent::Indent();
00571 _transmitter->dump(strm);
00572 BESIndent::UnIndent();
00573 } else {
00574 strm << BESIndent::LMarg << "transmitter: not set" << endl;
00575 }
00576 BESIndent::UnIndent();
00577 }