BESXMLInterface.cc
Go to the documentation of this file.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 <iostream>
00034 #include <sstream>
00035
00036 using std::endl ;
00037 using std::cout ;
00038 using std::stringstream ;
00039
00040 #include "BESXMLInterface.h"
00041 #include "BESXMLCommand.h"
00042 #include "BESXMLUtils.h"
00043 #include "BESDataNames.h"
00044 #include "BESDebug.h"
00045 #include "BESLog.h"
00046 #include "BESSyntaxUserError.h"
00047 #include "BESReturnManager.h"
00048
00049 BESXMLInterface::BESXMLInterface( const string &xml_doc, ostream *strm )
00050 : BESBasicInterface( strm )
00051 {
00052 _dhi = &_base_dhi ;
00053 _dhi->data[DATA_REQUEST] = "xml document" ;
00054 _dhi->data["XMLDoc"] = xml_doc ;
00055 }
00056
00057 BESXMLInterface::~BESXMLInterface()
00058 {
00059 clean() ;
00060 }
00061
00062 int
00063 BESXMLInterface::execute_request( const string &from )
00064 {
00065 return BESBasicInterface::execute_request( from ) ;
00066 }
00067
00070 void
00071 BESXMLInterface::initialize()
00072 {
00073 BESBasicInterface::initialize() ;
00074 }
00075
00078 void
00079 BESXMLInterface::validate_data_request()
00080 {
00081 BESBasicInterface::validate_data_request() ;
00082 }
00083
00086 void
00087 BESXMLInterface::build_data_request_plan()
00088 {
00089 BESDEBUG( "besxml", "building request plan for xml document: "
00090 << endl << _dhi->data["XMLDoc"] << endl ) ;
00091 if( BESLog::TheLog()->is_verbose() )
00092 {
00093 *(BESLog::TheLog()) << _dhi->data[SERVER_PID]
00094 << " from " << _dhi->data[REQUEST_FROM]
00095 << "] building" << endl ;
00096 }
00097
00098 LIBXML_TEST_VERSION
00099
00100 xmlDoc *doc = NULL ;
00101 xmlNode *root_element = NULL ;
00102 xmlNode *current_node = NULL ;
00103
00104 try
00105 {
00106
00107 vector<string> parseerrors ;
00108 xmlSetGenericErrorFunc( (void *)&parseerrors, BESXMLUtils::XMLErrorFunc );
00109
00110 doc = xmlParseDoc( (unsigned char *)_dhi->data["XMLDoc"].c_str() ) ;
00111 if( doc == NULL )
00112 {
00113 string err = "Problem parsing the request xml document:\n" ;
00114 bool isfirst = true ;
00115 vector<string>::const_iterator i = parseerrors.begin() ;
00116 vector<string>::const_iterator e = parseerrors.end() ;
00117 for( ; i != e; i++ )
00118 {
00119 if( !isfirst && (*i).compare( 0, 6, "Entity" ) == 0 )
00120 {
00121 err += "\n" ;
00122 }
00123 err += (*i) ;
00124 isfirst = false ;
00125 }
00126 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00127 }
00128
00129
00130 root_element = xmlDocGetRootElement( doc ) ;
00131 if( !root_element )
00132 {
00133 string err = "There is no root element in the xml document" ;
00134 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00135 }
00136
00137 string root_name ;
00138 string root_val ;
00139 map< string, string> props ;
00140 BESXMLUtils::GetNodeInfo( root_element, root_name, root_val, props ) ;
00141 if( root_name != "request" )
00142 {
00143 string err = (string)"The root element should be a request element, "
00144 + "name is " + (char *)root_element->name ;
00145 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00146 }
00147 if( root_val != "" )
00148 {
00149 string err = (string)"The request element must not contain a value, "
00150 + root_val ;
00151 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00152 }
00153
00154
00155 string &reqId = props[REQUEST_ID] ;
00156 if( reqId.empty() )
00157 {
00158 string err = (string)"request id value empty" ;
00159 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00160 }
00161 _dhi->data[REQUEST_ID] = reqId ;
00162 BESDEBUG( "besxml", "request id = " << _dhi->data[REQUEST_ID]
00163 << endl ) ;
00164
00165
00166
00167 bool has_response = false ;
00168 current_node = root_element->children ;
00169
00170 while( current_node )
00171 {
00172 if( current_node->type == XML_ELEMENT_NODE )
00173 {
00174
00175
00176 string node_name = (char *)current_node->name ;
00177 BESDEBUG( "besxml", "looking for command " << node_name
00178 << endl ) ;
00179 p_xmlcmd_builder bldr = BESXMLCommand::find_command( node_name ) ;
00180 if( bldr )
00181 {
00182 BESXMLCommand *current_cmd = bldr( _base_dhi ) ;
00183 if( !current_cmd )
00184 {
00185 string err = (string)"Failed to build command object for "
00186 + node_name ;
00187 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00188 }
00189
00190
00191 _cmd_list.push_back( current_cmd ) ;
00192
00193
00194
00195 bool cmd_has_response = current_cmd->has_response() ;
00196 if( has_response && cmd_has_response )
00197 {
00198 string err = "Multiple responses not allowed" ;
00199 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00200 }
00201 has_response = cmd_has_response ;
00202
00203
00204 BESDEBUG( "besxml", "parse request using " << node_name
00205 << endl ) ;
00206 current_cmd->parse_request( current_node ) ;
00207
00208 BESDataHandlerInterface ¤t_dhi = current_cmd->get_dhi();
00209 BESDEBUG( "besxml", node_name << " parsed request, dhi = "
00210 << current_dhi << endl ) ;
00211 string returnAs = current_dhi.data[RETURN_CMD] ;
00212 if( returnAs != "" )
00213 {
00214 BESDEBUG( "xml", "Finding transmitter: " << returnAs
00215 << " ... " << endl ) ;
00216 BESTransmitter *transmitter =
00217 BESReturnManager::TheManager()->find_transmitter( returnAs ) ;
00218 if( !transmitter )
00219 {
00220 string s = (string)"Unable to find transmitter "
00221 + returnAs ;
00222 throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ;
00223 }
00224 BESDEBUG( "xml", "OK" << endl ) ;
00225 }
00226 }
00227 else
00228 {
00229 string err = (string)"Unable to find command for "
00230 + node_name ;
00231 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00232 }
00233 }
00234 current_node = current_node->next ;
00235 }
00236 }
00237 catch( BESError &e )
00238 {
00239 xmlFreeDoc( doc ) ;
00240 throw e ;
00241 }
00242
00243 xmlFreeDoc( doc ) ;
00244 #if 0
00245
00246
00247 xmlCleanupParser() ;
00248 #endif
00249 BESDEBUG( "besxml", "Done building request plan" << endl ) ;
00250
00251 BESBasicInterface::build_data_request_plan() ;
00252 }
00253
00256 void
00257 BESXMLInterface::execute_data_request_plan()
00258 {
00259 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00260 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00261 for( ; i != e; i++ )
00262 {
00263 (*i)->prep_request() ;
00264 _dhi = &(*i)->get_dhi() ;
00265 BESBasicInterface::execute_data_request_plan() ;
00266 }
00267 }
00268
00271 void
00272 BESXMLInterface::invoke_aggregation()
00273 {
00274 BESBasicInterface::invoke_aggregation() ;
00275 }
00276
00279 void
00280 BESXMLInterface::transmit_data()
00281 {
00282 string returnAs = _dhi->data[RETURN_CMD] ;
00283 if( returnAs != "" )
00284 {
00285 BESDEBUG( "xml", "Setting transmitter: " << returnAs
00286 << " ... " << endl ) ;
00287 _transmitter =
00288 BESReturnManager::TheManager()->find_transmitter( returnAs ) ;
00289 if( !_transmitter )
00290 {
00291 string s = (string)"Unable to find transmitter "
00292 + returnAs ;
00293 throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ;
00294 }
00295 BESDEBUG( "xml", "OK" << endl ) ;
00296 }
00297
00298 BESBasicInterface::transmit_data() ;
00299 }
00300
00305 void
00306 BESXMLInterface::log_status()
00307 {
00308 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00309 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00310 for( ; i != e; i++ )
00311 {
00312 _dhi = &(*i)->get_dhi() ;
00313 BESBasicInterface::log_status() ;
00314 }
00315 }
00316
00332 void
00333 BESXMLInterface::report_request()
00334 {
00335 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00336 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00337 for( ; i != e; i++ )
00338 {
00339 _dhi = &(*i)->get_dhi() ;
00340 BESBasicInterface::report_request() ;
00341 }
00342 }
00343
00346 void
00347 BESXMLInterface::clean()
00348 {
00349 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00350 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00351 for( ; i != e; i++ )
00352 {
00353 BESXMLCommand *cmd = *i ;
00354 _dhi = &cmd->get_dhi() ;
00355 BESBasicInterface::clean() ;
00356 delete cmd ;
00357 }
00358 _cmd_list.clear() ;
00359 }
00360
00367 void
00368 BESXMLInterface::dump( ostream &strm ) const
00369 {
00370 strm << BESIndent::LMarg << "BESXMLInterface::dump - ("
00371 << (void *)this << ")" << endl ;
00372 BESIndent::Indent() ;
00373 BESBasicInterface::dump( strm ) ;
00374 vector<BESXMLCommand *>::const_iterator i = _cmd_list.begin() ;
00375 vector<BESXMLCommand *>::const_iterator e = _cmd_list.end() ;
00376 for( ; i != e; i++ )
00377 {
00378 BESXMLCommand *cmd = *i ;
00379 cmd->dump( strm ) ;
00380 }
00381 BESIndent::UnIndent() ;
00382 }
00383