示例#1
0
    def handle_server_subscription(self, obj, client, clients):
        client.routing_id = obj.metadata['routing-id']
        client.extra_routing_ids = RoutingMiddleware.extra_routing_ids(obj)
        client.subscriptions = obj.metadata.get('subscriptions', ['*'])
        client.echo = False
        client.server = True
        client.subscribed = True

        self.subscribe_to_server(client)

        client.send(
            BusinessObject(
                {
                    'event': 'routing/subscribe/reply',
                    'routing-id': client.routing_id,
                    'in-reply-to': obj.id,
                    'role': 'server'
                }, None), None)

        notification = BusinessObject(
            {
                'event': 'routing/subscribe/notification',
                'routing-id': client.routing_id,
                'role': 'server'
            }, None)

        for c in clients:
            if c != client:
                c.send(notification, None)

        self.route(self.neighbor_announcement(clients), None, clients)
        logger.info(u"Server {0} subscribed!".format(client))
示例#2
0
    def handle_client_subscription(self, obj, client, clients):
        client.extra_routing_ids = RoutingMiddleware.extra_routing_ids(obj)
        client.subscriptions = obj.metadata.get('subscriptions', [])
        client.echo = False
        client.server = False
        client.subscribed = True

        notification = BusinessObject(
            {
                'event': 'routing/subscribe/notification',
                'routing-id': client.routing_id
            }, None)
        # Send a registration reply
        client.send(
            BusinessObject(
                {
                    'event': 'routing/subscribe/reply',
                    'routing-id': client.routing_id,
                    'in-reply-to': obj.id
                }, None), None)

        for c in clients:
            if c != client:
                c.send(notification, None)

        self.route(self.neighbor_announcement(clients), None, clients)
        logger.info(u"Client {0} subscribed!".format(client))
示例#3
0
    def test_clients_on_other_server_receive(self):
        client, routing_id = self.clients[0]
        to_client, to_routing_id = self.clients[2]

        obj = BusinessObject({'to': to_routing_id}, None)
        obj.serialize(socket=client)

        self.assert_receives_object(to_client, obj.id)
示例#4
0
    def test_clients_on_other_server_receive(self):
        client, routing_id = self.clients[0]
        to_client, to_routing_id = self.clients[2]

        obj = BusinessObject({'to': to_routing_id}, None)
        obj.serialize(socket=client)

        self.assert_receives_object(to_client, obj.id)
示例#5
0
 def test_answers_to_service_call(self):
     list_obj = BusinessObject({'event': 'services/request',
                                'name': 'clients',
                                'request': 'list'}, None)
     list_obj.serialize(socket=self.sock)
     logger.info(self.server)
     logger.info(self.service)
     reply, time = reply_for_object(list_obj, self.sock, select=select)
     self.assertIsNotNone(reply)
示例#6
0
    def test_server_doesnt_deliver_when_no_echo(self):
        client, routing_id = self.make_subscribe_client(no_echo=True)

        obj = BusinessObject({}, None)
        obj.serialize(socket=client)

        reply = read_object_with_timeout(client, timeout_secs=0.1, select=select)
        self.assertIsNone(reply)
        client.close()
示例#7
0
 def make_send_subscription(self):
     obj = BusinessObject(
         {
             'event': 'routing/subscribe',
             'receive-mode': 'all',
             'types': 'all'
         }, None)
     obj.serialize(socket=self.sock)
     return obj
示例#8
0
    def handle_legacy_subscription(self, obj, sender, clients):
        client = sender
        RoutedSystemClient.promote(client, obj=obj)

        if 'route' in obj.metadata and len(obj.metadata['route']) > 1:
            return obj

        if 'routing-ids' in obj.metadata:
            routing_ids = obj.metadata['routing-ids']
            if isinstance(routing_ids, basestring):
                logger.error(u"Got {0} as routing-ids from {1}".format(
                    routing_ids, client))
            else:
                for routing_id in routing_ids:
                    client.extra_routing_ids.append(routing_id)

        # receive-mode handling
        receive_mode = obj.metadata.get(
            'receive-mode', obj.metadata.get('receive_mode', 'none'))

        if receive_mode == "no_echo":
            client.echo = False
        else:
            client.echo = True

        client.subscriptions = []
        if receive_mode == "events_only":
            client.subscriptions = ['@*']
        else:
            client.subscriptions = ['*']

        client.legacy = True
        client.subscribed = True

        logger.info(u"Legacy client {0} subscribed!".format(client))

        if receive_mode != "none" and obj.metadata['types'] != "none":
            client.send(
                BusinessObject(
                    {
                        'event': 'routing/subscribe/reply',
                        'routing-id': client.routing_id,
                        'in-reply-to': obj.id
                    }, None), None)

        notification = BusinessObject(
            {
                'event': 'routing/subscribe/notification',
                'routing-id': client.routing_id
            }, None)

        for c in clients:
            if c != client:
                c.send(notification, None)

        return None
