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 << " [" << _dhi->data[DATA_REQUEST] << "] building"
00096 << endl ;
00097 }
00098
00099 LIBXML_TEST_VERSION
00100
00101 xmlDoc *doc = NULL ;
00102 xmlNode *root_element = NULL ;
00103 xmlNode *current_node = NULL ;
00104
00105 try
00106 {
00107
00108 vector<string> parseerrors ;
00109 xmlSetGenericErrorFunc( (void *)&parseerrors, BESXMLUtils::XMLErrorFunc );
00110
00111 doc = xmlParseDoc( (unsigned char *)_dhi->data["XMLDoc"].c_str() ) ;
00112 if( doc == NULL )
00113 {
00114 string err = "Problem parsing the request xml document:\n" ;
00115 bool isfirst = true ;
00116 vector<string>::const_iterator i = parseerrors.begin() ;
00117 vector<string>::const_iterator e = parseerrors.end() ;
00118 for( ; i != e; i++ )
00119 {
00120 if( !isfirst && (*i).compare( 0, 6, "Entity" ) == 0 )
00121 {
00122 err += "\n" ;
00123 }
00124 err += (*i) ;
00125 isfirst = false ;
00126 }
00127 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00128 }
00129
00130
00131 root_element = xmlDocGetRootElement( doc ) ;
00132 if( !root_element )
00133 {
00134 string err = "There is no root element in the xml document" ;
00135 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00136 }
00137
00138 string root_name ;
00139 string root_val ;
00140 map< string, string> props ;
00141 BESXMLUtils::GetNodeInfo( root_element, root_name, root_val, props ) ;
00142 if( root_name != "request" )
00143 {
00144 string err = (string)"The root element should be a request element, "
00145 + "name is " + (char *)root_element->name ;
00146 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00147 }
00148 if( root_val != "" )
00149 {
00150 string err = (string)"The request element must not contain a value, "
00151 + root_val ;
00152 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00153 }
00154
00155
00156 string &reqId = props[REQUEST_ID] ;
00157 if( reqId.empty() )
00158 {
00159 string err = (string)"request id value empty" ;
00160 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00161 }
00162 _dhi->data[REQUEST_ID] = reqId ;
00163 BESDEBUG( "besxml", "request id = "<< _dhi->data[REQUEST_ID] << 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 p_xmlcmd_builder bldr = BESXMLCommand::find_command( node_name ) ;
00178 if( bldr )
00179 {
00180 BESXMLCommand *current_cmd = bldr( _base_dhi ) ;
00181 if( !current_cmd )
00182 {
00183 string err = (string)"Failed to build command object for "
00184 + node_name ;
00185 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00186 }
00187
00188
00189 _cmd_list.push_back( current_cmd ) ;
00190
00191
00192
00193 bool cmd_has_response = current_cmd->has_response() ;
00194 if( has_response && cmd_has_response )
00195 {
00196 string err = "Multiple responses not allowed" ;
00197 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00198 }
00199 has_response = cmd_has_response ;
00200
00201
00202 current_cmd->parse_request( current_node ) ;
00203
00204 BESDataHandlerInterface ¤t_dhi = current_cmd->get_dhi();
00205 string returnAs = current_dhi.data[RETURN_CMD] ;
00206 if( returnAs != "" )
00207 {
00208 BESDEBUG( "xml", "Finding transmitter: " << returnAs
00209 << " ... " << endl )
00210 BESTransmitter *transmitter =
00211 BESReturnManager::TheManager()->find_transmitter( returnAs ) ;
00212 if( !transmitter )
00213 {
00214 string s = (string)"Unable to find transmitter "
00215 + returnAs ;
00216 throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ;
00217 }
00218 BESDEBUG( "xml", "OK" << endl )
00219 }
00220 }
00221 else
00222 {
00223 string err = (string)"Unable to find command for "
00224 + node_name ;
00225 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00226 }
00227 }
00228 current_node = current_node->next ;
00229 }
00230 }
00231 catch( BESError &e )
00232 {
00233 xmlFreeDoc( doc ) ;
00234 throw e ;
00235 }
00236
00237 xmlFreeDoc( doc ) ;
00238 #if 0
00239
00240
00241 xmlCleanupParser() ;
00242 #endif
00243 BESDEBUG( "besxml", "Done building request plan" << endl )
00244
00245 BESBasicInterface::build_data_request_plan() ;
00246 }
00247
00250 void
00251 BESXMLInterface::execute_data_request_plan()
00252 {
00253 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00254 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00255 for( ; i != e; i++ )
00256 {
00257 (*i)->prep_request() ;
00258 _dhi = &(*i)->get_dhi() ;
00259 BESBasicInterface::execute_data_request_plan() ;
00260 }
00261 }
00262
00265 void
00266 BESXMLInterface::invoke_aggregation()
00267 {
00268 BESBasicInterface::invoke_aggregation() ;
00269 }
00270
00273 void
00274 BESXMLInterface::transmit_data()
00275 {
00276 string returnAs = _dhi->data[RETURN_CMD] ;
00277 if( returnAs != "" )
00278 {
00279 BESDEBUG( "xml", "Setting transmitter: " << returnAs
00280 << " ... " << endl )
00281 _transmitter =
00282 BESReturnManager::TheManager()->find_transmitter( returnAs ) ;
00283 if( !_transmitter )
00284 {
00285 string s = (string)"Unable to find transmitter "
00286 + returnAs ;
00287 throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ;
00288 }
00289 BESDEBUG( "xml", "OK" << endl )
00290 }
00291
00292 BESBasicInterface::transmit_data() ;
00293 }
00294
00299 void
00300 BESXMLInterface::log_status()
00301 {
00302 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00303 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00304 for( ; i != e; i++ )
00305 {
00306 _dhi = &(*i)->get_dhi() ;
00307 BESBasicInterface::log_status() ;
00308 }
00309 }
00310
00326 void
00327 BESXMLInterface::report_request()
00328 {
00329 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00330 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00331 for( ; i != e; i++ )
00332 {
00333 _dhi = &(*i)->get_dhi() ;
00334 BESBasicInterface::report_request() ;
00335 }
00336 }
00337
00340 void
00341 BESXMLInterface::clean()
00342 {
00343 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00344 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00345 for( ; i != e; i++ )
00346 {
00347 BESXMLCommand *cmd = *i ;
00348 _dhi = &cmd->get_dhi() ;
00349 BESBasicInterface::clean() ;
00350 delete cmd ;
00351 }
00352 _cmd_list.clear() ;
00353 }
00354
00361 void
00362 BESXMLInterface::dump( ostream &strm ) const
00363 {
00364 strm << BESIndent::LMarg << "BESXMLInterface::dump - ("
00365 << (void *)this << ")" << endl ;
00366 BESIndent::Indent() ;
00367 BESBasicInterface::dump( strm ) ;
00368 vector<BESXMLCommand *>::const_iterator i = _cmd_list.begin() ;
00369 vector<BESXMLCommand *>::const_iterator e = _cmd_list.end() ;
00370 for( ; i != e; i++ )
00371 {
00372 BESXMLCommand *cmd = *i ;
00373 cmd->dump( strm ) ;
00374 }
00375 BESIndent::UnIndent() ;
00376 }
00377