00001 #include "otsdaq-core/SOAPUtilities/SOAPMessenger.h" 00002 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h" 00003 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h" 00004 #include "otsdaq-core/MessageFacility/MessageFacility.h" 00005 #include "otsdaq-core/Macros/CoutMacros.h" 00006 //#include "otsdaq-core/DataTypes/DataStructs.h" 00007 00008 #include <xoap/Method.h> 00009 #include <xdaq/NamespaceURI.h> 00010 #include <xoap/MessageReference.h> 00011 #pragma GCC diagnostic push 00012 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 00013 #include <xoap/MessageFactory.h> 00014 #pragma GCC diagnostic pop 00015 #include <xoap/SOAPPart.h> 00016 #include <xoap/SOAPEnvelope.h> 00017 #include <xoap/SOAPBody.h> 00018 #include <xoap/domutils.h> 00019 #include <xoap/AttachmentPart.h> 00020 00021 //#include <iostream> 00022 //#include <sys/time.h> 00023 00024 00025 00026 00027 00028 using namespace ots; 00029 00030 //======================================================================================================================== 00031 SOAPMessenger::SOAPMessenger(xdaq::Application* application) : 00032 theApplication_(application) 00033 { 00034 } 00035 00036 //======================================================================================================================== 00037 SOAPMessenger::SOAPMessenger(const SOAPMessenger& aSOAPMessenger) : 00038 theApplication_(aSOAPMessenger.theApplication_) 00039 { 00040 } 00041 00042 //======================================================================================================================== 00043 std::string SOAPMessenger::receive(const xoap::MessageReference& message, SOAPCommand& soapCommand) 00044 { 00045 return receive(message, soapCommand.getParametersRef()); 00046 } 00047 00048 //======================================================================================================================== 00049 std::string SOAPMessenger::receive(const xoap::MessageReference& message) 00050 { 00051 //NOTE it is assumed that there is only 1 command for each message (that's why we use begin) 00052 return (message->getSOAPPart().getEnvelope().getBody().getChildElements()).begin()->getElementName().getLocalName(); 00053 } 00054 00055 //======================================================================================================================== 00056 std::string SOAPMessenger::receive(const xoap::MessageReference& message, SOAPParameters& parameters) 00057 { 00058 xoap::SOAPEnvelope envelope = message->getSOAPPart().getEnvelope(); 00059 std::vector<xoap::SOAPElement> bodyList = envelope.getBody().getChildElements(); 00060 xoap::SOAPElement command = bodyList[0]; 00061 std::string commandName = command.getElementName().getLocalName(); 00062 xoap::SOAPName name = envelope.createName("Key"); 00063 00064 for (SOAPParameters::iterator it=parameters.begin(); it!=parameters.end(); it++) 00065 { 00066 name = envelope.createName(it->first); 00067 00068 try 00069 { 00070 it->second = command.getAttributeValue(name); 00071 //if( parameters.getParameter(it->first).isEmpty() ) 00072 //{ 00073 // __COUT__ << "Complaint from " << (theApplication_->getApplicationDescriptor()->getClassName()) << std::endl; 00074 // __COUT__ << " : Parameter "<< it->first 00075 // << " does not exist in the list of incoming parameters!" << std::endl; 00076 // __COUT__ << "It could also be because you passed an empty std::string" << std::endl; 00077 // //assert(0); 00078 //}; 00079 } 00080 catch (xoap::exception::Exception& e) 00081 { 00082 __COUT__ << "Parameter " << it->first << " does not exist in the list of incoming parameters!" << std::endl; 00083 XCEPT_RETHROW(xoap::exception::Exception,"Looking for parameter that does not exist!",e); 00084 } 00085 00086 } 00087 00088 return commandName; 00089 } 00090 00091 //======================================================================================================================== 00092 // in xdaq 00093 // xdaq::ApplicationDescriptor* sourceptr; 00094 // void getURN() 00095 // 00096 std::string SOAPMessenger::send(XDAQ_CONST_CALL xdaq::ApplicationDescriptor* ind, 00097 xoap::MessageReference message) 00098 00099 { 00100 return receive(sendWithSOAPReply(ind,message)); 00101 } 00102 //{ 00103 // //const_cast away the const 00104 // // so that this line is compatible with slf6 and slf7 versions of xdaq 00105 // // where they changed to XDAQ_CONST_CALL xdaq::ApplicationDescriptor* in slf7 00106 // XDAQ_CONST_CALL xdaq::ApplicationDescriptor* d = 00107 // const_cast<xdaq::ApplicationDescriptor*>(ind); 00108 // try 00109 // { 00110 // message->getMimeHeaders()->setHeader("Content-Location", d->getURN()); 00111 // 00112 // __COUT__ << d->getURN() << __E__; 00113 // __COUT__ << SOAPUtilities::translate(message) << __E__; 00114 // std::string mystring; 00115 // message->writeTo(mystring); 00116 // __COUT__<< mystring << std::endl; 00117 // 00118 // xoap::MessageReference reply = theApplication_->getApplicationContext()->postSOAP(message, 00119 // *(theApplication_->getApplicationDescriptor()), 00120 // *d); 00121 // std::string replyString = receive(reply); 00122 // __COUT__ << "replyString " << replyString << std::endl; 00123 // return replyString; 00124 // } 00125 // catch (xdaq::exception::Exception& e) 00126 // { 00127 // __COUT__ << "This application failed to send a SOAP message to " 00128 // << d->getClassName() << " instance " << d->getInstance() 00129 // << " re-throwing exception = " << xcept::stdformat_exception_history(e); 00130 // std::string mystring; 00131 // message->writeTo(mystring); 00132 // __COUT__<< mystring << std::endl; 00133 // XCEPT_RETHROW(xdaq::exception::Exception,"Failed to send SOAP command.",e); 00134 // } 00135 //} 00136 00137 //======================================================================================================================== 00138 std::string SOAPMessenger::send(XDAQ_CONST_CALL xdaq::ApplicationDescriptor* d, SOAPCommand soapCommand) 00139 00140 { 00141 if(soapCommand.hasParameters()) 00142 return send(d, soapCommand.getCommand(), soapCommand.getParameters()); 00143 else 00144 return send(d, soapCommand.getCommand()); 00145 } 00146 00147 //======================================================================================================================== 00148 std::string SOAPMessenger::send(XDAQ_CONST_CALL xdaq::ApplicationDescriptor* d, std::string command) 00149 00150 { 00151 xoap::MessageReference message = SOAPUtilities::makeSOAPMessageReference(command); 00152 return send(d, message); 00153 } 00154 00155 //======================================================================================================================== 00156 std::string SOAPMessenger::send(XDAQ_CONST_CALL xdaq::ApplicationDescriptor* ind, std::string cmd, 00157 SOAPParameters parameters) 00158 00159 { 00160 return receive(sendWithSOAPReply(ind,cmd,parameters)); 00161 } 00162 00163 //{ 00164 // //const_cast away the const 00165 // // so that this line is compatible with slf6 and slf7 versions of xdaq 00166 // // where they changed to XDAQ_CONST_CALL xdaq::ApplicationDescriptor* in slf7 00167 // XDAQ_CONST_CALL xdaq::ApplicationDescriptor* d = 00168 // const_cast<xdaq::ApplicationDescriptor*>(ind); 00169 // 00170 // xoap::MessageReference message; 00171 // try 00172 // { 00173 // message = SOAPUtilities::makeSOAPMessageReference(cmd, parameters); 00174 // message->getMimeHeaders()->setHeader("Content-Location", d->getURN()); 00175 // 00176 // __COUT__ << d->getURN() << __E__; 00177 // __COUT__ << SOAPUtilities::translate(message) << __E__; 00178 // std::string mystring; 00179 // message->writeTo(mystring); 00180 // __COUT__<< mystring << std::endl; 00181 // 00182 // xoap::MessageReference reply = theApplication_->getApplicationContext()->postSOAP(message, 00183 // *(theApplication_->getApplicationDescriptor()), *d); 00184 // std::string replyString = receive(reply); 00185 // return replyString; 00186 // } 00187 // catch (xdaq::exception::Exception& e) 00188 // { 00189 // __COUT__ << "This application failed to send a SOAP message to " 00190 // << d->getClassName() << " instance " << d->getInstance() 00191 // << " with command = " << cmd 00192 // << " re-throwing exception = " << xcept::stdformat_exception_history(e)<<std::endl; 00193 // 00194 // std::string mystring; 00195 // message->writeTo(mystring); 00196 // __COUT_ERR__ << mystring; 00197 // XCEPT_RETHROW(xdaq::exception::Exception,"Failed to send SOAP command.",e); 00198 // } 00199 // 00200 //} 00201 00202 //======================================================================================================================== 00203 xoap::MessageReference SOAPMessenger::sendWithSOAPReply(XDAQ_CONST_CALL xdaq::ApplicationDescriptor* ind, 00204 std::string cmd) 00205 00206 { 00207 return sendWithSOAPReply(ind, SOAPUtilities::makeSOAPMessageReference(cmd)); 00208 } 00209 //{ 00210 // //const_cast away the const 00211 // // so that this line is compatible with slf6 and slf7 versions of xdaq 00212 // // where they changed to XDAQ_CONST_CALL xdaq::ApplicationDescriptor* in slf7 00213 // XDAQ_CONST_CALL xdaq::ApplicationDescriptor* d = 00214 // const_cast<xdaq::ApplicationDescriptor*>(ind); 00215 // try 00216 // { 00217 // xoap::MessageReference message = SOAPUtilities::makeSOAPMessageReference(cmd); 00218 // message->getMimeHeaders()->setHeader("Content-Location", d->getURN()); 00219 // 00220 // __COUT__ << d->getURN() << __E__; 00221 // __COUT__ << SOAPUtilities::translate(message) << __E__; 00222 // std::string mystring; 00223 // message->writeTo(mystring); 00224 // __COUT__<< mystring << std::endl; 00225 // 00226 // xoap::MessageReference reply = theApplication_->getApplicationContext()->postSOAP(message, 00227 // *(theApplication_->getApplicationDescriptor()), 00228 // *d); 00229 // return reply; 00230 // } 00231 00232 // catch (xdaq::exception::Exception& e) 00233 // { 00234 // __COUT__ << "This application failed to send a SOAP message to " 00235 // << d->getClassName() << " instance " << d->getInstance() 00236 // << " with command = " << cmd 00237 // << " re-throwing exception = " << xcept::stdformat_exception_history(e)<<std::endl; 00238 // XCEPT_RETHROW(xdaq::exception::Exception,"Failed to send SOAP command.",e); 00239 // } 00240 // 00241 //} 00242 00243 //======================================================================================================================== 00244 xoap::MessageReference SOAPMessenger::sendWithSOAPReply(XDAQ_CONST_CALL xdaq::ApplicationDescriptor *ind, 00245 xoap::MessageReference message) 00246 00247 { 00248 //const_cast away the const 00249 // so that this line is compatible with slf6 and slf7 versions of xdaq 00250 // where they changed to XDAQ_CONST_CALL xdaq::ApplicationDescriptor* in slf7 00251 XDAQ_CONST_CALL xdaq::ApplicationDescriptor* d = 00252 const_cast<xdaq::ApplicationDescriptor*>(ind); 00253 try 00254 { 00255 message->getMimeHeaders()->setHeader("Content-Location", d->getURN()); 00256 00257 //__COUT__ << d->getURN() << __E__; 00258 //__COUT__ << SOAPUtilities::translate(message) << __E__; 00259 std::string mystring; 00260 message->writeTo(mystring); 00261 //__COUT__<< mystring << std::endl; 00262 00263 xoap::MessageReference reply = theApplication_->getApplicationContext()->postSOAP(message, 00264 *(theApplication_->getApplicationDescriptor()), 00265 *d); 00266 return reply; 00267 } 00268 catch (xdaq::exception::Exception& e) 00269 { 00270 __COUT__ << "This application failed to send a SOAP message to " 00271 << d->getClassName() << " instance " << d->getInstance() 00272 << " re-throwing exception = " << xcept::stdformat_exception_history(e); 00273 std::string mystring; 00274 message->writeTo(mystring); 00275 __COUT_ERR__<< mystring << std::endl; 00276 XCEPT_RETHROW(xdaq::exception::Exception,"Failed to send SOAP command.",e); 00277 } 00278 } 00279 00280 //======================================================================================================================== 00281 xoap::MessageReference SOAPMessenger::sendWithSOAPReply(XDAQ_CONST_CALL xdaq::ApplicationDescriptor* ind, 00282 std::string cmd, SOAPParameters parameters) 00283 00284 { 00285 return sendWithSOAPReply(ind, SOAPUtilities::makeSOAPMessageReference(cmd, parameters)); 00286 } 00287 //{ 00288 // //const_cast away the const 00289 // // so that this line is compatible with slf6 and slf7 versions of xdaq 00290 // // where they changed to XDAQ_CONST_CALL xdaq::ApplicationDescriptor* in slf7 00291 // XDAQ_CONST_CALL xdaq::ApplicationDescriptor* d = 00292 // const_cast<xdaq::ApplicationDescriptor*>(ind); 00293 // try 00294 // { 00295 // xoap::MessageReference message = SOAPUtilities::makeSOAPMessageReference(cmd, parameters); 00296 // message->getMimeHeaders()->setHeader("Content-Location", d->getURN()); 00297 // xoap::MessageReference reply = theApplication_->getApplicationContext()->postSOAP(message, 00298 // *(theApplication_->getApplicationDescriptor()), *d); 00299 // return reply; 00300 // } 00301 // catch (xdaq::exception::Exception& e) 00302 // { 00303 // __COUT__ << "This application failed to send a SOAP message to " 00304 // << d->getClassName() << " instance " << d->getInstance() 00305 // << " with command = " << cmd 00306 // << " re-throwing exception = " << xcept::stdformat_exception_history(e); 00307 // XCEPT_RETHROW(xdaq::exception::Exception,"Failed to send SOAP command.",e); 00308 // } 00309 // 00310 //} 00311 00312 //======================================================================================================================== 00313 /* 00314 std::string SOAPMessenger::send(XDAQ_CONST_CALL xdaq::ApplicationDescriptor* d, std::string cmd, std::string filepath) 00315 { 00316 00317 try 00318 { 00319 __COUT__ << "SOAP XML file path : " << filepath << std::endl; 00320 xoap::MessageReference message = xoap::createMessage(); 00321 xoap::SOAPPart soap = message->getSOAPPart(); 00322 xoap::SOAPEnvelope envelope = soap.getEnvelope(); 00323 xoap::AttachmentPart * attachment; 00324 attachment = message->createAttachmentPart(); 00325 attachment->setContent(filepath); 00326 attachment->setContentId("SOAPTEST1"); 00327 attachment->addMimeHeader("Content-Description", "This is a SOAP message with attachments"); 00328 message->addAttachmentPart(attachment); 00329 xoap::SOAPName command = envelope.createName(cmd, "xdaq", XDAQ_NS_URI); 00330 xoap::SOAPBody body= envelope.getBody(); 00331 body.addBodyElement(command); 00332 #ifdef DEBUGMSG 00333 std::string mystring; 00334 message->writeTo(mystring); 00335 __COUT__ << "SOAP Message : "<< mystring <<std::endl << std::endl; 00336 #endif 00337 message->getMimeHeaders()->setHeader("Content-Location", d->getURN()); 00338 xoap::MessageReference reply=theApplication_->getApplicationContext()->postSOAP(message, *(theApplication_->getApplicationDescriptor()), *d); 00339 std::string replyString = receive(reply); 00340 return replyString; 00341 } 00342 catch (xdaq::exception::Exception& e) 00343 { 00344 XCEPT_RETHROW(xdaq::exception::Exception,"Failed to send SOAP command.",e); 00345 } 00346 } 00347 */ 00348 //======================================================================================================================== 00349 std::string SOAPMessenger::sendStatus(XDAQ_CONST_CALL xdaq::ApplicationDescriptor* ind, 00350 std::string message) 00351 00352 { 00353 //const_cast away the const 00354 // so that this line is compatible with slf6 and slf7 versions of xdaq 00355 // where they changed to XDAQ_CONST_CALL xdaq::ApplicationDescriptor* in slf7 00356 XDAQ_CONST_CALL xdaq::ApplicationDescriptor* d = 00357 const_cast<xdaq::ApplicationDescriptor*>(ind); 00358 00359 std::string cmd = "StatusNotification"; 00360 try 00361 { 00362 timeval tv; //keep track of when the message comes 00363 gettimeofday(&tv,NULL); 00364 00365 std::stringstream ss; 00366 SOAPParameters parameters; 00367 parameters.addParameter("Description",message); 00368 ss.str(""); ss << tv.tv_sec; 00369 parameters.addParameter("Time",ss.str()); 00370 ss.str(""); ss << tv.tv_usec; 00371 parameters.addParameter("usec",ss.str()); 00372 return send(d, cmd, parameters); 00373 } 00374 catch (xdaq::exception::Exception& e) 00375 { 00376 __COUT__ << "This application failed to send a SOAP error message to " 00377 << d->getClassName() << " instance " << d->getInstance() 00378 << " with command = " << cmd 00379 << " re-throwing exception = " << xcept::stdformat_exception_history(e) << std::endl; 00380 XCEPT_RETHROW(xdaq::exception::Exception,"Failed to send SOAP command.",e); 00381 } 00382 }