示例#9
0
    def test_server_doesnt_deliver_when_no_echo(self):
        client, routing_id = self.make_subscribe_client(no_echo=True)

        obj = BusinessObject({}, None)
        obj.serialize(socket=client)

        reply = read_object_with_timeout(client,
                                         timeout_secs=0.1,
                                         select=select)
        self.assertIsNone(reply)
        client.close()
示例#10
0
    def make_send_subscription(self, sock, no_echo=False):
        metadata = {'event': 'routing/subscribe',
                    'receive-mode': 'all',
                    'types': 'all'}

        if no_echo:
            metadata['receive-mode'] = 'no_echo'

        obj = BusinessObject(metadata, None)
        obj.serialize(socket=sock)
        return obj
示例#11
0
 def test_answers_to_service_call(self):
     list_obj = BusinessObject(
         {
             'event': 'services/request',
             'name': 'clients',
             'request': 'list'
         }, None)
     list_obj.serialize(socket=self.sock)
     logger.info(self.server)
     logger.info(self.service)
     reply, time = reply_for_object(list_obj, self.sock, select=select)
     self.assertIsNotNone(reply)
示例#12
0
    def make_send_subscription(self, sock, no_echo=False):
        metadata = {
            'event': 'routing/subscribe',
            'receive-mode': 'all',
            'types': 'all'
        }

        if no_echo:
            metadata['receive-mode'] = 'no_echo'

        obj = BusinessObject(metadata, None)
        obj.serialize(socket=sock)
        return obj
示例#13
0
    def test_correct_registration(self):
        obj = BusinessObject(
            {
                'event': 'services/request',
                'name': 'clients',
                'request': 'join',
                'client': str(uuid4()),
                'user': str(uuid4())
            }, None)
        obj.serialize(socket=self.sock)

        list_obj = BusinessObject(
            {
                'event': 'services/request',
                'name': 'clients',
                'request': 'list'
            }, None)
        list_obj.serialize(socket=self.sock)
        reply, time = reply_for_object(list_obj, self.sock, select=select)
        self.assertIsNotNone(reply, msg=u'No reply to service request')

        payload_text = reply.payload.decode('utf-8')
        payload = json.loads(payload_text)

        self.assertCorrectClientListReply(obj, payload)
示例#14
0
    def handle_legacy_registration(self, obj, sender, clients):
        client = sender
        RoutedSystemClient.promote(client, obj=obj)

        if 'route' in obj.metadata and len(obj.metadata['route']) > 1:
            return obj

        if 'routing-ids' in obj.metadata:
            routing_ids = obj.metadata['routing-ids']
            if isinstance(routing_ids, basestring):
                logger.error(u"Got {0} as routing-ids from {1}".format(
                    routing_ids, client))
            else:
                for routing_id in routing_ids:
                    client.extra_routing_ids.append(routing_id)

        client.receive_mode = obj.metadata.get('receive', 'all')
        client.types = obj.metadata.get('subscriptions', 'all')
        client.subscribed = True
        client.legacy = True

        logger.info(
            u"Legacy client {0} subscribed (registered)!".format(client))

        if client.receive_mode != "none" and client.types != "none":
            client.send(
                BusinessObject(
                    {
                        'event': 'clients/register/reply',
                        'routing-id': sender.routing_id
                    }, None), None)

        notification = BusinessObject(
            {
                'event': 'routing/subscribe/notification',
                'routing-id': client.routing_id
            }, None)
        for c in clients:
            if c != client:
                c.send(notification, None)

        return BusinessObject(
            {
                'event': 'services/request',
                'name': 'clients',
                'request': 'join',
                'client': obj.metadata.get('name', 'no-client'),
                'user': obj.metadata.get('user', 'no-user'),
                'route': obj.metadata.get('route', [])
            }, None)
