Ejemplo n.º 1
0
 def _distribute(self, peer, topic, headers, message=None, bus=''):
     try:
         subscriptions = self._peer_subscriptions[bus]
     except KeyError:
         return 0
     subscribers = set()
     for prefix, subscription in subscriptions.iteritems():
         if subscription and topic.startswith(prefix):
             subscribers |= subscription
     if subscribers:
         sender = encode_peer(peer)
         json_msg = jsonapi.dumps(
             jsonrpc.json_method(None, 'pubsub.push',
                                 [sender, bus, topic, headers, message],
                                 None))
         frames = [
             zmq.Frame(b''),
             zmq.Frame(b''),
             zmq.Frame(b'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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
    def publish(self, peer, topic, headers=None, message=None, bus=''):
        """Publish a message to a given topic via a peer.

        Publish headers and message to all subscribers of topic on bus.
        If peer is None, use self. Adds volttron platform version
        compatibility information to header as variables
        min_compatible_version and max_compatible version
        param peer: peer
        type peer: str
        param topic: topic for the publish message
        type topic: str
        param headers: header info for the message
        type headers: None or dict
        param message: actual message
        type message: None or any
        param bus: bus
        type bus: str
        return: Number of subscribers the message was sent to.
        :rtype: int

        :Return Values:
        Number of subscribers
        """
        if headers is None:
            headers = {}
        headers['min_compatible_version'] = min_compatible_version
        headers['max_compatible_version'] = max_compatible_version

        if peer is None:
            peer = 'pubsub'

        # For backward compatibility with old pubsub
        if self._send_via_rpc:
            return self.rpc().call(
                peer, 'pubsub.publish', topic=topic, headers=headers,
                message=message, 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='publish', peer=peer,
                              topic=topic, bus=bus,
                              headers=headers, message=message)
                self._save_parameters(result.ident, **kwargs)

            json_msg = jsonapi.dumps(dict(bus=bus, headers=headers, message=message))
            frames = [zmq.Frame(b'publish'), zmq.Frame(str(topic)), zmq.Frame(str(json_msg))]
            #<recipient, subsystem, args, msg_id, flags>
            self.vip_socket.send_vip(b'', 'pubsub', frames, result.ident, copy=False)
            return result
Ejemplo n.º 4
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))
Ejemplo n.º 5
0
    def publish_callback(self, peer, sender, bus, topic, headers, message):
        """
        Callback method registered with local message bus to receive PubSub messages
        subscribed by external platform agents. PubSub component of router will route the message to
        appropriate external platform subscribers.
        :return:
        """
        json_msg = jsonapi.dumps(
            dict(bus=bus, headers=headers, message=message))
        # Reformat the message into ZMQ VIP message frames
        frames = [
            sender, '', 'VIP', '', '', 'pubsub',
            zmq.Frame('publish'),
            zmq.Frame(str(topic)),
            zmq.Frame(str(json_msg))
        ]

        self.zmq_router.pubsub.handle_subsystem(frames, '')
Ejemplo n.º 6
0
 def pubsub_peer_publish(self, topic, headers, message=None, bus=''):
     peer = bytes(self.local.vip_message.peer)
     try:
         subscriptions = self._pubsub_peer_subscriptions[bus]
     except KeyError:
         return 0
     subscribers = set()
     for prefix, subscription in subscriptions.iteritems():
         if subscription and topic.startswith(prefix):
             subscribers |= subscription
     if subscribers:
         json_msg = jsonapi.dumps(jsonrpc.json_method(
             None, 'pubsub.push', [peer, bus, topic, headers, message], None))
         frames = [zmq.Frame(b'RPC'), zmq.Frame(json_msg)]
         socket = self.vip_socket
         for subscriber in subscribers:
             socket.send_vip(subscriber, 'RPC', flags=SNDMORE)
             socket.send_multipart(frames, copy=False)
     return len(subscribers)
Ejemplo n.º 7
0
    if __file__.endswith('.pyc') or __file__.endswith('.pyo'):
        from imp import load_compiled as load
    else:
        from imp import load_source as load
    green = load('.'.join([__name__, 'green']), __file__)
    import zmq
from zmq import NOBLOCK, SNDMORE, ZMQError, EINVAL, DEALER, ROUTER, RCVMORE

__all__ = ['ProtocolError', 'Message', 'Socket', 'BaseRouter']

_GREEN = zmq.__name__.endswith('.green')

PROTO = b'VIP1'

# Create these static frames for non-copy sends as an optimization
_PROTO = zmq.Frame(PROTO)
_ERROR = zmq.Frame(b'error')
_PONG = zmq.Frame(b'pong')
_VERSION = zmq.Frame(b'1.0')
_WELCOME = zmq.Frame(b'welcome')

# Error code to message mapping
ERRORS = {
    30: 'Peer unknown',
    31: 'Peer temporarily unavailable',
    40: 'Bad request',
    41: 'Unauthorized',
    50: 'Internal error',
    51: 'Not implemented',
}
Ejemplo n.º 8
0
    if __file__.endswith('.pyc') or __file__.endswith('.pyo'):
        from imp import load_compiled as load
    else:
        from imp import load_source as load
    green = load('.'.join([__name__, 'green']), __file__)  # pylint: disable=invalid-name
    import zmq
from zmq import NOBLOCK, SNDMORE, ZMQError, EINVAL, DEALER, ROUTER, RCVMORE

__all__ = ['ProtocolError', 'Message', 'Socket', 'BaseRouter']

_GREEN = zmq.__name__.endswith('.green')

PROTO = b'VIP1'

# Create these static frames for non-copy sends as an optimization
_PROTO = zmq.Frame(PROTO)
_ERROR = zmq.Frame(b'error')
_PONG = zmq.Frame(b'pong')
_VERSION = zmq.Frame(b'1.0')
_WELCOME = zmq.Frame(b'welcome')

# Again, optimizing by pre-creating frames
_ROUTE_ERRORS = {
    errnum: (zmq.Frame(str(errnum).encode('ascii')),
             zmq.Frame(os.strerror(errnum).encode('ascii')))
    for errnum in [zmq.EHOSTUNREACH, zmq.EAGAIN]
}
_INVALID_SUBSYSTEM = (zmq.Frame(str(zmq.EPROTONOSUPPORT).encode('ascii')),
                      zmq.Frame(
                          os.strerror(zmq.EPROTONOSUPPORT).encode('ascii')))