1
2
3
4
5
6
7
8
9
10 import threading
11 import rospy
12 import gateway_msgs.msg as gateway_msgs
13 import rocon_hub_client
14
15
16 from .exceptions import GatewayUnavailableError
17 import gateway_hub
18
19
20
21
22
23
25
26
27
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
40
42 return True if self.hubs else False
43
44
45
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
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
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
100 remote_gateway_info = hub.remote_gateway_info(remote_gateway_name)
101 break
102 self._hub_lock.release()
103 return remote_gateway_info
104
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
121 try:
122 firewall_flag = hub.get_remote_gateway_firewall_flag(remote_gateway_name)
123 break
124 except GatewayUnavailableError:
125 pass
126 self._hub_lock.release()
127 return firewall_flag
128
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
147 try:
148 hub.send_unflip_request(remote_gateway_name, remote_rule)
149 self._hub_lock.release()
150 return
151 except GatewayUnavailableError:
152 pass
153 self._hub_lock.release()
154
155
156
157
158
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
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
198
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
205 self._hub_lock.acquire()
206 for hub in self.hubs:
207 hub.advertise(connection)
208 self._hub_lock.release()
209
211 self._hub_lock.acquire()
212 for hub in self.hubs:
213 hub.unadvertise(connection)
214 self._hub_lock.release()
215
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 = []
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
229 matches = list(set(matches))
230 weak_matches = list(set(weak_matches))
231 return matches, weak_matches
232