示例#15
0
    def setUp(self):
        super(ClientRegistryTestCase, self).setUp()

        self.start_client_registry(_host, _port) # TODO: multiple inheritance
        logger.info('Started client registry, connecting to %s:%s', _host, _port)

        global _host, _port
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect((_host, _port))
        obj = BusinessObject({'event': 'routing/subscribe',
                              'receive-mode': 'all',
                              'types': 'all'}, None)
        obj.serialize(socket=self.sock)
        resp, time = reply_for_object(obj, self.sock, select=select)
        self.routing_id = resp.metadata['routing-id']
示例#16
0
    def _run(self):
        client = self.client
        logger.info(u"Receiver handling connection from {0}".format(
            client.address))

        last_activity = datetime.now()
        while True:
            if client.server and last_activity + timedelta(
                    minutes=30) < datetime.now():
                client.close('inactivity')
                return

            rlist, wlist, xlist = select([client.socket], [], [], timeout=30.0)

            if len(rlist) == 1:
                # logger.debug(u"Attempting to read an object from {0}".format(self.socket))
                try:
                    obj = BusinessObject.read_from_socket(client.socket)
                    if obj is None:
                        client.close("couldn't read object")
                        return
                    # logger.debug(u"Successfully read object {0}".format(str(obj)))
                    logger.debug(u"<< {0}: {1}".format(client, obj))
                    client.gateway.send(obj, client)
                    last_activity = datetime.now()
                except InvalidObject, ivo:
                    client.close(u"{0}".format(ivo))
                    return
                except socket.error, e:
                    client.close(u"{0}".format(e))
                    return
                except IOError, ioe:
                    client.close(u"{0}".format(e))
                    return
示例#17
0
def subscription_object(subscriptions=[], echo=False):
    metadata = {
        'event': 'routing/subscribe',
        'subscriptions': subscriptions,
        'echo': echo
    }
    return BusinessObject(metadata, None)
示例#18
0
def reply_for_object(obj, sock, timeout_secs=1.0, select=select):
    """
    Waits for a reply to a sent object (connected by in-reply-to field).

    Returns the object and seconds elapsed as tuple (obj, secs).

    select-module is parameterizable (if not given, Python standard one is used);
    useful for e.g. gevent select.
    """
    started = datetime.now()
    delta = timedelta(seconds=timeout_secs)
    while True:
        rlist, wlist, xlist = select.select([sock], [], [], 0.0001)

        if datetime.now() > started + delta:
            return None, timeout_secs

        if len(rlist) == 0:
            continue

        reply = BusinessObject.read_from_socket(sock)

        if reply is None:
            raise InvalidObject
        elif reply.metadata.get('in-reply-to', None) == obj.id:
            took = datetime.now() - started
            if hasattr(took, 'total_seconds'):
                return reply, took.total_seconds()
            else:
                return reply, _total_seconds(took)
示例#19
0
    def _run(self):
        client = self.client
        logger.info(u"Receiver handling connection from {0}".format(client.address))

        last_activity = datetime.now()
        while True:
            if client.server and last_activity + timedelta(minutes=30) < datetime.now():
                client.close('inactivity')
                return

            rlist, wlist, xlist = select([client.socket], [], [], timeout=30.0)

            if len(rlist) == 1:
                # logger.debug(u"Attempting to read an object from {0}".format(self.socket))
                try:
                    obj = BusinessObject.read_from_socket(client.socket)
                    if obj is None:
                        client.close("couldn't read object")
                        return
                    # logger.debug(u"Successfully read object {0}".format(str(obj)))
                    logger.debug(u"<< {0}: {1}".format(client, obj))
                    client.gateway.send(obj, client)
                    last_activity = datetime.now()
                except InvalidObject, ivo:
                    client.close(u"{0}".format(ivo))
                    return
                except socket.error, e:
                    client.close(u"{0}".format(e))
                    return
                except IOError, ioe:
                    client.close(u"{0}".format(e))
                    return
示例#20
0
def reply_for_object(obj, sock, timeout_secs=1.0, select=select):
    """
    Waits for a reply to a sent object (connected by in-reply-to field).

    Returns the object and seconds elapsed as tuple (obj, secs).

    select-module is parameterizable (if not given, Python standard one is used);
    useful for e.g. gevent select.
    """
    started = datetime.now()
    delta = timedelta(seconds=timeout_secs)
    while True:
        rlist, wlist, xlist = select.select([sock], [], [], 0.0001)

        if datetime.now() > started + delta:
            return None, timeout_secs

        if len(rlist) == 0:
            continue

        reply = BusinessObject.read_from_socket(sock)

        if reply is None:
            raise InvalidObject
        elif reply.metadata.get('in-reply-to', None) == obj.id:
            took = datetime.now() - started
            if hasattr(took, 'total_seconds'):
                return reply, took.total_seconds()
            else:
                return reply, _total_seconds(took)
