SdoServiceAdmin.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: euc-jp -*-
00003 
00004 ##
00005 # @file SdoServiceAdmin.py
00006 # @brief SDO service administration class
00007 # @date $Date$
00008 # @author Noriaki Ando <n-ando@aist.go.jp> and Shinji Kurihara
00009 #
00010 # Copyright (C) 2011
00011 #     Intelligent Systems Research Institute,
00012 #     National Institute of
00013 #         Advanced Industrial Science and Technology (AIST), Japan
00014 #     All rights reserved.
00015 
00016 import copy
00017 import threading
00018 import OpenRTM_aist
00019 
00020 
00021 ##
00022 # @if jp
00023 #
00024 # @class SDO service administration class
00025 # @brief SDO service 管理クラス
00026 #
00027 # このクラスは、SDO Service を管理するためのクラスである。SDO
00028 # Service は OMG SDO Specification において定義されている、SDOが特定
00029 # の機能のために提供また要求するサービスの一つである。詳細は仕様にお
00030 # いて定義されていないが、本クラスでは以下のように振る舞うサービスで
00031 # あるものとし、これらを管理するためのクラスが本クラスである。
00032 #
00033 # SDO Service においては、SDO/RTCに所有され、ある種のサービスを提供
00034 # するものを SDO Service Provider、他のSDO/RTCやアプリケーションが提
00035 # 供するサービスオブジェクトの参照を受け取り、それらの機能を利用する
00036 # ものを、SDO Service Consumer と呼ぶ。
00037 #
00038 # SDO Service Provider は他のアプリケーションから呼ばれ、SDO/RTC内部
00039 # の機能にアクセスするために用いられる。他のSDO/RTCまたはアプリケー
00040 # ションは、
00041 #
00042 # - SDO::get_service_profiles ()
00043 # - SDO::get_service_profile (in UniqueIdentifier id)
00044 # - SDO::get_sdo_service (in UniqueIdentifier id) 
00045 #
00046 # のいずれかのオペレーションにより、ServiceProfile または SDO
00047 # Service の参照を取得し、機能を利用するためのオペレーションを呼び出
00048 # す。他のSDO/RTCまたはアプリケーション上での参照の破棄は任意のタイ
00049 # ミングで行われ、サービス提供側では、どこからどれだけ参照されている
00050 # かは知ることはできない。一方で、SDO/RTC側も、任意のタイミングでサー
00051 # ビスの提供を停止することもできるため、サービスの利用側では、常に
00052 # サービスが利用できるとは限らないものとしてサービスオペレーションを
00053 # 呼び出す必要がある。
00054 #
00055 # 一方、SDO Service Consumer は当該SDO/RTC以外のSDO/RTCまたはアプリ
00056 # ケーションがサービスの実体を持ち、当該SDO/RTCにオブジェクト参照を
00057 # 含むプロファイルを与えることで、SDO/RTC側からサービスオペレーショ
00058 # ンが呼ばれ外部のSDO/RTCまたはアプリケーションが提供する機能を利用
00059 # できる。また、オブザーバ的なオブジェクトを与えることで、SDO/RTC側
00060 # からのコールバックを実現するためにも利用することができる。コンシュー
00061 # マは、プロバイダとは異なり、SDO Configurationインターフェースから
00062 # 追加、削除が行われる。関連するオペレーションは以下のとおりである。
00063 #
00064 # - Configuration::add_service_profile (in ServiceProfile sProfile)
00065 # - Configuration::remove_service_profile (in UniqueIdentifier id)
00066 #
00067 # 外部のSDO/RTCまたはアプリケーションは、自身が持つSDO Servcie
00068 # Provider の参照をIDおよびinterface type、プロパティとともに
00069 # ServcieProfile にセットしたうえで、add_service_profile() の引数と
00070 # して与えることで、当該SDO/RTCにサービスを与える。この際、IDはUUID
00071 # など一意なIDでなければならない。また、削除する際にはIDにより対象と
00072 # するServiceProfileを探索するため、サービス提供側では削除時までIDを
00073 # 保持しておかなければならない。
00074 #
00075 # 
00076 #
00077 #
00078 #
00079 # @since 1.1.0
00080 #
00081 # @else
00082 #
00083 # @class SDO service administration class
00084 # @brief SDO service administration class
00085 #
00086 #
00087 # @since 1.1.0
00088 #
00089 # @endif
00090 class SdoServiceAdmin:
00091   """
00092   """
00093 
00094   
00095   ##
00096   # @if jp
00097   # @brief コンストラクタ
00098   # コンストラクタ
00099   # @param 
00100   # 
00101   # @else
00102   # @brief Constructor
00103   # Constructor
00104   # @param 
00105   # @endif
00106   # SdoServiceAdmin(::RTC::RTObject_impl& rtobj);
00107   def __init__(self, rtobj):
00108     self._rtobj = rtobj
00109     self._consumerTypes = []
00110     self._providers = []
00111     self._allConsumerEnabled = True
00112 
00113 
00114     ##
00115     # @if jp
00116     # @brief Lock 付き SDO ServiceProfileList
00117     # @else
00118     # @brief SDO ServiceProfileList with mutex lock
00119     # @endif
00120     self._providerProfiles = []
00121     self._provider_mutex = threading.RLock()
00122     
00123     ##
00124     # @if jp
00125     # @brief Lock 付き SDO ServiceProfileList
00126     # @else
00127     # @brief SDO ServiceProfileList with mutex lock
00128     # @endif
00129     self._consumers = []
00130     self._consumer_mutex = threading.RLock()
00131 
00132     ##
00133     # @if jp
00134     # @brief logger
00135     # @else
00136     # @brief logger
00137     # @endif
00138     self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf("SdoServiceAdmin")
00139 
00140     self._rtcout.RTC_TRACE("SdoServiceAdmin::SdoServiceAdmin(%s)",
00141                            rtobj.getProperties().getProperty("instance_name"))
00142 
00143     prop = self._rtobj.getProperties()
00144 
00145     # ------------------------------------------------------------
00146     # SDO service provider
00147     enabledProviderTypes = [s.strip() for s in prop.getProperty("sdo.service.provider.enabled_services").split(",")]
00148     self._rtcout.RTC_DEBUG("sdo.service.provider.enabled_services: %s",
00149                            prop.getProperty("sdo.service.provider.enabled_services"))
00150 
00151     availableProviderTypes = OpenRTM_aist.SdoServiceProviderFactory.instance().getIdentifiers()
00152     prop.setProperty("sdo.service.provider.available_services",
00153                      str(OpenRTM_aist.flatten(availableProviderTypes)))
00154     self._rtcout.RTC_DEBUG("sdo.service.provider.available_services: %s",
00155                            prop.getProperty("sdo.service.provider.available_services"))
00156 
00157     
00158     # If types include '[Aa][Ll][Ll]', all types enabled in this RTC
00159     activeProviderTypes = []
00160     for i in range(len(enabledProviderTypes)):
00161       tmp = enabledProviderTypes[i].lower()
00162       if tmp == "all":
00163         activeProviderTypes = availableProviderTypes
00164         self._rtcout.RTC_DEBUG("sdo.service.provider.enabled_services: ALL")
00165         break
00166 
00167       for j in range(len(availableProviderTypes)):
00168         if availableProviderTypes[j] == enabledProviderTypes[i]:
00169           activeProviderTypes.append(availableProviderTypes[j])
00170 
00171     factory = OpenRTM_aist.SdoServiceProviderFactory.instance()
00172     for i in range(len(activeProviderTypes)):
00173       svc = factory.createObject(activeProviderTypes[i])
00174       propkey = self.ifrToKey(activeProviderTypes[i])
00175       properties = []
00176       OpenRTM_aist.NVUtil.copyFromProperties(properties,
00177                                              prop.getNode(str(propkey)))
00178       prof = SDOPackage.ServiceProfile(str(activeProviderTypes[i]),
00179                                        str(activeProviderTypes[i]),
00180                                        properties,
00181                                        svc._this())
00182 
00183       svc.init(rtobj, prof)
00184       self._providers.append(svc)
00185 
00186     # ------------------------------------------------------------
00187     # SDO service consumer
00188     # getting consumer types from RTC's properties
00189     constypes = prop.getProperty("sdo.service.consumer.enabled_services")
00190     self._consumerTypes = [s.strip() for s in constypes.split(",")]
00191     self._rtcout.RTC_DEBUG("sdo.service.consumer.enabled_services: %s",
00192                            str(constypes))
00193 
00194     prop.setProperty("sdo.service.consumer.available_services",
00195                      str(OpenRTM_aist.flatten(OpenRTM_aist.SdoServiceConsumerFactory.instance().getIdentifiers())))
00196     self._rtcout.RTC_DEBUG("sdo.service.consumer.available_services: %s",
00197                            prop.getProperty("sdo.service.consumer.available_services"))
00198 
00199     # If types include '[Aa][Ll][Ll]', all types allowed in this RTC
00200     for ctype in self._consumerTypes:
00201       tmp = ctype.lower()
00202       if tmp == "all":
00203         self._allConsumerEnabled = True
00204         self._rtcout.RTC_DEBUG("sdo_service.consumer_types: ALL")
00205 
00206     return
00207 
00208 
00209   ##
00210   # @if jp
00211   # @brief 仮想デストラクタ
00212   # 仮想デストラクタ。
00213   # 
00214   # @else
00215   # @brief Virtual destractor
00216   # Virtual destractor.
00217   # @endif
00218   def __del__(self):
00219     len_ = len(self._proiders)
00220     for i in range(len_):
00221       idx = (len_ - 1) - i
00222       self._providers[idx].finalize()
00223       del self._providers[idx]
00224 
00225     self._providers = []
00226 
00227     len_ = len(self._consumers)
00228     for i in range(len_):
00229       idx = (len_ - 1) - i
00230       self._consumers[idx].finalize()
00231       del self._consumers[idx]
00232 
00233     self._consumers = []
00234     return
00235 
00236 
00237   ##
00238   # @if jp
00239   # @brief SDO Service Provider の ServiceProfileList を取得する
00240   # @else
00241   # @brief Get ServiceProfileList of SDO Service Provider
00242   # @endif
00243   #
00244   # SDOPackage::ServiceProfileList* SdoServiceAdmin::getServiceProviderProfiles()
00245   def getServiceProviderProfiles(self):
00246     prof = []
00247     guard = OpenRTM_aist.ScopedLock(self._provider_mutex)
00248     for i in range(len(self._providers)):
00249       prof.append(self._providers[i].getProfile())
00250     return prof
00251 
00252 
00253   ##
00254   # @if jp
00255   # @brief SDO Service Provider の ServiceProfile を取得する
00256   # @else
00257   # @brief Get ServiceProfile of an SDO Service Provider
00258   # @endif
00259   #
00260   # SDOPackage::ServiceProfile*
00261   # SdoServiceAdmin::getServiceProviderProfile(const char* id)
00262   def getServiceProviderProfile(self, id):
00263     idstr = id
00264     guard = OpenRTM_aist.ScopedLock(self._provider_mutex)
00265     for i in range(len(self._providers)):
00266       if idstr == str(self._providers[i].getProfile().id):
00267         return self._providers[i].getProfile()
00268 
00269     raise SDOPackage.InvalidParameter()
00270 
00271 
00272   ##
00273   # @if jp
00274   # @brief SDO Service Provider の Service を取得する
00275   # @else
00276   # @brief Get ServiceProfile of an SDO Service
00277   # @endif
00278   #
00279   # SDOPackage::SDOService_ptr SdoServiceAdmin::getServiceProvider(const char* id)
00280   def getServiceProvider(self, id):
00281     prof = self.getServiceProviderProfile(id)
00282     return prof.service
00283 
00284 
00285   ##
00286   # @if jp
00287   # @brief SDO service provider をセットする
00288   # @else
00289   # @brief Set a SDO service provider
00290   # @endif
00291   #
00292   # bool SdoServiceAdmin::
00293   # addSdoServiceProvider(const SDOPackage::ServiceProfile& prof,
00294   #                       SdoServiceProviderBase* provider)
00295   def addSdoServiceProvider(self, prof, provider):
00296     self._rtcout.RTC_TRACE("SdoServiceAdmin::addSdoServiceProvider(if=%s)",
00297                            prof.interface_type)
00298     guard = OpenRTM_aist.ScopedLock(self._provider_mutex)
00299     id = prof.id
00300     for i in range(len(self._providers)):
00301       if id == str(self._providers[i].getProfile().id):
00302         self._rtcout.RTC_ERROR("SDO service(id=%s, ifr=%s) already exists",
00303                                str(prof.id), str(prof.interface_type))
00304         return False
00305 
00306     self._providers.append(provider)
00307     return True
00308 
00309 
00310   ##
00311   # @if jp
00312   # @brief SDO service provider を削除する
00313   # @else
00314   # @brief Remove a SDO service provider
00315   # @endif
00316   #
00317   # bool SdoServiceAdmin::removeSdoServiceProvider(const char* id)
00318   def removeSdoServiceProvider(self, id):
00319     self._rtcout.RTC_TRACE("removeSdoServiceProvider(%d)", id)
00320     guard = OpenRTM_aist.ScopedLock(self._provider_mutex)
00321 
00322     strid = id
00323     len_ = len(self._providers)
00324     for i in range(len_):
00325       idx = (len_ - 1) - i
00326       if strid == str(self._providers[idx].getProfile().id):
00327         self._providers[idx].finalize()
00328         factory = OpenRTM_aist.SdoServiceProviderFactory.instance()
00329         factory.deleteObject(self._providers[idx])
00330         del self._providers[idx]
00331         self._rtcout.RTC_INFO("SDO service provider has been deleted: %s", id)
00332         return True
00333     self._rtcout.RTC_WARN("Specified SDO service provider not found: %s", id)
00334     return False
00335 
00336 
00337   ##
00338   # @if jp
00339   # @brief Service Consumer を追加する
00340   # 
00341   # @else
00342   # @brief Add Service Consumer
00343   # @endif
00344   # bool addSdoServiceConsumer(const SDOPackage::ServiceProfile& sProfile);
00345   def addSdoServiceConsumer(self, sProfile):
00346     self._rtcout.RTC_TRACE("addSdoServiceConsumer(IFR = %s)",
00347                            sProfile.interface_type)
00348     profile = copy.deepcopy(sProfile)
00349 
00350     # Not supported consumer type -> error return
00351     if not self.isEnabledConsumerType(sProfile):
00352       self._rtcout.RTC_ERROR("Not supported consumer type. %s", profile.id)
00353       return False
00354 
00355     if not self.isExistingConsumerType(sProfile):
00356       self._rtcout.RTC_ERROR("type %s already exists.", profile.id)
00357       return False
00358     if str(profile.id) ==  "":
00359       self._rtcout.RTC_WARN("No id specified. It should be given by clients.")
00360       return False
00361 
00362     # re-initialization
00363     guard = OpenRTM_aist.ScopedLock(self._consumer_mutex)
00364     id = str(sProfile.id)
00365     for i in range(len(self._consumers)):
00366       if id == str(self._consumers[i].getProfile().id):
00367         self._rtcout.RTC_INFO("Existing consumer is reinitilized.")
00368         self._rtcout.RTC_DEBUG("Propeteis are: %s",
00369                                NVUtil.toString(sProfile.properties))
00370         return self._consumers[i].reinit(sProfile)
00371     del guard
00372 
00373     # new pofile
00374     factory = OpenRTM_aist.SdoServiceConsumerFactory.instance()
00375     ctype = str(profile.interface_type)
00376     consumer = factory.createObject(ctype)
00377     if consumer == None:
00378       self._rtcout.RTC_ERROR("Hmm... consumer must be created.")
00379       return False
00380 
00381     # initialize
00382     if not consumer.init(self._rtobj, sProfile):
00383       self._rtcout.RTC_WARN("SDO service initialization was failed.")
00384       self._rtcout.RTC_DEBUG("id:         %s", str(sProfile.id))
00385       self._rtcout.RTC_DEBUG("IFR:        %s", str(sProfile.interface_type))
00386       self._rtcout.RTC_DEBUG("properties: %s", OpenRTM_aist.NVUtil.toString(sProfile.properties))
00387       factory.deleteObject(consumer)
00388       self._rtcout.RTC_INFO("SDO consumer was deleted by initialization failure")
00389       return False
00390 
00391     # store consumer
00392     guard = OpenRTM_aist.ScopedLock(self._consumer_mutex)
00393     self._consumers.append(consumer)
00394     del guard
00395 
00396     return True
00397 
00398   
00399   ##
00400   # @if jp
00401   # @brief Service Consumer を削除する
00402   # 
00403   # @else
00404   # @brief Remove Service Consumer
00405   # @endif
00406   # bool removeSdoServiceConsumer(const char* id);
00407   def removeSdoServiceConsumer(self, id):
00408     if id == None or id[0] == '\0':
00409       self._rtcout.RTC_ERROR("removeSdoServiceConsumer(): id is invalid.")
00410       return False
00411 
00412     self._rtcout.RTC_TRACE("removeSdoServiceConsumer(id = %s)", id)
00413 
00414     guard = OpenRTM_aist.ScopedLock(self._consumer_mutex)
00415     strid = id
00416 
00417     for (idx,cons) in enumerate(self._consumers):
00418       if strid == str(cons.getProfile().id):
00419         cons.finalize()
00420         del self._consumers[idx]
00421         factory = OpenRTM_aist.SdoServiceConsumerFactory.instance()
00422         factory.deleteObject(cons)
00423         self._rtcout.RTC_INFO("SDO service has been deleted: %s", id)
00424         return True
00425 
00426     self._rtcout.RTC_WARN(("Specified SDO consumer not found: %s", id))
00427     return False
00428     
00429 
00430   ##
00431   # @if jp
00432   # @brief 許可されたサービス型かどうか調べる
00433   # @else
00434   # @brief If it is enabled service type
00435   # @endif
00436   #
00437   # bool SdoServiceAdmin::
00438   # isEnabledConsumerType(const SDOPackage::ServiceProfile& sProfile)
00439   def isEnabledConsumerType(self, sProfile):
00440     if self._allConsumerEnabled:
00441       return True
00442 
00443     for i in range(len(self._consumerTypes)):
00444       if self._consumerTypes[i] == str(sProfile.interface_type):
00445         self._rtcout.RTC_DEBUG("%s is supported SDO service.",
00446                                str(sProfile.interface_type))
00447         return True
00448 
00449     self._rtcout.RTC_WARN("Consumer type is not supported: %s",
00450                           str(sProfile.interface_type))
00451     return False
00452 
00453 
00454   ##
00455   # @if jp
00456   # @brief 存在するサービス型かどうか調べる
00457   # 
00458   # @else
00459   # @brief If it is existing service type
00460   # @endif
00461   # bool isExistingConsumerType(const SDOPackage::ServiceProfile& sProfile);
00462   def isExistingConsumerType(self, sProfile):
00463     factory = OpenRTM_aist.SdoServiceConsumerFactory.instance()
00464     consumerTypes = factory.getIdentifiers()
00465     for i in range(len(consumerTypes)):
00466       if consumerTypes[i] == str(sProfile.interface_type):
00467         self._rtcout.RTC_DEBUG("%s exists in the SDO service factory.", str(sProfile.interface_type))
00468         self._rtcout.RTC_PARANOID("Available SDO serices in the factory: %s", str(OpenRTM_aist.flatten(consumerTypes)))
00469         return True
00470     self._rtcout.RTC_WARN("No available SDO service in the factory: %s",
00471                           str(sProfile.interface_type))
00472     return False
00473 
00474 
00475   # const std::string getUUID() const;
00476   def getUUID(self):
00477     return str(OpenRTM_aist.uuid1())
00478 
00479   # std::string SdoServiceAdmin::ifrToKey(std::string& ifr)
00480   def ifrToKey(self, ifr):
00481     ifrvstr = ifr.split(":")
00482     ifrvstr[1] = ifrvstr[1].lower()
00483     ifrvstr[1] = ifrvstr[1].replace(".", "_")
00484     ifrvstr[1] = ifrvstr[1].replace("/", ".")
00485     return ifrvstr[1]


openrtm_aist_python
Author(s): Shinji Kurihara
autogenerated on Thu Aug 27 2015 14:17:28