示例#1
0
    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)
示例#2
0
 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)
示例#3
0
 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)
示例#4
0
 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)
示例#5
0
    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
示例#6
0
    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
示例#7
0
    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
示例#8
0
    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
示例#9
0
    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)
示例#10
0
    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))
示例#11
0
    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
示例#12
0
    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