示例#21
0
 def connect(self, client, clients):
     client.send(
         BusinessObject(
             {
                 'type': 'text/plain; charset=UTF-8',
                 'size': len(self.payload),
                 'sender': 'pyabboe'
             }, self.payload), None)
示例#22
0
    def test_server_delivers_to_specified_recipient(self):
        client, routing_id = self.clients[0]
        to_client, to_routing_id = self.clients[1]

        obj = BusinessObject({'to': to_routing_id}, None)
        obj.serialize(socket=client)

        self.assert_receives_object(to_client, obj.id)

        for client, routing_id in self.clients[2:]:
            reply = read_object_with_timeout(client, timeout_secs=0.1, select=select)
            if reply is not None:
                self.assertIsNotNone(reply.event)
            while reply is not None and reply.event is not None:
                reply = read_object_with_timeout(client, timeout_secs=0.1, select=select)

            self.assertIsNone(reply)
示例#23
0
def registration_object(client_name, user_name):
    metadata = {
        'event': 'services/request',
        'name': 'clients',
        'request': 'join',
        'client': client_name,
        'user': user_name
    }
    return BusinessObject(metadata, None)
示例#24
0
    def handle(self, obj):
        self.logger.debug(u"Request {0}".format(obj.metadata))

        try:
            if 'url' not in obj.metadata:
                metadata = {
                    'event':
                    'services/reply',
                    'in-reply-to':
                    obj.id,
                    'error':
                    "URL for head request not found in metadata (attribute 'url')"
                }
                if 'route' in obj.metadata:
                    metadata['to'] = obj.metadata['route'][0]
                reply = BusinessObject(metadata, None)
                self.logger.debug(u"Error reply {0}".format(reply.metadata))
                return reply

            payload = {}
            r = requests.head(obj.metadata['url'])
            for k, v in r.headers.iteritems():
                payload[k] = v
            payload['status_code'] = r.status_code

            metadata = {
                'event': 'services/reply',
                'in-reply-to': obj.id,
                'type': 'text/json; charset=utf-8'
            }
            if 'route' in obj.metadata:
                metadata['to'] = obj.metadata['route'][0]

            payload = bytearray(json.dumps(payload, ensure_ascii=False),
                                encoding='utf-8')
            metadata['size'] = len(payload)

            reply = BusinessObject(metadata, payload)
            self.logger.debug(u"Reply {0}".format(reply.metadata))
            return reply
        except Exception, e:
            traceback.print_exc()
            self.logger.error(u"{0}".format(e))
示例#25
0
def make_server_subscription(routing_id):
    metadata = {
        'event': 'routing/subscribe',
        'role': 'server',
        'routing-id': routing_id,
        'subscriptions': ['*'],
        'name': 'Objectoplex',
        'user': env.get('USER', 'unknown-user')
    }
    return BusinessObject(metadata, None)
示例#26
0
    def setUp(self):
        super(ClientRegistryTestCase, self).setUp()

        self.start_client_registry(_host, _port)  # TODO: multiple inheritance
        logger.info('Started client registry, connecting to %s:%s', _host,
                    _port)

        global _host, _port
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect((_host, _port))
        obj = BusinessObject(
            {
                'event': 'routing/subscribe',
                'receive-mode': 'all',
                'types': 'all'
            }, None)
        obj.serialize(socket=self.sock)
        resp, time = reply_for_object(obj, self.sock, select=select)
        self.routing_id = resp.metadata['routing-id']
示例#27
0
 def handle(self, obj, sender, *args, **kwargs):
     if obj.event == 'ping' and isinstance(sender, RoutedSystemClient) and \
        sender.subscribed:
         sender.send(
             BusinessObject(
                 {
                     'event': 'pong',
                     'routing-id': sender.routing_id,
                     'in-reply-to': obj.id
                 }, None), None)
     else:
         return obj
示例#28
0
    def neighbor_announcement(self, clients):
        logger.debug("Sending neighbor announcement")
        metadata = {
            'event': 'routing/announcement/neighbors',
            'node': self.routing_id,
            'neighbors': [{
                'routing-id': client.routing_id
            } for client in clients]
        }
        obj = BusinessObject(metadata, None)

        return obj
