diff --git a/OpenRTM_aist/CORBA_RTCUtil.py b/OpenRTM_aist/CORBA_RTCUtil.py index 4d531a48..fc3900c4 100644 --- a/OpenRTM_aist/CORBA_RTCUtil.py +++ b/OpenRTM_aist/CORBA_RTCUtil.py @@ -1536,3 +1536,236 @@ def set_configuration_parameter(conf, confset, value_name, value): confset.configuration_data = confData conf.set_configuration_set_values(confset) return True + + +## +# @if jp +# @class CorbaURI +# @brief 指定のCORBAオブジェクト参照用URLから参照形式、ホスト名、ポート番号、 +# パス、オブジェクトキーを取得する機能を提供するクラス +# +# @since 2.0.0 +# +# @else +# @class CorbaURI +# @brief +# +# @since 2.0.0 +# +# @endif +class CorbaURI: + ## + # @if jp + # + # @brief コンストラクタ + # + # uriには以下の形式のURLを指定できる + # - corbaloc形式(例:corbaloc:iiop:192.168.11.1:2809/Nameservice) + # - corbaname形式(例:corbaname::192.168.11.1:2809#ConsoleOut0.rtc) + # - HTTP(例:http://192.168.11.1:2809/call#Nameservice) + # - HTTPS(例:https://192.168.11.1:2809/call#Nameservice) + # - WS(例:ws://192.168.11.1:2809/ws#Nameservice) + # - WSS(例:wss://192.168.11.1:2809/ws#Nameservice) + # + # また、giop:ではじまるエンドポイントを指定することもできる + # この場合は上記のcorbaloc形式、corbaname形式、HTTP、HTTPS、WS、WSSのURLに変換する + # - giop::192.168.11.1:2809 -> corbaloc:iiop:192.168.11.1:2809 + # - giop:tcp:192.168.11.1:2809 -> corbaloc:iiop:192.168.11.1:2809 + # - giop:ssl:192.168.11.1:2809 -> corbaloc:ssliop:192.168.11.1:2809 + # - giop:http:http://192.168.11.1:2809/call -> + # http://192.168.11.1:2809/call + # + # アドレス、ポート番号を指定した場合はcorbaloc形式URLに変換する。 + # - 192.168.11.1:2809 -> corbaloc:iiop:192.168.11.1:2809 + # + # objkeyを指定した場合はURIの末尾に追加する。 + # - corbaloc:iiop:192.168.11.1:2809 -> + # corbaloc:iiop:192.168.11.1:2809/Nameservice + # - corbaname::192.168.11.1:2809 -> + # corbaloc:iiop:192.168.11.1:2809#ConsoleOut0.rtc + # - http://192.168.11.1:2809/call -> + # http://192.168.11.1:2809/call#Nameservice + # + # @param self + # @param uri CORBAオブジェクト参照用URL + # @param objkey オブジェクト名 + # + # @else + # + # @brief Consructor + # + # + # @param self + # @param uri + # @param objkey + # + # @endif + def __init__(self, uri, objkey=""): + import urllib.parse + protocols_str = {"giop:tcp:": "corbaloc:iiop:", + "giop:ssl:": "corbaloc:ssliop:", + "giop:http:": "", + "giop::": "corbaloc:iiop:", + "iiop://": "corbaloc:iiop:", + "diop://": "corbaloc:diop:", + "uiop://": "corbaloc:uiop:", + "ssliop://": "corbaloc:ssliop:", + "shmiop://": "corbaloc:shmiop:", + "htiop://": "corbaloc:htiop:", + "inet:": "corbaloc:iiop:"} + + converted = False + for k, v in protocols_str.items(): + if uri.find(k) == 0: + uri = uri.replace(k, v) + converted = True + break + + protocols_o_str = {"iiop:": "corbaloc:iiop:", + "ssliop:": "corbaloc:ssliop:", + "diop:": "corbaloc:diop:", + "shmiop:": "corbaloc:shmiop:", + "htiop:": "corbaloc:htiop:"} + + if not converted: + for k, v in protocols_o_str.items(): + if uri.find(k) == 0: + uri = uri.replace(k, v) + break + + self._uri = "" + self._port = None + self._addressonly = False + ret = urllib.parse.urlparse(uri) + self._protocol = ret.scheme + + loc = [s.strip() for s in ret.netloc.split(":")] + if len(loc) >= 2: + self._host = loc[0] + self._port = int(loc[1]) + else: + self._host = ret.netloc + self._path = ret.path + self._fragment = ret.fragment + + if self._fragment: + self._uri = uri + return + else: + self._fragment = objkey + if self._protocol == "corbaloc": + self._uri = uri + "/" + self._uri += self._fragment + elif self._protocol: + self._uri = uri + "#" + self._uri += self._fragment + else: + self._uri = "corbaloc:iiop:" + self._uri += uri + "/" + self._uri += self._fragment + self._protocol = "corbaloc" + self._addressonly = True + host_port = [s.strip() for s in uri.split(":")] + if len(host_port) == 2: + self._host = host_port[0] + try: + self._port = int(host_port[1]) + except BaseException: + pass + ## + # @if jp + # + # @brief CORBAオブジェクト参照用URLを取得する + # + # @param self + # @return CORBAオブジェクト参照用URL + # + # @else + # + # @brief Consructor + # + # @param self + # @return + # + # @endif + + def toString(self): + return self._uri + + ## + # @if jp + # + # @brief 参照形式を取得する + # 例:corbaloc、corbaname、http、https、ws、wss + # + # @param self + # @return 参照形式 + # + # @else + # + # @brief + # + # @param self + # @return + # + # @endif + def getProtocol(self): + return self._protocol + + ## + # @if jp + # + # @brief ホスト名を取得する + # + # @param self + # @return ホスト名 + # + # @else + # + # @brief + # + # @param self + # @return + # + # @endif + def getHost(self): + return self._host + + ## + # @if jp + # + # @brief ポート番号を取得する + # + # @param self + # @return ポート番号 + # + # @else + # + # @brief + # + # @param self + # @return + # + # @endif + def getPort(self): + return self._port + + ## + # @if jp + # + # @brief 初期化時にCORBAオブジェクト参照用URLを指定した場合はfalse、 + # ホスト名、ポート番号のみを指定した場合はtrueを返す。 + # + # @param self + # @return 参照先の指定方法 + # + # @else + # + # @brief + # + # @param self + # @return + # + # @endif + def isAddressOnly(self): + return self._addressonly diff --git a/OpenRTM_aist/CorbaNaming.py b/OpenRTM_aist/CorbaNaming.py index a26611f8..c9272eff 100644 --- a/OpenRTM_aist/CorbaNaming.py +++ b/OpenRTM_aist/CorbaNaming.py @@ -17,6 +17,7 @@ import omniORB.CORBA as CORBA import CosNaming +import OpenRTM_aist.CORBA_RTCUtil import string import sys import traceback @@ -85,12 +86,16 @@ def __init__(self, orb, name_server=None): self._blLength = 100 if name_server: - self._nameServer = "corbaloc::" + name_server + "/NameService" - obj = orb.string_to_object(self._nameServer) - self._rootContext = obj._narrow(CosNaming.NamingContext) - if CORBA.is_nil(self._rootContext): - print("CorbaNaming: Failed to narrow the root naming context.") - raise MemoryError + self._nameServer = OpenRTM_aist.CORBA_RTCUtil.CorbaURI(name_server, "NameService").toString() + try: + obj = orb.string_to_object(self._nameServer) + self._rootContext = obj._narrow(CosNaming.NamingContext) + if CORBA.is_nil(self._rootContext): + print("CorbaNaming: Failed to narrow the root naming context.") + + except CORBA.ORB.InvalidName: + self.__print_exception() + print("Service required is invalid [does not exist].") return @@ -125,7 +130,7 @@ def __del__(self): # @endif def init(self, name_server): - self._nameServer = "corbaloc::" + name_server + "/NameService" + self._nameServer = OpenRTM_aist.CORBA_RTCUtil.CorbaURI(name_server, "NameService").toString() obj = self._orb.string_to_object(self._nameServer) self._rootContext = obj._narrow(CosNaming.NamingContext) if CORBA.is_nil(self._rootContext): diff --git a/OpenRTM_aist/Manager.py b/OpenRTM_aist/Manager.py index 3e6fc3f1..362fbcee 100644 --- a/OpenRTM_aist/Manager.py +++ b/OpenRTM_aist/Manager.py @@ -1789,6 +1789,38 @@ def createORBOptions(self): return opt + ## + # @if jp + # @brief giopからはじまるORBエンドポイントでの指定した場合にtrue、 + # それ以外(例えばホスト名:ポート番号の指定)の場合はfalseを返す。 + # + # + # @param endpoint エンドポイント + # @return エンドポイントの指定方法 + # + # @else + # @brief + # + # @param endpoint + # @return + # + # @endif + # + # static bool isORBEndPoint(const std::string& endpoint); + + @staticmethod + def isORBEndPoint(endpoint): + headers = ["giop:", "iiop://", + "diop://", "uiop://", + "ssliop://", "shmiop://", + "htiop://", "inet:"] + + for header in headers: + if header in endpoint: + return True + + return False + ## # @if jp # @brief エンドポイントの生成 @@ -1839,11 +1871,14 @@ def createORBEndpoints(self): if OpenRTM_aist.toBool(self._config.getProperty( "manager.is_master"), "YES", "NO", False): mm = self._config.getProperty("corba.master_manager", ":2810") - mmm = [s.strip() for s in mm.split(":")] - if len(mmm) == 2: - endpoints.insert(0, ":" + mmm[1]) + if not Manager.isORBEndPoint(mm): + mmm = [s.strip() for s in mm.split(":")] + if len(mmm) == 2: + endpoints.insert(0, ":" + mmm[1]) + else: + endpoints.insert(0, ":2810") else: - endpoints.insert(0, ":2810") + endpoints.insert(0, mm) endpoints = OpenRTM_aist.unique_sv(endpoints) @@ -1882,12 +1917,21 @@ def createORBEndpointOption(self, opt, endpoints): if endpoint == "all:": opt += " -ORBendPointPublish all(addr)" else: - opt += " -ORBendPoint giop:tcp:" + endpoint + if not Manager.isORBEndPoint(endpoint): + opt += " -ORBendPoint giop:tcp:" + endpoint + else: + opt += " -ORBendPoint " + endpoint elif corba == "TAO": - opt += "-ORBEndPoint iiop://" + endpoint + if not Manager.isORBEndPoint(endpoint): + opt += "-ORBEndPoint iiop://" + endpoint + else: + opt += "-ORBEndPoint " + endpoint elif corba == "MICO": - opt += "-ORBIIOPAddr inet:" + endpoint + if not Manager.isORBEndPoint(endpoint): + opt += "-ORBIIOPAddr inet:" + endpoint + else: + opt += "-ORBIIOPAddr " + endpoint endpoints[i] = endpoint diff --git a/OpenRTM_aist/ManagerServant.py b/OpenRTM_aist/ManagerServant.py index d11499f0..7667a417 100644 --- a/OpenRTM_aist/ManagerServant.py +++ b/OpenRTM_aist/ManagerServant.py @@ -20,6 +20,7 @@ import time from omniORB import CORBA import OpenRTM_aist +import OpenRTM_aist.CORBA_RTCUtil import RTC import RTM import RTM__POA @@ -1172,9 +1173,7 @@ def findManager(self, host_port): self._rtcout.RTC_TRACE("findManager(host_port = %s)", host_port) try: config = copy.deepcopy(self._mgr.getConfig()) - mgrloc = "corbaloc:iiop:" - mgrloc += host_port - mgrloc += "/" + config.getProperty("manager.name") + mgrloc = OpenRTM_aist.CORBA_RTCUtil.CorbaURI(host_port, config.getProperty("manager.name")).toString() self._rtcout.RTC_DEBUG("corbaloc: %s", mgrloc) diff --git a/OpenRTM_aist/NamingManager.py b/OpenRTM_aist/NamingManager.py index 92ebc7bd..5605c351 100644 --- a/OpenRTM_aist/NamingManager.py +++ b/OpenRTM_aist/NamingManager.py @@ -19,6 +19,7 @@ import OpenRTM_aist +import OpenRTM_aist.CORBA_RTCUtil from omniORB import CORBA import RTM import RTC @@ -563,11 +564,9 @@ def getManager(self, name): mgr = mgr_sev.getObjRef() return mgr try: - mgrloc = "corbaloc:iiop:" prop = self._mgr.getConfig() manager_name = prop.getProperty("manager.name") - mgrloc += name - mgrloc += "/" + manager_name + mgrloc = OpenRTM_aist.CORBA_RTCUtil.CorbaURI(name, manager_name).toString() mobj = self._orb.string_to_object(mgrloc) mgr = mobj._narrow(RTM.Manager) @@ -793,7 +792,13 @@ def unbindObject(self, name): guard = OpenRTM_aist.ScopedLock(self._namesMutex) for n in self._names: if n.ns: - n.ns.unbindObject(name) + try: + n.ns.unbindObject(name) + except BaseException: + del n.ns + n.ns = None + + self.unregisterCompName(name) self.unregisterMgrName(name) self.unregisterPortName(name) @@ -910,7 +915,10 @@ def createNamingObj(self, method, name_server): def bindCompsTo(self, ns): for comp in self._compNames: - ns.bindObject(comp.name, comp.rtobj) + try: + ns.bindObject(comp.name, comp.rtobj) + except BaseException: + pass ## # @if jp