00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <iostream.h>
00024 #include <OB/CORBA.h>
00025 #include <OB/CosNaming.h>
00026 #include "BridgeStub.h"
00027 #include "Parser.h"
00028 #include "StdAfx.h"
00029 #include "SoapCorba.h"
00030 #include "DbObjects.h"
00031 #include "ReadIR.h"
00032 #include "SoapBridge.h"
00033 #include "SoapBridge_skel.h"
00034 #include "sbimpl.h"
00035 #include "curl/curl.h"
00036
00037 CORBA::Boolean AnyInterface::_is_a (const char *name)
00038 throw (CORBA::SystemException)
00039 {
00040 CString idl = "IDL:";
00041 idl += m_Intf;
00042 idl += ":1.0";
00043 CORBA::Boolean _r = idl.Compare (name) == 0;
00044 if (!_r) {
00045 corbaBridgeLog->error ("AnyInterface::_is_a: %s != %s\n", (const char *) idl, name);
00046 }
00047 return _r;
00048 }
00049
00050 size_t curlWriter (void *ptr, size_t siz, size_t num, void *pStream)
00051 {
00052 CString *pcs = (CString *) pStream;
00053 CString cop ((char *) ptr, siz * num);
00054 *pcs += cop;
00055 return siz * num;
00056 }
00057
00064 void AnyInterface::ErrorCallback (const char *name, const char *msg)
00065 {
00066 corbaBridgeLog->warn ("CCerr: %s, %s/%s (%s): %s",
00067 (const char *) m_Addr, (const char *) m_Intf, name, (const char *) m_Ctxk, msg);
00068 if (!CORBA::is_nil (m_cb)) {
00069 try {
00070 m_cb->tellMe (m_Addr, m_Intf, name, m_Ctxk, msg);
00071 corbaBridgeLog->info ("Succesfully informed caller of error");
00072 }
00073 catch (...) {
00074 corbaBridgeLog->warn ("Could not tell caller, failed to invoke callback.");
00075 }
00076 } else {
00077 corbaBridgeLog->warn ("Could not tell caller, no callback was registered.");
00078 }
00079 }
00080
00092 void AnyInterface::invoke (CORBA::ServerRequest_ptr request) throw ()
00093 {
00094 CORBA::String_var name = request->operation ();
00095 CString mp = "/";
00096 mp += m_Intf;
00097 mp += "/";
00098 mp += (const char *) name;
00099 CString spAct = m_Intf;
00100 spAct += '#';
00101 spAct += (const char *) name;
00102 corbaBridgeLog->info ("CORBACall::invoke (%s)\n", (const char *) mp);
00103 ParList_Holder _plhold;
00104 SCParamList *pParList = NULL;
00105
00106 {
00107 IRPlus *pIRP = (IRPlus *) irplusHandle;
00108 JTCSynchronized synchronized (pIRP->monitor);
00109 SCInterfaceMethod *pMeth = pIRP->IRC.FindInterfaceMethod (mp);
00110 if (!pMeth) {
00111 ErrorCallback (name, "No such interface/method in the repository");
00112 CORBA::Any exAny;
00113 exAny <<= new CORBA::BAD_OPERATION ();
00114 request -> set_exception(exAny);
00115 return;
00116 }
00117 _plhold.pParList = pParList = new SCParamList (pMeth, dynFact);
00118 }
00119 {
00120 CORBA::NVList_ptr list;
00121 orb->create_list (0, list);
00122 SCParamList::ParamValueIterator iParVal (pParList);
00123 while (++iParVal) {
00124 CORBA::TypeCode_var tc = iParVal->GetDynAnyPtr ()->type ();
00125 if (iParVal->m_prmKind == ioeIn) {
00126 list->add (CORBA::ARG_IN)->value ()->replace (tc, 0);
00127 }
00128 if (iParVal->m_prmKind == ioeInOut) {
00129 list->add (CORBA::ARG_INOUT)->value ()->replace (tc, 0);
00130 }
00131 }
00132 request->arguments (list);
00133 iParVal.Reset ();
00134
00135 DOM_Document doc;
00136 DOM_Element envel;
00137 DOM_Element body;
00138 createEmptySoap (doc, envel, body);
00139 {
00140 DOM_Element hd;
00141 addHeader (doc, envel, hd,
00142 NULL,
00143 m_Ctxk.IsEmpty () ? NULL : (const char *) m_Ctxk,
00144 (const char *) spAct);
00145 }
00146 DOM_Element methNode = addElement (doc, body, name);
00147 body.setAttribute ("xmlns:m", (const char *) mp);
00148 unsigned int listPtr = 0;
00149 while (++iParVal) {
00150 if (iParVal->m_prmKind == ioeIn || iParVal->m_prmKind == ioeInOut) {
00151 DOM_Element insNode = addElement (doc, methNode, iParVal->m_prmName);
00152 CORBA::Any aar (*(list->item (listPtr)->value ()));
00153 DynamicAny::DynAny_var tmpDa = dynFact->create_dyn_any (aar);
00154 DynAny2Xml (doc, insNode, iParVal, tmpDa, m_Ctxk);
00155 }
00156 if (iParVal->m_prmKind != ioeException && iParVal->m_prmName.Compare ("return") != 0) {
00157 listPtr ++;
00158 }
00159 }
00160 unsigned char *outXml = NULL;
00161 unsigned long outXmlSiz = 0;
00162 CString answer;
00163 CURLcode result;
00164 GetXML (outXml, outXmlSiz, (DOM_H) &doc);
00165 {
00166 CURL *curl;
00167 curl = curl_easy_init ();
00168 if (curl) {
00169 curl_easy_setopt (curl, CURLOPT_URL, (const char *) m_Addr);
00170 curl_easy_setopt (curl, CURLOPT_TIMEOUT, 10);
00171 curl_easy_setopt (curl, CURLOPT_POST, 1);
00172 curl_easy_setopt (curl, CURLOPT_POSTFIELDS, outXml);
00173 curl_easy_setopt (curl, CURLOPT_POSTFIELDSIZE, outXmlSiz);
00174 struct curl_slist *pList = NULL;
00175 CString sa = "SOAPAction: " + spAct;
00176 pList = curl_slist_append (pList, (const char *) sa);
00177 curl_easy_setopt (curl, CURLOPT_HTTPHEADER, pList);
00178 curl_easy_setopt (curl, CURLOPT_FILE, &answer);
00179 curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, curlWriter);
00180 corbaBridgeLog->debug ("Calling SOAP Server...\n");
00181 result = curl_easy_perform (curl);
00182 curl_easy_cleanup (curl);
00183 corbaBridgeLog->info ("Call result=%d\n", result);
00184 } else {
00185 ErrorCallback (name, "Server error: cURL init failed");
00186 CORBA::Any exAny;
00187 exAny <<= new CORBA::BAD_OPERATION ();
00188 request -> set_exception(exAny);
00189 return;
00190 }
00191 }
00192 delete outXml;
00193 if (!result) {
00194 try {
00195 corbaBridgeLog->debug ("Result=%s\n", (const char *) answer);
00196 DOM_Holder Holder (parseDOM ((const unsigned char *) (const char *) answer, answer.GetLength ()));
00197 if (Holder.domHdl) {
00198 DOM_Document Doc = *((DOM_Document *) Holder.domHdl);
00199 HrefIdMap HrefMap;
00200 HrefMap.Build (Doc);
00201
00202
00203
00204 DOM_Element soapEnvelope;
00205 {
00206 DOM_Node sNode = Doc.getFirstChild ();
00207 DOMTRACE (sNode.getNodeName ());
00208 while (sNode != NULL && sNode.getNodeType () != DOM_Node::ELEMENT_NODE) {
00209 sNode = sNode.getNextSibling ();
00210 }
00211 DOMString envelopeTag ("Envelope");
00212 if (sNode == NULL || !envelopeTag.equals (sNode.getLocalName ())) {
00213 ErrorCallback (name, "SOAP response error: No SOAP Envelope");
00214 CORBA::Any exAny;
00215 exAny <<= new CORBA::BAD_OPERATION ();
00216 request -> set_exception(exAny);
00217 return;
00218 }
00219 HrefMap.RealNode (soapEnvelope, sNode);
00220 }
00221 DOM_Element soapBody;
00222 {
00223 DOM_Node sNode = soapEnvelope.getFirstChild ();
00224 DOMTRACE (sNode.getLocalName ());
00225 while (sNode != NULL && sNode.getNodeType () != DOM_Node::ELEMENT_NODE) {
00226 sNode = sNode.getNextSibling ();
00227 }
00228 DOMString headerTag ("Header");
00229 if (sNode != NULL && headerTag.equals (sNode.getLocalName ())) {
00230 sNode = sNode.getNextSibling ();
00231 }
00232 DOMTRACE (sNode.getNodeName ());
00233 while (sNode != NULL && sNode.getNodeType () != DOM_Node::ELEMENT_NODE) {
00234 sNode = sNode.getNextSibling ();
00235 }
00236 DOMString bodyTag ("Body");
00237 if (sNode == NULL || !bodyTag.equals (sNode.getLocalName ())) {
00238 ErrorCallback (name, "SOAP response error: No SOAP Body");
00239 CORBA::Any exAny;
00240 exAny <<= new CORBA::BAD_OPERATION ();
00241 request -> set_exception(exAny);
00242 return;
00243 }
00244 HrefMap.RealNode (soapBody, sNode);
00245 }
00246
00247
00248 DOM_Element soapResp;
00249 {
00250 DOM_Node sNode = soapBody.getFirstChild ();
00251 while (sNode != NULL && sNode.getNodeType () != DOM_Node::ELEMENT_NODE) {
00252 sNode = sNode.getNextSibling ();
00253 }
00254 DOMString responseTag (name);
00255 responseTag += "Response";
00256 DOMString faultTag ("SOAP-ENV:Fault");
00257 if (sNode != NULL && responseTag.equals (sNode.getLocalName ())) {
00258 DOM_Node parNode = sNode.getFirstChild ();
00259 while (parNode != NULL && parNode.getNodeType () != DOM_Node::ELEMENT_NODE) {
00260 parNode = parNode.getNextSibling ();
00261 }
00262 iParVal.Reset ();
00263 listPtr = 0;
00264 while (++iParVal) {
00265 if (iParVal->m_prmKind == ioeOut && iParVal->m_prmName.Compare ("return") == 0) {
00266 DOMString returnTag ("return");
00267 if (parNode != NULL && returnTag.equals (parNode.getLocalName ())) {
00268
00269 DOM_Element methodParm;
00270 HrefMap.RealNode (methodParm, parNode);
00271 if (parNode != NULL) {
00272 do {
00273 parNode = parNode.getNextSibling ();
00274 } while (parNode != NULL && parNode.getNodeType () != DOM_Node::ELEMENT_NODE);
00275 }
00276 try {
00277 FillInDynAny (HrefMap, iParVal, iParVal->GetDynAnyPtr (), methodParm);
00278 }
00279 catch (DOM_Document &) {
00280 ErrorCallback (name, "SOAP Fault thrown from FillInDynAny");
00281 CORBA::Any exAny;
00282 exAny <<= new CORBA::BAD_OPERATION ();
00283 request -> set_exception(exAny);
00284 return;
00285 }
00286 catch (...) {
00287 soapBridgeLog->crit ("Unknown Exception in FillInDynAny\n");
00288 abort ();
00289 }
00290 CORBA::Any_var an = iParVal->GetDynAnyPtr ()->to_any ();
00291 request -> set_result(an);
00292 }
00293 } else if (iParVal->m_prmKind == ioeOut || iParVal->m_prmKind == ioeInOut) {
00294 if (parNode != NULL) {
00295 DOM_Element methodParm;
00296 HrefMap.RealNode (methodParm, parNode);
00297 if (parNode != NULL) {
00298 do {
00299 parNode = parNode.getNextSibling ();
00300 } while (parNode != NULL && parNode.getNodeType () != DOM_Node::ELEMENT_NODE);
00301 }
00302 try {
00303 FillInDynAny (HrefMap, iParVal, iParVal->GetDynAnyPtr (), methodParm);
00304 }
00305 catch (DOM_Document &) {
00306 ErrorCallback (name, "SOAP Fault thrown from FillInDynAny");
00307 CORBA::Any exAny;
00308 exAny <<= new CORBA::BAD_OPERATION ();
00309 request -> set_exception(exAny);
00310 return;
00311 }
00312 catch (...) {
00313 soapBridgeLog->crit ("Unknown Exception in FillInDynAny\n");
00314 abort ();
00315 }
00316 CORBA::Any_var an = iParVal->GetDynAnyPtr ()->to_any ();
00317 CORBA::Any *pAny = list->item (listPtr)->value ();
00318 *pAny = an;
00319 } else {
00320 CString misPar;
00321 misPar.Format ("Missing parameter '%s' in SOAP response",
00322 (const char *) iParVal->m_prmName);
00323 ErrorCallback (name, misPar);
00324 CORBA::Any exAny;
00325 exAny <<= new CORBA::BAD_OPERATION ();
00326 request -> set_exception(exAny);
00327 return;
00328 }
00329 listPtr ++;
00330 } else if (iParVal->m_prmKind == ioeIn) {
00331 listPtr ++;
00332 }
00333 }
00334 } else if (sNode != NULL && faultTag.equals (sNode.getNodeName ())) {
00335
00336 GetXML (outXml, outXmlSiz, (DOM_H) &sNode);
00337 CString cs ((const char *) outXml, outXmlSiz);
00338 delete outXml;
00339 ErrorCallback (name, (const char *) cs);
00340 CORBA::Any exAny;
00341 exAny <<= new CORBA::BAD_OPERATION ();
00342 request -> set_exception(exAny);
00343 return;
00344 } else {
00345 ErrorCallback (name, "SOAP response error: Neither a response nor a Fault was returned");
00346 CORBA::Any exAny;
00347 exAny <<= new CORBA::BAD_OPERATION ();
00348 request -> set_exception(exAny);
00349 return;
00350 }
00351 }
00352
00353 } else {
00354 ErrorCallback (name, "Failed to parse SOAP response.");
00355 CORBA::Any exAny;
00356 exAny <<= new CORBA::BAD_OPERATION ();
00357 request -> set_exception(exAny);
00358 return;
00359 }
00360 }
00361 catch (...) {
00362 ErrorCallback (name, "An exception occured while processing the SOAP response.");
00363 CORBA::Any exAny;
00364 exAny <<= new CORBA::BAD_OPERATION ();
00365 request -> set_exception(exAny);
00366 return;
00367 }
00368 } else {
00369 ErrorCallback (name, "Failed to call SOAP server.");
00370 CORBA::Any exAny;
00371 exAny <<= new CORBA::BAD_OPERATION ();
00372 request -> set_exception(exAny);
00373 return;
00374 }
00375 }
00376 }
00377
00378 CORBA::RepositoryId AnyInterface::_primary_interface (
00379 const PortableServer::ObjectId &oid,
00380 PortableServer::POA_ptr pPoa)
00381 {
00382 CString idl = "IDL:";
00383 idl += m_Intf;
00384 idl += ":1.0";
00385 return CORBA::string_dup ((const char *) idl);
00386 }
00387
00388
00389
00390
00391 SOAPBridge::CORBACall_impl::CORBACall_impl(PortableServer::POA_ptr poa)
00392 : poa_(PortableServer::POA::_duplicate(poa))
00393 {
00394 }
00395
00396 SOAPBridge::CORBACall_impl::~CORBACall_impl()
00397 {
00398 }
00399
00400 PortableServer::POA_ptr SOAPBridge::CORBACall_impl::_default_POA()
00401 {
00402 return PortableServer::POA::_duplicate(poa_);
00403 }
00404
00405
00406
00407
00408 char* SOAPBridge::CORBACall_impl::contextKey()
00409 throw(CORBA::SystemException)
00410 {
00411
00412 char* _r = CORBA::string_dup(ctxKey);
00413 return _r;
00414 }
00415
00416 void SOAPBridge::CORBACall_impl::contextKey(const char* a)
00417 throw(CORBA::SystemException)
00418 {
00419 ctxKey = a;
00420 }
00421
00422
00423
00424
00425 CORBA::Object_ptr SOAPBridge::CORBACall_impl::CreateSession(const char* soapAddress,
00426 const char* intfName,
00427 CORBA::Boolean obtainContextKey,
00428 SOAPBridge::CORBACallback_ptr cb)
00429 throw(CORBA::SystemException)
00430 {
00431 corbaBridgeLog->info ("SOAPBridge::CORBACall_impl::CreateSession:%s/%s\n", soapAddress, intfName);
00432 if (obtainContextKey) {
00433
00434 AnyInterface cki (soapAddress, "SOAPBridge/ContextManager", "", SOAPBridge::CORBACallback::_nil());
00435 PortableServer::ObjectId_var ckid = poa_ -> activate_object (&cki);
00436 CORBA::Object_var obj = poa_ -> id_to_reference (ckid);
00437 SOAPBridge::ContextManager_var man = SOAPBridge::ContextManager::_narrow (obj);
00438 CString userId = soapAddress;
00439 userId += intfName;
00440 SOAPBridge::ContextManager::SOAPContext_var tmp = man->allocateContext (1800, userId);
00441 ctxKey = (char *) tmp->contextKey;
00442 }
00443 AnyInterface *pi = new AnyInterface (soapAddress, intfName, ctxKey, cb);
00444 PortableServer::ObjectId_var id = poa_ -> activate_object (pi);
00445 return poa_ -> id_to_reference (id);
00446 }
00447
00448
00449
00450
00451 void SOAPBridge::CORBACall_impl::DestroySession(CORBA::Object_ptr sessionObject)
00452 throw(CORBA::SystemException)
00453 {
00454 CORBA::release (sessionObject);
00455 }
00456