示例#29
0
    def test_server_delivers_to_specified_recipient(self):
        client, routing_id = self.clients[0]
        to_client, to_routing_id = self.clients[1]

        obj = BusinessObject({'to': to_routing_id}, None)
        obj.serialize(socket=client)

        self.assert_receives_object(to_client, obj.id)

        for client, routing_id in self.clients[2:]:
            reply = read_object_with_timeout(client,
                                             timeout_secs=0.1,
                                             select=select)
            if reply is not None:
                self.assertIsNotNone(reply.event)
            while reply is not None and reply.event is not None:
                reply = read_object_with_timeout(client,
                                                 timeout_secs=0.1,
                                                 select=select)

            self.assertIsNone(reply)
示例#30
0
    def disconnect(self, client, clients):
        assert (client.__class__ == RoutedSystemClient)

        if client.server:
            logger.info(u"Server {0} disconnected!".format(client))
        else:
            logger.info(u"Client {0} disconnected!".format(client))

        if client.subscribed:
            self.route(
                BusinessObject(
                    {
                        'event': 'routing/disconnect',
                        'routing-id': client.routing_id
                    }, None), None, clients)
示例#31
0
    def send_statistics(self, client, original_id):
        statistics = {
            'received objects': self.received_objects,
            'clients connected total': self.clients_connected_total,
            'clients disconnected total': self.clients_disconnected_total,
            'objects by type': self.objects_by_type,
            'events by type': self.events_by_type,
            'client count': self.client_count,
            'bytes in': self.bytes_in,
            'average send queue length': self.average_send_queue_length,
        }
        payload = bytearray(json.dumps(statistics, ensure_ascii=False),
                            encoding='utf-8')

        metadata = {
            'event': 'server/statistics/reply',
            'in-reply-to': original_id,
            'size': len(payload),
            'type': 'text/json'
        }

        client.send(BusinessObject(metadata, payload), None)
示例#32
0
    def test_correct_registration(self):
        obj = BusinessObject({'event': 'services/request',
                              'name': 'clients',
                              'request': 'join',
                              'client': str(uuid4()),
                              'user': str(uuid4())}, None)
        obj.serialize(socket=self.sock)

        list_obj = BusinessObject({'event': 'services/request',
                                   'name': 'clients',
                                   'request': 'list'}, None)
        list_obj.serialize(socket=self.sock)
        reply, time = reply_for_object(list_obj, self.sock, select=select)
        self.assertIsNotNone(reply, msg=u'No reply to service request')

        payload_text = reply.payload.decode('utf-8')
        payload = json.loads(payload_text)

        self.assertCorrectClientListReply(obj, payload)
示例#33
0
def read_object_with_timeout(sock, timeout_secs=1.0, select=select):
    rlist, wlist, xlist = select.select([sock], [], [], timeout_secs)

    if len(rlist) > 0:
        return BusinessObject.read_from_socket(sock)
示例#34
0
    def test_server_delivers_to_all(self):
        obj = BusinessObject({}, None)
        obj.serialize(socket=self.clients[0][0])

        for sock, routing_id in self.clients:
            self.assert_receives_object(sock, obj.id)
示例#35
0
    def test_server_delivers_to_all(self):
        obj = BusinessObject({}, None)
        obj.serialize(socket=self.clients[0][0])

        for sock, routing_id in self.clients:
            self.assert_receives_object(sock, obj.id)
示例#36
0
def read_object_with_timeout(sock, timeout_secs=1.0, select=select):
    rlist, wlist, xlist = select.select([sock], [], [], timeout_secs)

    if len(rlist) > 0:
        return BusinessObject.read_from_socket(sock)
示例#37
0
 def test_server_delivers_to_sender(self):
     obj = BusinessObject({}, None)
     obj.serialize(socket=self.clients[0][0])
     self.assert_receives_object(self.clients[0][0], obj.id)
示例#38
0
 def test_server_delivers_to_sender(self):
     obj = BusinessObject({}, None)
     obj.serialize(socket=self.clients[0][0])
     self.assert_receives_object(self.clients[0][0], obj.id)
示例#39
0
 def make_send_subscription(self):
     obj = BusinessObject({'event': 'routing/subscribe',
                           'receive-mode': 'all',
                           'types': 'all'}, None)
     obj.serialize(socket=self.sock)
     return obj