Package rocon_gateway :: Module hub_manager
[frames] | no frames]

Source Code for Module rocon_gateway.hub_manager

  1  #!/usr/bin/env pythonupdate 
  2  # 
  3  # License: BSD 
  4  #   https://raw.github.com/robotics-in-concert/rocon_multimaster/hydro_devel/hub_manager/LICENSE 
  5  # 
  6  ############################################################################### 
  7  # Imports 
  8  ############################################################################### 
  9   
 10  import threading 
 11  import rospy 
 12  import gateway_msgs.msg as gateway_msgs 
 13  import rocon_hub_client 
 14   
 15  # local imports 
 16  from .exceptions import GatewayUnavailableError 
 17  import gateway_hub 
 18   
 19  ############################################################################## 
 20  # Hub Manager 
 21  ############################################################################## 
 22   
 23   
24 -class HubManager(object):
25 26 ########################################################################## 27 # Init & Shutdown 28 ########################################################################## 29
30 - def __init__(self, hub_whitelist, hub_blacklist):
31 self._param = {} 32 self._param['hub_whitelist'] = hub_whitelist 33 self._param['hub_blacklist'] = hub_blacklist 34 self.hubs = [] 35 self._hub_lock = threading.Lock()
36
37 - def shutdown(self):
38 for hub in self.hubs: 39 hub.unregister_gateway()
40
41 - def is_connected(self):
42 return True if self.hubs else False
43 44 ########################################################################## 45 # Introspection 46 ########################################################################## 47
49 ''' 50 Parse all the hubs and retrieve the list of remote gateway names. 51 52 Note: not sure where is most convenient, here or in gateway class. 53 54 @return list of remote gateway names (with hashes), e.g. gateway345ae2c... 55 @rtype list of str 56 ''' 57 remote_gateway_names = [] 58 self._hub_lock.acquire() 59 for hub in self.hubs: 60 remote_gateway_names.extend(hub.list_remote_gateway_names()) 61 self._hub_lock.release() 62 # return the list without duplicates 63 return list(set(remote_gateway_names))
64
66 ''' 67 Utility function to parse all hubs for the remote gateways and 68 create a dictionary of the type: 69 70 dic['remote_gateway_name'] = ['hub1', 'hub2'] 71 72 where the hub list is a list of actual hub object references. 73 ''' 74 dic = {} 75 self._hub_lock.acquire() 76 for hub in self.hubs: 77 for remote_gateway in hub.list_remote_gateway_names(): 78 if remote_gateway in dic: 79 dic[remote_gateway].append(hub) 80 else: 81 dic[remote_gateway] = [hub] 82 self._hub_lock.release() 83 return dic
84
85 - def remote_gateway_info(self, remote_gateway_name):
86 ''' 87 Return information that a remote gateway has posted on the hub(s). 88 89 @param remote_gateway_name : the hash name for the remote gateway 90 @type str 91 92 @return remote gateway information 93 @rtype gateway_msgs.RemotGateway or None 94 ''' 95 remote_gateway_info = None 96 self._hub_lock.acquire() 97 for hub in self.hubs: 98 if remote_gateway_name in hub.list_remote_gateway_names(): 99 # I don't think we need more than one hub's info.... 100 remote_gateway_info = hub.remote_gateway_info(remote_gateway_name) 101 break 102 self._hub_lock.release() 103 return remote_gateway_info
104
105 - def get_remote_gateway_firewall_flag(self, remote_gateway_name):
106 ''' 107 Return information that a remote gateway has posted on the hub(s). 108 109 @param remote_gateway_name : the hash name for the remote gateway 110 @type string 111 112 @return True, false if the flag is set or not, None if remote 113 gateway information cannot found 114 @rtype Bool 115 ''' 116 firewall_flag = None 117 self._hub_lock.acquire() 118 for hub in self.hubs: 119 if remote_gateway_name in hub.list_remote_gateway_names(): 120 # I don't think we need more than one hub's info.... 121 try: 122 firewall_flag = hub.get_remote_gateway_firewall_flag(remote_gateway_name) 123 break 124 except GatewayUnavailableError: 125 pass # cycle through the other hubs looking as well. 126 self._hub_lock.release() 127 return firewall_flag
128
129 - def send_unflip_request(self, remote_gateway_name, remote_rule):
130 ''' 131 Send an unflip request to the specified gateway through 132 the first common hub that can be found. 133 134 Doesn't raise GatewayUnavailableError if nothing got sent as the higher level 135 doesn't need any logic there yet (only called from gateway.shutdown). 136 137 @param remote_gateway_name : the hash name for the remote gateway 138 @type string 139 140 @param remote_rule : the remote rule to unflip 141 @type gateway_msgs.RemoteRule 142 ''' 143 self._hub_lock.acquire() 144 for hub in self.hubs: 145 if remote_gateway_name in hub.list_remote_gateway_names(): 146 # I don't think we need more than one hub's info.... 147 try: 148 hub.send_unflip_request(remote_gateway_name, remote_rule) 149 self._hub_lock.release() 150 return 151 except GatewayUnavailableError: 152 pass # cycle through the other hubs looking as well. 153 self._hub_lock.release()
154 155 ########################################################################## 156 # Hub Connections 157 ########################################################################## 158
159 - def connect_to_hub(self, ip, port):
160 ''' 161 Attempts to make a connection and register the gateway with a hub. 162 163 @param ip 164 @param port 165 166 @return an integer indicating error (important for the service call) 167 @rtype gateway_msgs.ErrorCodes 168 169 @raise 170 ''' 171 try: 172 new_hub = gateway_hub.GatewayHub(ip, port, self._param['hub_whitelist'], self._param['hub_blacklist']) 173 except rocon_hub_client.HubError as e: 174 return None, e.id, str(e) 175 already_exists_error = False 176 self._hub_lock.acquire() 177 for hub in self.hubs: 178 if hub.uri == new_hub.uri: 179 already_exists_error = True 180 break 181 self._hub_lock.release() 182 if not already_exists_error: 183 self._hub_lock.acquire() 184 self.hubs.append(new_hub) 185 self._hub_lock.release() 186 return new_hub, gateway_msgs.ErrorCodes.SUCCESS, "success" 187 else: 188 return None, gateway_msgs.ErrorCodes.HUB_CONNECTION_ALREADY_EXISTS, "already connected to this hub"
189
190 - def disengage_hub(self, hub_to_be_disengaged):
191 ''' 192 Disengages a hub. Make sure all necessary connections 193 are cleaned up before calling this (Gateway.disengage_hub). 194 195 @param hub_to_be_disengaged 196 ''' 197 #uri = str(ip) + ":" + str(port) 198 # Could dig in and find the name here, but not worth the bother. 199 rospy.loginfo("Gateway : lost connection to the hub [%s][%s]" % (hub_to_be_disengaged.name, hub_to_be_disengaged.uri)) 200 self._hub_lock.acquire() 201 self.hubs[:] = [hub for hub in self.hubs if hub != hub_to_be_disengaged] 202 self._hub_lock.release()
203
204 - def advertise(self, connection):
205 self._hub_lock.acquire() 206 for hub in self.hubs: 207 hub.advertise(connection) 208 self._hub_lock.release()
209
210 - def unadvertise(self, connection):
211 self._hub_lock.acquire() 212 for hub in self.hubs: 213 hub.unadvertise(connection) 214 self._hub_lock.release()
215
216 - def match_remote_gateway_name(self, remote_gateway_name):
217 ''' 218 Parses the hub lists looking for strong (identical) and 219 weak (matches the name without the uuid hash) matches. 220 ''' 221 matches = [] 222 weak_matches = [] # doesn't match any hash names, but matches a base name 223 self._hub_lock.acquire() 224 for hub in self.hubs: 225 matches.extend(hub.matches_remote_gateway_name(remote_gateway_name)) 226 weak_matches.extend(hub.matches_remote_gateway_basename(remote_gateway_name)) 227 self._hub_lock.release() 228 # these are hash name lists, make sure they didn't pick up matches for a single hash name from multiple hubs 229 matches = list(set(matches)) 230 weak_matches = list(set(weak_matches)) 231 return matches, weak_matches
232