00001
00020 #include <functional>
00021 #include <algorithm>
00022 #include <iostream>
00023
00024 #include <coil/Routing.h>
00025 #include <coil/stringutil.h>
00026
00027 #include <rtm/NamingManager.h>
00028 #include <rtm/Manager.h>
00029 #include <rtm/CORBA_IORUtil.h>
00030
00031 namespace RTC
00032 {
00040 NamingOnCorba::NamingOnCorba(CORBA::ORB_ptr orb, const char* names)
00041 : m_cosnaming(orb, names), m_endpoint(""),
00042 m_replaceEndpoint(false)
00043 {
00044 rtclog.setName("NamingOnCorba");
00045 coil::Properties& prop(Manager::instance().getConfig());
00046 m_replaceEndpoint =
00047 coil::toBool(prop["corba.nameservice.replace_endpoint"].c_str(),
00048 "YES", "NO", true);
00049
00050
00051 coil::vstring host_port(coil::split(names, ":"));
00052 if (coil::dest_to_endpoint(host_port[0], m_endpoint))
00053 {
00054 RTC_INFO(("Endpoint for the CORBA naming service (%s) is %s.",
00055 host_port[0].c_str(),
00056 m_endpoint.c_str()));
00057 }
00058 else
00059 {
00060 RTC_WARN(("No endpoint for the CORBA naming service (%s) was found.",
00061 host_port[0].c_str()));
00062 }
00063 }
00071 void NamingOnCorba::bindObject(const char* name,
00072 const RTObject_impl* rtobj)
00073 {
00074 RTC_TRACE(("bindObject(name = %s, rtobj)", name));
00075 #ifdef ORB_IS_OMNIORB
00076 if (!m_endpoint.empty() && m_replaceEndpoint)
00077 {
00078 CORBA::Object_var obj(RTObject::_duplicate(rtobj->getObjRef()));
00079 CORBA::String_var ior;
00080 ior = RTC::Manager::instance().getORB()->object_to_string(obj.in());
00081 std::string iorstr((const char*)ior);
00082
00083 RTC_DEBUG(("Original IOR information:\n %s",
00084 CORBA_IORUtil::formatIORinfo(iorstr.c_str()).c_str()));
00085 CORBA_IORUtil::replaceEndpoint(iorstr, m_endpoint);
00086 CORBA::Object_var newobj = RTC::Manager::instance().
00087 getORB()->string_to_object(iorstr.c_str());
00088
00089 RTC_DEBUG(("Modified IOR information:\n %s",
00090 CORBA_IORUtil::formatIORinfo(iorstr.c_str()).c_str()));
00091 m_cosnaming.rebindByString(name, newobj.in(), true);
00092 }
00093 else
00094 {
00095 #endif // ORB_IS_OMNIORB
00096 m_cosnaming.rebindByString(name, rtobj->getObjRef(), true);
00097 #ifdef ORB_IS_OMNIORB
00098 }
00099 #endif // ORB_IS_OMNIORB
00100 }
00101
00102 void NamingOnCorba::bindObject(const char* name,
00103 const RTM::ManagerServant* mgr)
00104 {
00105 RTC_TRACE(("bindObject(name = %s, mgr)", name));
00106 #ifdef ORB_IS_OMNIORB
00107 if (!m_endpoint.empty() && m_replaceEndpoint)
00108 {
00109 CORBA::Object_var obj(RTM::Manager::_duplicate(mgr->getObjRef()));
00110 CORBA::String_var ior;
00111 ior = RTC::Manager::instance().getORB()->object_to_string(obj.in());
00112 std::string iorstr((const char*)ior);
00113
00114 RTC_DEBUG(("Original IOR information:\n %s",
00115 CORBA_IORUtil::formatIORinfo(iorstr.c_str()).c_str()));
00116 CORBA_IORUtil::replaceEndpoint(iorstr, m_endpoint);
00117 CORBA::Object_var newobj = RTC::Manager::instance().
00118 getORB()->string_to_object(iorstr.c_str());
00119
00120 RTC_DEBUG(("Modified IOR information]\n %s",
00121 CORBA_IORUtil::formatIORinfo(iorstr.c_str()).c_str()));
00122 m_cosnaming.rebindByString(name, newobj.in(), true);
00123 }
00124 else
00125 {
00126 #endif // ORB_IS_OMNIORB
00127 m_cosnaming.rebindByString(name, mgr->getObjRef(), true);
00128 #ifdef ORB_IS_OMNIORB
00129 }
00130 #endif // ORB_IS_OMNIORB
00131 }
00132
00140 void NamingOnCorba::unbindObject(const char* name)
00141 {
00142 RTC_TRACE(("unbindObject(name = %s)", name));
00143 m_cosnaming.unbind(name);
00144 }
00145
00146 bool NamingOnCorba::isAlive()
00147 {
00148 RTC_TRACE(("isAlive()"));
00149 return m_cosnaming.isAlive();
00150 }
00151
00152
00153
00154
00155
00163 NamingManager::NamingManager(Manager* manager)
00164 :m_manager(manager), rtclog("NamingManager")
00165 {
00166 }
00167
00175 NamingManager::~NamingManager()
00176 {
00177 }
00178
00186 void NamingManager::registerNameServer(const char* method,
00187 const char* name_server)
00188 {
00189 RTC_TRACE(("NamingManager::registerNameServer(%s, %s)",
00190 method, name_server));
00191 NamingBase* name;
00192 name = createNamingObj(method, name_server);
00193
00194 Guard guard(m_namesMutex);
00195 m_names.push_back(new Names(method, name_server, name));
00196 }
00197
00205 void NamingManager::bindObject(const char* name,
00206 const RTObject_impl* rtobj)
00207 {
00208 RTC_TRACE(("NamingManager::bindObject(%s)", name));
00209
00210 Guard guard(m_namesMutex);
00211 for (int i(0), len(m_names.size()); i < len; ++i)
00212 {
00213 if (m_names[i]->ns != 0)
00214 {
00215 try
00216 {
00217 m_names[i]->ns->bindObject(name, rtobj);
00218 }
00219 catch (...)
00220 {
00221 delete m_names[i]->ns;
00222 m_names[i]->ns = 0;
00223 }
00224 }
00225 }
00226 registerCompName(name, rtobj);
00227 }
00228 void NamingManager::bindObject(const char* name,
00229 const RTM::ManagerServant* mgr)
00230 {
00231 RTC_TRACE(("NamingManager::bindObject(%s)", name));
00232
00233 Guard guard(m_namesMutex);
00234 for (int i(0), len(m_names.size()); i < len; ++i)
00235 {
00236 if (m_names[i]->ns != 0)
00237 {
00238 try
00239 {
00240 m_names[i]->ns->bindObject(name, mgr);
00241 }
00242 catch (...)
00243 {
00244 delete m_names[i]->ns;
00245 m_names[i]->ns = 0;
00246 }
00247 }
00248 }
00249 registerMgrName(name, mgr);
00250 }
00251
00259 void NamingManager::update()
00260 {
00261 RTC_TRACE(("NamingManager::update()"));
00262
00263 Guard guard(m_namesMutex);
00264 bool rebind(coil::toBool(m_manager->getConfig()["naming.update.rebind"],
00265 "YES", "NO", false));
00266 for (int i(0), len(m_names.size()); i < len; ++i)
00267 {
00268 if (m_names[i]->ns == 0)
00269 {
00270 RTC_DEBUG(("Retrying connection to %s/%s",
00271 m_names[i]->method.c_str(),
00272 m_names[i]->nsname.c_str()));
00273 retryConnection(m_names[i]);
00274 }
00275 else
00276 {
00277 try
00278 {
00279 if (rebind) { bindCompsTo(m_names[i]->ns); }
00280 if (!m_names[i]->ns->isAlive())
00281 {
00282 RTC_INFO(("Name server: %s (%s) disappeared.",
00283 m_names[i]->nsname.c_str(),
00284 m_names[i]->method.c_str()));
00285 delete m_names[i]->ns;
00286 m_names[i]->ns = 0;
00287 }
00288 }
00289 catch (...)
00290 {
00291 RTC_INFO(("Name server: %s (%s) disappeared.",
00292 m_names[i]->nsname.c_str(),
00293 m_names[i]->method.c_str()));
00294 delete m_names[i]->ns;
00295 m_names[i]->ns = 0;
00296 }
00297 }
00298 }
00299 }
00300
00308 void NamingManager::unbindObject(const char* name)
00309 {
00310 RTC_TRACE(("NamingManager::unbindObject(%s)", name));
00311
00312 Guard guard(m_namesMutex);
00313 for (int i(0), len(m_names.size()); i < len; ++i)
00314 {
00315 if (m_names[i]->ns != NULL)
00316 {
00317 m_names[i]->ns->unbindObject(name);
00318 }
00319 }
00320 unregisterCompName(name);
00321 unregisterMgrName(name);
00322 }
00323
00331 void NamingManager::unbindAll()
00332 {
00333 RTC_TRACE(("NamingManager::unbindAll(): %d names.", m_compNames.size()));
00334 {
00335 Guard guard(m_compNamesMutex);
00336 coil::vstring names;
00337
00338 for (int i(0), len(m_compNames.size()); i < len; ++i)
00339 {
00340 names.push_back(m_compNames[i]->name);
00341 }
00342 for (size_t i(0); i < names.size(); ++i)
00343 {
00344 unbindObject(names[i].c_str());
00345 }
00346
00347 }
00348 {
00349 Guard guard(m_mgrNamesMutex);
00350 coil::vstring names;
00351
00352 for (int i(0), len(m_mgrNames.size()); i < len; ++i)
00353 {
00354 names.push_back(m_mgrNames[i]->name);
00355 }
00356 for (size_t i(0); i < names.size(); ++i)
00357 {
00358 unbindObject(names[i].c_str());
00359 }
00360 }
00361 }
00362
00370 std::vector<RTObject_impl*> NamingManager::getObjects()
00371 {
00372 std::vector<RTObject_impl*> comps;
00373 Guard guard(m_compNamesMutex);
00374
00375 for (int i(0), len(m_compNames.size()); i < len; ++i)
00376 {
00377 comps.push_back(const_cast<RTObject_impl*>(m_compNames[i]->rtobj));
00378 }
00379 return comps;
00380 }
00381
00382
00383
00384
00392 NamingBase* NamingManager::createNamingObj(const char* method,
00393 const char* name_server)
00394 {
00395 RTC_TRACE(("createNamingObj(method = %s, nameserver = %s",
00396 method, name_server));
00397 std::string m(method);
00398 if (m == "corba")
00399 {
00400 try
00401 {
00402 NamingBase* name;
00403 CORBA::ORB_var orb;
00404 orb = CORBA::ORB::_duplicate(m_manager->getORB());
00405 name = new NamingOnCorba(orb.in(), name_server);
00406 if (name == NULL) return NULL;
00407 RTC_INFO(("NameServer connection succeeded: %s/%s", \
00408 method, name_server));
00409 return name;
00410 }
00411 catch (...)
00412 {
00413 RTC_INFO(("NameServer connection failed: %s/%s", \
00414 method, name_server));
00415 return NULL;
00416 }
00417 }
00418 return NULL;
00419 }
00420
00428 void NamingManager::bindCompsTo(NamingBase* ns)
00429 {
00430 for (int i(0), len(m_compNames.size()); i < len; ++i)
00431 {
00432 ns->bindObject(m_compNames[i]->name.c_str(), m_compNames[i]->rtobj);
00433 }
00434 }
00435
00443 void NamingManager::registerCompName(const char* name,
00444 const RTObject_impl* rtobj)
00445 {
00446 for (int i(0), len(m_compNames.size()); i < len; ++i)
00447 {
00448 if (m_compNames[i]->name == name)
00449 {
00450 m_compNames[i]->rtobj = rtobj;
00451 return;
00452 }
00453 }
00454 m_compNames.push_back(new Comps(name, rtobj));
00455 return;
00456 }
00457 void NamingManager::registerMgrName(const char* name,
00458 const RTM::ManagerServant* mgr)
00459 {
00460 for (int i(0), len(m_mgrNames.size()); i < len; ++i)
00461 {
00462 if (m_mgrNames[i]->name == name)
00463 {
00464 m_mgrNames[i]->mgr = mgr;
00465 return;
00466 }
00467 }
00468 m_mgrNames.push_back(new Mgr(name, mgr));
00469 return;
00470 }
00471
00479 void NamingManager::unregisterCompName(const char* name)
00480 {
00481 std::vector<Comps*>::iterator it(m_compNames.begin());
00482 for (int i(0), len(m_compNames.size()); i < len; ++i, ++it)
00483 {
00484 if (m_compNames[i]->name == name)
00485 {
00486 delete m_compNames[i];
00487 m_compNames.erase(it);
00488 return;
00489 }
00490 }
00491 return;
00492 }
00493 void NamingManager::unregisterMgrName(const char* name)
00494 {
00495 std::vector<Mgr*>::iterator it(m_mgrNames.begin());
00496 for (int i(0), len(m_mgrNames.size()); i < len; ++i, ++it)
00497 {
00498 if (m_mgrNames[i]->name == name)
00499 {
00500 delete m_mgrNames[i];
00501 m_mgrNames.erase(it);
00502 return;
00503 }
00504 }
00505 return;
00506 }
00507
00508 void NamingManager::retryConnection(Names* ns)
00509 {
00510
00511 NamingBase* nsobj(0);
00512 try
00513 {
00514 nsobj = createNamingObj(ns->method.c_str(),
00515 ns->nsname.c_str());
00516 if (nsobj != 0)
00517 {
00518 RTC_INFO(("Connected to a name server: %s/%s",
00519 ns->method.c_str(), ns->nsname.c_str()));
00520 ns->ns = nsobj;
00521 bindCompsTo(nsobj);
00522 return;
00523 }
00524 else
00525 {
00526 RTC_DEBUG(("Name service: %s/%s still not available.",
00527 ns->method.c_str(),
00528 ns->nsname.c_str()));
00529 }
00530 }
00531 catch (...)
00532 {
00533 RTC_DEBUG(("Name server: %s/%s disappeared again.",
00534 ns->method.c_str(),
00535 ns->nsname.c_str()));
00536 if (nsobj != 0)
00537 {
00538 delete ns->ns;
00539 ns->ns = 0;
00540 }
00541 }
00542 }
00543 };