def synchronize(self): """Synchronize local subscriptions with the PubSubService. """ result = next(self._results) subscriptions = { platform: { bus: list(subscriptions.keys()) } for platform, bus_subscriptions in self._my_subscriptions.items() for bus, subscriptions in bus_subscriptions.items() } sync_msg = jsonapi.dumpb(dict(subscriptions=subscriptions)) frames = ['synchronize', 'connected', sync_msg] # For backward compatibility with old pubsub if self._send_via_rpc: delay = random.random() self.core().spawn_later(delay, self.rpc().notify, 'pubsub', 'pubsub.sync', subscriptions) else: # Parameters are stored initially, in case remote agent/platform is using old pubsub if self._parameters_needed: kwargs = dict(op='synchronize', subscriptions=subscriptions) self._save_parameters(result.ident, **kwargs) self.vip_socket.send_vip('', 'pubsub', frames, result.ident, copy=False) # 2073 - python3 dictionary keys method returns a dict_keys structure that isn't serializable. # added list(subscriptions.keys()) to make it like python2 list of strings. items = [{ platform: { bus: list(subscriptions.keys()) } for platform, bus_subscriptions in self._my_subscriptions.items() for bus, subscriptions in bus_subscriptions.items() }] for subscriptions in items: sync_msg = jsonapi.dumpb(dict(subscriptions=subscriptions)) frames = ['synchronize', 'connected', sync_msg] # For backward compatibility with old pubsub if self._send_via_rpc: delay = random.random() self.core().spawn_later(delay, self.rpc().notify, 'pubsub', 'pubsub.sync', subscriptions) else: # Parameters are stored initially, in case remote agent/platform is using old pubsub if self._parameters_needed: kwargs = dict(op='synchronize', subscriptions=subscriptions) self._save_parameters(result.ident, **kwargs) self.vip_socket.send_vip('', 'pubsub', frames, result.ident, copy=False)
def _distribute(self, peer, topic, headers, message=None, bus=''): self._check_if_protected_topic(topic) try: subscriptions = self._my_subscriptions[bus] except KeyError: subscriptions = dict() subscribers = set() for prefix, subscription in subscriptions.items(): if subscription and topic.startswith(prefix): subscribers |= subscription if subscribers: sender = encode_peer(peer) json_msg = jsonapi.dumpb( jsonrpc.json_method(None, 'pubsub.push', [sender, bus, topic, headers, message], None)) frames = [ zmq.Frame(''), zmq.Frame(''), zmq.Frame('RPC'), zmq.Frame(json_msg) ] socket = self.core().socket for subscriber in subscribers: socket.send(subscriber, flags=SNDMORE) socket.send_multipart(frames, copy=False) return len(subscribers)
def _send_auth_update_to_pubsub(self): user_to_caps = self.get_user_to_capabilities() # Send auth update message to router json_msg = jsonapi.dumpb(dict(capabilities=user_to_caps)) frames = [zmq.Frame(b'auth_update'), zmq.Frame(json_msg)] # <recipient, subsystem, args, msg_id, flags> self.core.socket.send_vip(b'', b'pubsub', frames, copy=False)
def store(self, data): fd = os.open(self.filename, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, self.permissions) try: os.write(fd, jsonapi.dumpb(data, indent=4)) finally: os.close(fd)
def setup_send_file(self, channel_name): _log.debug("Setup send file executed!") BYTES_REQUESTED = 1024 peer = self.vip.rpc.context.vip_message.peer _log.debug(f"Creating channel to peer {peer} named: {channel_name}") channel = self.vip.channel(peer, channel_name) _log.debug("Sending data back to peer contact.") make_fetch_request = jsonapi.dumpb(['fetch', BYTES_REQUESTED]) make_checksum_request = jsonapi.dumpb(['checksum', '']) # channel.send(data_str) # .send_multipart(serialize_frames(['fetch', BYTES_REQUESTED])) # # channel.send(BYTES_REQUESTED) # data = channel.recv() # _log.debug(f"data received {len(data)}") with open(self.receiver_file_path, "wb") as fout: sha512 = hashlib.sha512() while True: _log.debug("Receiver sending fetch") channel.send(make_fetch_request) # chunk binary representation of the bytes read from # the other side of the connectoin chunk = channel.recv() if chunk == b'complete': _log.debug("Completed file") break _log.debug("Receiver sending checksum") channel.send(make_checksum_request) checksum = channel.recv() _log.debug(f"The checksum returned was: {checksum}") sha512.update(chunk) _log.debug(f"Received checksum: {checksum}") _log.debug(f"Expected checksum: {sha512.hexdigest()}") assert checksum.decode('utf-8') == sha512.hexdigest( ), "Invalid checksum detected." fout.write(chunk) _log.debug("File completed!") channel.close(linger=0) del channel
def subscribe(self, peer, prefix, callback, bus='', all_platforms=False, persistent_queue=None): """Subscribe to topic and register callback. Subscribes to topics beginning with prefix. If callback is supplied, it should be a function taking four arguments, callback(peer, sender, bus, topic, headers, message), where peer is the ZMQ identity of the bus owner sender is identity of the publishing peer, topic is the full message topic, headers is a case-insensitive dictionary (mapping) of message headers, and message is a possibly empty list of message parts. :param peer :type peer :param prefix prefix to the topic :type prefix str :param callback callback method :type callback method :param bus bus :type bus str :param platforms :type platforms :returns: Subscribe is successful or not :rtype: boolean :Return Values: Success or Failure """ # For backward compatibility with old pubsub if self._send_via_rpc: self._add_subscription(prefix, callback, bus) return self.rpc().call(peer, 'pubsub.subscribe', prefix, bus=bus) else: result = next(self._results) # Parameters are stored initially, in case remote agent/platform is using old pubsub if self._parameters_needed: kwargs = dict(op='subscribe', prefix=prefix, bus=bus) self._save_parameters(result.ident, **kwargs) self._add_subscription(prefix, callback, bus, all_platforms) sub_msg = jsonapi.dumpb( dict(prefix=prefix, bus=bus, all_platforms=all_platforms)) frames = ['subscribe', sub_msg] self.vip_socket.send_vip('', 'pubsub', frames, result.ident, copy=False) return result
def list(self, peer, prefix='', bus='', subscribed=True, reverse=False, all_platforms=False): """Gets list of subscriptions matching the prefix and bus for the specified peer. param peer: peer type peer: str param prefix: prefix of a topic type prefix: str param bus: bus type bus: bus param subscribed: subscribed or not type subscribed: boolean param reverse: reverse type reverse: :returns: List of subscriptions, i.e, list of tuples of bus, topic and flag to indicate if peer is a subscriber or not :rtype: list of tuples :Return Values: List of tuples [(topic, bus, flag to indicate if peer is a subscriber or not)] """ # For backward compatibility with old pubsub if self._send_via_rpc: return self.rpc().call(peer, 'pubsub.list', prefix, bus, subscribed, reverse) else: result = next(self._results) # Parameters are stored initially, in case remote agent/platform is using old pubsub if self._parameters_needed: kwargs = dict(op='list', prefix=prefix, subscribed=subscribed, reverse=reverse, bus=bus) self._save_parameters(result.ident, **kwargs) list_msg = jsonapi.dumpb( dict(prefix=prefix, all_platforms=all_platforms, subscribed=subscribed, reverse=reverse, bus=bus)) frames = ['list', list_msg] self.vip_socket.send_vip('', 'pubsub', frames, result.ident, copy=False) return result
def unsubscribe(self, peer, prefix, callback, bus='', all_platforms=False): """Unsubscribe and remove callback(s). Remove all handlers matching the given info - peer, callback and bus, which was used earlier to subscribe as well. If all handlers for a topic prefix are removed, the topic is also unsubscribed. param peer: peer type peer: str param prefix: prefix that needs to be unsubscribed type prefix: str param callback: callback method type callback: method param bus: bus type bus: bus return: success or not :rtype: boolean :Return Values: success or not """ # For backward compatibility with old pubsub if self._send_via_rpc == True: topics = self._drop_subscription(prefix, callback, bus) return self.rpc().call(peer, 'pubsub.unsubscribe', topics, bus=bus) else: subscriptions = dict() result = next(self._results) if not all_platforms: platform = 'internal' topics = self._drop_subscription(prefix, callback, bus, platform) subscriptions[platform] = dict(prefix=topics, bus=bus) else: platform = 'all' topics = self._drop_subscription(prefix, callback, bus, platform) subscriptions[platform] = dict(prefix=topics, bus=bus) # Parameters are stored initially, in case remote agent/platform is using old pubsub if self._parameters_needed: kwargs = dict(op='unsubscribe', prefix=topics, bus=bus) self._save_parameters(result.ident, **kwargs) unsub_msg = jsonapi.dumpb(subscriptions) topics = self._drop_subscription(prefix, callback, bus) frames = ['unsubscribe', unsub_msg] self.vip_socket.send_vip('', 'pubsub', frames, result.ident, copy=False) return result
def synchronize(self): """Synchronize local subscriptions with the PubSubService. """ result = next(self._results) subscriptions = { platform: { bus: list(subscriptions.keys()) } for platform, bus_subscriptions in self._my_subscriptions.items() for bus, subscriptions in bus_subscriptions.items() } sync_msg = jsonapi.dumpb(dict(subscriptions=subscriptions)) frames = ['synchronize', 'connected', sync_msg] self.vip_socket.send_vip('', 'pubsub', frames, result.ident, copy=False) # 2073 - python3 dictionary keys method returns a dict_keys structure that isn't serializable. # added list(subscriptions.keys()) to make it like python2 list of strings. items = [{ platform: { bus: list(subscriptions.keys()) } for platform, bus_subscriptions in self._my_subscriptions.items() for bus, subscriptions in bus_subscriptions.items() }] for subscriptions in items: sync_msg = jsonapi.dumpb(dict(subscriptions=subscriptions)) frames = ['synchronize', 'connected', sync_msg] self.vip_socket.send_vip('', 'pubsub', frames, result.ident, copy=False)
def _send_protected_update_to_pubsub(self, contents): protected_topics_msg = jsonapi.dumpb(contents) frames = [ zmq.Frame(b'protected_update'), zmq.Frame(protected_topics_msg) ] if self._is_connected: try: # <recipient, subsystem, args, msg_id, flags> self.core.socket.send_vip(b'', b'pubsub', frames, copy=False) except VIPError as ex: _log.error( "Error in sending protected topics update to clear PubSub: " + str(ex))
def list(self, peer, prefix='', bus='', subscribed=True, reverse=False, all_platforms=False): """Gets list of subscriptions matching the prefix and bus for the specified peer. param peer: peer type peer: str param prefix: prefix of a topic type prefix: str param bus: bus type bus: bus param subscribed: subscribed or not type subscribed: boolean param reverse: reverse type reverse: :returns: List of subscriptions, i.e, list of tuples of bus, topic and flag to indicate if peer is a subscriber or not :rtype: list of tuples :Return Values: List of tuples [(topic, bus, flag to indicate if peer is a subscriber or not)] """ result = next(self._results) list_msg = jsonapi.dumpb( dict(prefix=prefix, all_platforms=all_platforms, subscribed=subscribed, reverse=reverse, bus=bus)) frames = ['list', list_msg] self.vip_socket.send_vip('', 'pubsub', frames, result.ident, copy=False) return result
def unsubscribe(self, peer, prefix, callback, bus='', all_platforms=False): """Unsubscribe and remove callback(s). Remove all handlers matching the given info - peer, callback and bus, which was used earlier to subscribe as well. If all handlers for a topic prefix are removed, the topic is also unsubscribed. param peer: peer type peer: str param prefix: prefix that needs to be unsubscribed type prefix: str param callback: callback method type callback: method param bus: bus type bus: bus return: success or not :rtype: boolean :Return Values: success or not """ subscriptions = dict() result = next(self._results) if not all_platforms: platform = 'internal' topics = self._drop_subscription(prefix, callback, bus, platform) subscriptions[platform] = dict(prefix=topics, bus=bus) else: platform = 'all' topics = self._drop_subscription(prefix, callback, bus, platform) subscriptions[platform] = dict(prefix=topics, bus=bus) unsub_msg = jsonapi.dumpb(subscriptions) topics = self._drop_subscription(prefix, callback, bus) frames = ['unsubscribe', unsub_msg] self.vip_socket.send_vip('', 'pubsub', frames, result.ident, copy=False) return result