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]
00164 << endl ) ;
00165
00166
00167
00168 bool has_response = false ;
00169 current_node = root_element->children ;
00170
00171 while( current_node )
00172 {
00173 if( current_node->type == XML_ELEMENT_NODE )
00174 {
00175
00176
00177 string node_name = (char *)current_node->name ;
00178 p_xmlcmd_builder bldr = BESXMLCommand::find_command( node_name ) ;
00179 if( bldr )
00180 {
00181 BESXMLCommand *current_cmd = bldr( _base_dhi ) ;
00182 if( !current_cmd )
00183 {
00184 string err = (string)"Failed to build command object for "
00185 + node_name ;
00186 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00187 }
00188
00189
00190 _cmd_list.push_back( current_cmd ) ;
00191
00192
00193
00194 bool cmd_has_response = current_cmd->has_response() ;
00195 if( has_response && cmd_has_response )
00196 {
00197 string err = "Multiple responses not allowed" ;
00198 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00199 }
00200 has_response = cmd_has_response ;
00201
00202
00203 current_cmd->parse_request( current_node ) ;
00204
00205 BESDataHandlerInterface ¤t_dhi = current_cmd->get_dhi();
00206 string returnAs = current_dhi.data[RETURN_CMD] ;
00207 if( returnAs != "" )
00208 {
00209 BESDEBUG( "xml", "Finding transmitter: " << returnAs
00210 << " ... " << endl ) ;
00211 BESTransmitter *transmitter =
00212 BESReturnManager::TheManager()->find_transmitter( returnAs ) ;
00213 if( !transmitter )
00214 {
00215 string s = (string)"Unable to find transmitter "
00216 + returnAs ;
00217 throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ;
00218 }
00219 BESDEBUG( "xml", "OK" << endl ) ;
00220 }
00221 }
00222 else
00223 {
00224 string err = (string)"Unable to find command for "
00225 + node_name ;
00226 throw BESSyntaxUserError( err, __FILE__, __LINE__ ) ;
00227 }
00228 }
00229 current_node = current_node->next ;
00230 }
00231 }
00232 catch( BESError &e )
00233 {
00234 xmlFreeDoc( doc ) ;
00235 throw e ;
00236 }
00237
00238 xmlFreeDoc( doc ) ;
00239 #if 0
00240
00241
00242 xmlCleanupParser() ;
00243 #endif
00244 BESDEBUG( "besxml", "Done building request plan" << endl ) ;
00245
00246 BESBasicInterface::build_data_request_plan() ;
00247 }
00248
00251 void
00252 BESXMLInterface::execute_data_request_plan()
00253 {
00254 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00255 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00256 for( ; i != e; i++ )
00257 {
00258 (*i)->prep_request() ;
00259 _dhi = &(*i)->get_dhi() ;
00260 BESBasicInterface::execute_data_request_plan() ;
00261 }
00262 }
00263
00266 void
00267 BESXMLInterface::invoke_aggregation()
00268 {
00269 BESBasicInterface::invoke_aggregation() ;
00270 }
00271
00274 void
00275 BESXMLInterface::transmit_data()
00276 {
00277 string returnAs = _dhi->data[RETURN_CMD] ;
00278 if( returnAs != "" )
00279 {
00280 BESDEBUG( "xml", "Setting transmitter: " << returnAs
00281 << " ... " << endl ) ;
00282 _transmitter =
00283 BESReturnManager::TheManager()->find_transmitter( returnAs ) ;
00284 if( !_transmitter )
00285 {
00286 string s = (string)"Unable to find transmitter "
00287 + returnAs ;
00288 throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ;
00289 }
00290 BESDEBUG( "xml", "OK" << endl ) ;
00291 }
00292
00293 BESBasicInterface::transmit_data() ;
00294 }
00295
00300 void
00301 BESXMLInterface::log_status()
00302 {
00303 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00304 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00305 for( ; i != e; i++ )
00306 {
00307 _dhi = &(*i)->get_dhi() ;
00308 BESBasicInterface::log_status() ;
00309 }
00310 }
00311
00327 void
00328 BESXMLInterface::report_request()
00329 {
00330 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00331 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00332 for( ; i != e; i++ )
00333 {
00334 _dhi = &(*i)->get_dhi() ;
00335 BESBasicInterface::report_request() ;
00336 }
00337 }
00338
00341 void
00342 BESXMLInterface::clean()
00343 {
00344 vector<BESXMLCommand *>::iterator i = _cmd_list.begin() ;
00345 vector<BESXMLCommand *>::iterator e = _cmd_list.end() ;
00346 for( ; i != e; i++ )
00347 {
00348 BESXMLCommand *cmd = *i ;
00349 _dhi = &cmd->get_dhi() ;
00350 BESBasicInterface::clean() ;
00351 delete cmd ;
00352 }
00353 _cmd_list.clear() ;
00354 }
00355
00362 void
00363 BESXMLInterface::dump( ostream &strm ) const
00364 {
00365 strm << BESIndent::LMarg << "BESXMLInterface::dump - ("
00366 << (void *)this << ")" << endl ;
00367 BESIndent::Indent() ;
00368 BESBasicInterface::dump( strm ) ;
00369 vector<BESXMLCommand *>::const_iterator i = _cmd_list.begin() ;
00370 vector<BESXMLCommand *>::const_iterator e = _cmd_list.end() ;
00371 for( ; i != e; i++ )
00372 {
00373 BESXMLCommand *cmd = *i ;
00374 cmd->dump( strm ) ;
00375 }
00376 BESIndent::UnIndent() ;
00377 }
00378