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 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