Exemple #1
0
    def test_send_message(self):
        '''Sending a message should place the message on the queue for the
        channel'''
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()
        redis = yield self.get_redis()
        channel = Channel(redis, config, properties, id='test-channel')
        yield channel.save()
        yield channel.start(self.service)
        resp = yield self.post('/channels/test-channel/messages/', {
            'to': '+1234',
            'content': 'foo',
            'from': None
        })
        yield self.assert_response(resp,
                                   http.OK,
                                   'message sent', {
                                       'to': '+1234',
                                       'channel_id': 'test-channel',
                                       'from': None,
                                       'reply_to': None,
                                       'channel_data': {},
                                       'content': 'foo',
                                   },
                                   ignore=['timestamp', 'message_id'])

        [message] = self.get_dispatched_messages('test-channel.outbound')
        message_id = (yield resp.json())['result']['message_id']
        self.assertEqual(message['message_id'], message_id)

        event_url = yield self.api.outbounds.load_event_url(
            'test-channel', message['message_id'])
        self.assertEqual(event_url, None)
Exemple #2
0
    def test_delete_channel(self):
        config = yield self.create_channel_config()
        properties = self.create_channel_properties()
        channel = Channel(self.redis, config, properties, 'test-channel')
        yield channel.save()
        yield channel.start(self.service)

        self.assertTrue('test-channel' in self.service.namedServices)
        properties = yield self.redis.get('test-channel:properties')
        self.assertNotEqual(properties, None)

        resp = yield self.delete('/channels/test-channel')
        yield self.assert_response(resp, http.OK, 'channel deleted', {})

        self.assertFalse('test-channel' in self.service.namedServices)
        properties = yield self.redis.get('test-channel:properties')
        self.assertEqual(properties, None)

        resp = yield self.delete('/channels/test-channel')
        yield self.assert_response(
            resp, http.NOT_FOUND, 'channel not found', {
                'errors': [{
                    'message': '',
                    'type': 'ChannelNotFound',
                }]
            })

        self.assertFalse('test-channel' in self.service.namedServices)
        properties = yield self.redis.get('test-channel:properties')
        self.assertEqual(properties, None)
Exemple #3
0
    def send_message(self, request, body, channel_id):
        '''Send an outbound (mobile terminated) message'''
        if 'to' not in body and 'reply_to' not in body:
            raise ApiUsageError(
                'Either "to" or "reply_to" must be specified')

        if 'to' in body and 'reply_to' in body:
            raise ApiUsageError(
                'Only one of "to" and "reply_to" may be specified')

        if 'from' in body and 'reply_to' in body:
            raise ApiUsageError(
                'Only one of "from" and "reply_to" may be specified')

        try:
            self.service.getServiceNamed(channel_id)
        except KeyError:
            raise ChannelNotFound()

        if 'to' in body:
            msg = yield Channel.send_message(
                channel_id, self.message_sender, self.outbounds, body)
        else:
            msg = yield Channel.send_reply_message(
                channel_id, self.message_sender, self.outbounds,
                self.inbounds, body)

        returnValue(response(request, 'message sent', msg))
Exemple #4
0
    def test_send_message_event_url(self):
        '''Sending a message with a specified event url should store the event
        url for sending events in the future'''
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()
        redis = yield self.get_redis()
        channel = Channel(redis, config, properties, 'test-channel')
        yield channel.save()
        yield channel.start(self.service)
        resp = yield self.post('/channels/test-channel/messages/', {
            'to': '+1234', 'content': 'foo', 'from': None,
            'event_url': 'http://test.org'})
        yield self.assert_response(
            resp, http.OK, 'message sent', {
                'to': '+1234',
                'channel_id': 'test-channel',
                'from': None,
                'reply_to': None,
                'channel_data': {},
                'content': 'foo',
            }, ignore=['timestamp', 'message_id'])

        event_url = yield self.api.outbounds.load_event_url(
            'test-channel', (yield resp.json())['result']['message_id'])
        self.assertEqual(event_url, 'http://test.org')
Exemple #5
0
    def test_send_message(self):
        '''Sending a message should place the message on the queue for the
        channel'''
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()
        redis = yield self.get_redis()
        channel = Channel(redis, config, properties, 'test-channel')
        yield channel.save()
        yield channel.start(self.service)
        resp = yield self.post('/channels/test-channel/messages/', {
            'to': '+1234', 'content': 'foo', 'from': None})
        yield self.assert_response(
            resp, http.OK, 'message sent', {
                'to': '+1234',
                'channel_id': 'test-channel',
                'from': None,
                'reply_to': None,
                'channel_data': {},
                'content': 'foo',
            }, ignore=['timestamp', 'message_id'])

        [message] = self.get_dispatched_messages('test-channel.outbound')
        message_id = (yield resp.json())['result']['message_id']
        self.assertEqual(message['message_id'], message_id)

        event_url = yield self.api.outbounds.load_event_url(
            'test-channel', message['message_id'])
        self.assertEqual(event_url, None)
Exemple #6
0
    def create_channel(
            self, service, redis, transport_class=None,
            properties=default_channel_properties, id=None, config=None,
            plugins=[]):
        '''Creates and starts, and saves a channel, with a
        TelnetServerTransport transport'''
        self.patch(junebug.logging_service, 'LogFile', DummyLogFile)
        if transport_class is None:
            transport_class = 'vumi.transports.telnet.TelnetServerTransport'

        properties = deepcopy(properties)
        logpath = self.mktemp()
        if config is None:
            config = yield self.create_channel_config(
                channels={
                    properties['type']: transport_class
                },
                logging_path=logpath)

        channel = Channel(
            redis, config, properties, id=id, plugins=plugins)
        yield channel.start(self.service)

        properties['config']['transport_name'] = channel.id

        yield channel.save()
        self.addCleanup(channel.stop)
        returnValue(channel)
Exemple #7
0
    def create_channel(self,
                       service,
                       redis,
                       transport_class=None,
                       properties=default_channel_properties,
                       id=None,
                       config=None,
                       plugins=[]):
        '''Creates and starts, and saves a channel, with a
        TelnetServerTransport transport'''
        self.patch(junebug.logging_service, 'LogFile', DummyLogFile)
        if transport_class is None:
            transport_class = 'vumi.transports.telnet.TelnetServerTransport'

        properties = deepcopy(properties)
        logpath = self.mktemp()
        if config is None:
            config = yield self.create_channel_config(
                channels={properties['type']: transport_class},
                logging_path=logpath)

        channel = Channel(redis, config, properties, id=id, plugins=plugins)
        yield channel.start(self.service)

        properties['config']['transport_name'] = channel.id

        yield channel.save()
        self.addCleanup(channel.stop)
        returnValue(channel)
Exemple #8
0
 def test_send_message_over_character_limit(self):
     '''If the content length is over the character limit, an error should
     be returned'''
     properties = self.create_channel_properties(character_limit=10)
     config = yield self.create_channel_config()
     redis = yield self.get_redis()
     channel = Channel(redis, config, properties, id='test-channel')
     yield channel.save()
     yield channel.start(self.service)
     resp = yield self.post('/channels/test-channel/messages/', {
         'to': '+1234',
         'content': 'Over the character limit.',
         'from': None
     })
     yield self.assert_response(
         resp, http.BAD_REQUEST, 'message too long', {
             'errors': [{
                 'message':
                 "Message content u'Over the character limit.' "
                 "is of length 25, which is greater than the character "
                 "limit of 10",
                 'type':
                 'MessageTooLong',
             }],
         })
Exemple #9
0
 def test_send_message_equal_character_limit(self):
     '''If the content length is equal to the character limit, no errors
     should be returned'''
     content = 'Equal to the character limit.'
     properties = self.create_channel_properties(
         character_limit=len(content))
     config = yield self.create_channel_config()
     redis = yield self.get_redis()
     channel = Channel(redis, config, properties, id='test-channel')
     yield channel.save()
     yield channel.start(self.service)
     resp = yield self.post('/channels/test-channel/messages/', {
         'to': '+1234',
         'content': content,
         'from': None
     })
     yield self.assert_response(resp,
                                http.OK,
                                'message sent', {
                                    'to': '+1234',
                                    'channel_id': 'test-channel',
                                    'from': None,
                                    'reply_to': None,
                                    'channel_data': {},
                                    'content': content,
                                },
                                ignore=['timestamp', 'message_id'])
Exemple #10
0
    def test_send_message_event_url(self):
        '''Sending a message with a specified event url should store the event
        url for sending events in the future'''
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()
        redis = yield self.get_redis()
        channel = Channel(redis, config, properties, id='test-channel')
        yield channel.save()
        yield channel.start(self.service)
        resp = yield self.post(
            '/channels/test-channel/messages/', {
                'to': '+1234',
                'content': 'foo',
                'from': None,
                'event_url': 'http://test.org'
            })
        yield self.assert_response(resp,
                                   http.OK,
                                   'message sent', {
                                       'to': '+1234',
                                       'channel_id': 'test-channel',
                                       'from': None,
                                       'reply_to': None,
                                       'channel_data': {},
                                       'content': 'foo',
                                   },
                                   ignore=['timestamp', 'message_id'])

        event_url = yield self.api.outbounds.load_event_url(
            'test-channel', (yield resp.json())['result']['message_id'])
        self.assertEqual(event_url, 'http://test.org')
Exemple #11
0
    def test_delete_channel(self):
        config = yield self.create_channel_config()
        properties = self.create_channel_properties()
        channel = Channel(self.redis, config, properties, id='test-channel')
        yield channel.save()
        yield channel.start(self.service)

        self.assertTrue('test-channel' in self.service.namedServices)
        properties = yield self.redis.get('test-channel:properties')
        self.assertNotEqual(properties, None)

        resp = yield self.delete('/channels/test-channel')
        yield self.assert_response(resp, http.OK, 'channel deleted', {})

        self.assertFalse('test-channel' in self.service.namedServices)
        properties = yield self.redis.get('test-channel:properties')
        self.assertEqual(properties, None)

        resp = yield self.delete('/channels/test-channel')
        yield self.assert_response(
            resp, http.NOT_FOUND, 'channel not found',
            {'errors': [{
                'message': '',
                'type': 'ChannelNotFound',
            }]})

        self.assertFalse('test-channel' in self.service.namedServices)
        properties = yield self.redis.get('test-channel:properties')
        self.assertEqual(properties, None)
Exemple #12
0
 def create_channel(self, request, body):
     '''Create a channel'''
     channel = Channel(
         self.redis, self.config, body)
     yield channel.save()
     yield channel.start(self.service)
     returnValue(response(
         request, 'channel created', (yield channel.status())))
Exemple #13
0
 def create_channel(self, request, body):
     '''Create a channel'''
     channel = Channel(
         self.redis, self.config, body, self.plugins)
     yield channel.start(self.service)
     yield channel.save()
     returnValue(response(
         request, 'channel created', (yield channel.status()),
         code=http.CREATED))
Exemple #14
0
    def create_channel(self, request, body):
        '''Create a channel'''
        if not (body.get('mo_url') or body.get('amqp_queue')):
            raise ApiUsageError(
                'One or both of "mo_url" and "amqp_queue" must be specified')

        channel = Channel(self.redis, self.config, body, self.plugins)
        yield channel.start(self.service)
        yield channel.save()
        returnValue(
            response(request, 'channel created', (yield channel.status())))
Exemple #15
0
    def test_get_all(self):
        channels = yield Channel.get_all(self.redis)
        self.assertEqual(channels, set())

        channel1 = yield self.create_channel(self.service, self.redis)
        channels = yield Channel.get_all(self.redis)
        self.assertEqual(channels, set([channel1.id]))

        channel2 = yield self.create_channel(self.service, self.redis)
        channels = yield Channel.get_all(self.redis)
        self.assertEqual(channels, set([channel1.id, channel2.id]))
Exemple #16
0
    def create_channel(self, request, body):
        '''Create a channel'''
        if not (body.get('mo_url') or body.get('amqp_queue')):
            raise ApiUsageError(
                'One or both of "mo_url" and "amqp_queue" must be specified')

        channel = Channel(
            self.redis, self.config, body, self.plugins)
        yield channel.save()
        yield channel.start(self.service)
        returnValue(response(
            request, 'channel created', (yield channel.status())))
    def test_get_all_channels(self):
        channels = yield Channel.get_all(self.redis)
        self.assertEqual(channels, set())

        channel1 = yield self.create_channel(
            self.service, self.redis, TelnetServerTransport)
        channels = yield Channel.get_all(self.redis)
        self.assertEqual(channels, set([channel1.id]))

        channel2 = yield self.create_channel(
            self.service, self.redis, TelnetServerTransport)
        channels = yield Channel.get_all(self.redis)
        self.assertEqual(channels, set([channel1.id, channel2.id]))
Exemple #18
0
 def create_channel(
         self, service, redis, transport_class,
         properties=default_channel_properties, id=None):
     '''Creates and starts, and saves a channel, with a
     TelnetServerTransport transport'''
     properties = deepcopy(properties)
     config = yield self.create_channel_config()
     channel = Channel(
         redis, config, properties, id=id)
     properties['config']['transport_name'] = channel.id
     yield channel.start(self.service)
     yield channel.save()
     self.addCleanup(channel.stop)
     returnValue(channel)
Exemple #19
0
    def test_get_channel(self):
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()
        redis = yield self.get_redis()
        channel = Channel(redis, config, properties, u'test-channel')
        yield channel.save()
        yield channel.start(self.service)
        resp = yield self.get('/channels/test-channel')

        yield self.assert_response(
            resp, http.OK, 'channel found', conjoin(properties, {
                'status': {},
                'id': 'test-channel',
            }))
Exemple #20
0
    def test_get_channel(self):
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()
        redis = yield self.get_redis()
        channel = Channel(redis, config, properties, id=u'test-channel')
        yield channel.save()
        yield channel.start(self.service)
        resp = yield self.get('/channels/test-channel')

        yield self.assert_response(
            resp, http.OK, 'channel found',
            conjoin(properties, {
                'status': self.generate_status(),
                'id': 'test-channel',
            }))
Exemple #21
0
    def test_restart_channel(self):
        config = yield self.create_channel_config()
        properties = self.create_channel_properties()
        channel = Channel(self.redis, config, properties, id='test-channel')
        yield channel.save()
        yield channel.start(self.service)

        actions = self.record_channel_methods('start', 'stop')

        resp = yield self.post('/channels/test-channel/restart', None)
        yield self.assert_response(resp, http.OK, 'channel restarted', {})

        self.assertEqual(actions, [
            ('stop', u'test-channel'),
            ('start', u'test-channel'),
        ])
Exemple #22
0
    def send_message(self, request, body, channel_id):
        '''Send an outbound (mobile terminated) message'''
        if 'to' not in body and 'reply_to' not in body:
            raise ApiUsageError(
                'Either "to" or "reply_to" must be specified')

        if 'to' in body and 'reply_to' in body:
            raise ApiUsageError(
                'Only one of "to" and "reply_to" may be specified')

        if 'from' in body and 'reply_to' in body:
            raise ApiUsageError(
                'Only one of "from" and "reply_to" may be specified')

        channel = yield Channel.from_id(
            self.redis, self.config, channel_id, self.service, self.plugins)

        if 'to' in body:
            msg = yield channel.send_message(
                self.message_sender, self.outbounds, body)
        else:
            msg = yield channel.send_reply_message(
                self.message_sender, self.outbounds, self.inbounds, body)

        yield self.message_rate.increment(
            channel_id, 'outbound', self.config.metric_window)

        returnValue(response(request, 'message sent', msg))
Exemple #23
0
 def test_transport_class_name_specified(self):
     config = yield self.create_channel_config(channels={'foo': 'bar.baz'})
     properties = self.create_channel_properties(type='foo')
     channel = Channel(self.redis, config, properties)
     self.assertEqual(
         channel._transport_cls_name,
         'bar.baz')
Exemple #24
0
 def test_transport_class_name_default(self):
     config = yield self.create_channel_config(channels={})
     properties = self.create_channel_properties(type='telnet')
     channel = Channel(self.redis, config, properties)
     self.assertEqual(
         channel._transport_cls_name,
         'vumi.transports.telnet.TelnetServerTransport')
Exemple #25
0
    def validate_router_config(cls, api, config):
        try:
            config = FromAddressRouterConfig(config)
        except ConfigError as e:
            raise InvalidRouterConfig(e.message)

        channel_id = str(config.channel)
        try:
            channel = yield Channel.from_id(
                api.redis, api.config, channel_id, api.service, api.plugins)
        except ChannelNotFound:
            raise InvalidRouterConfig(
                "Channel {} does not exist".format(channel_id))
        if channel.has_destination:
            raise InvalidRouterConfig(
                "Channel {} already has a destination specified".format(
                    channel_id))

        # Check that no other routers are listening to this channel
        def check_router_channel(router):
            channel = router.get('config', {}).get('channel', None)
            if channel == channel_id:
                raise InvalidRouterConfig(
                    "Router {} is already routing channel {}".format(
                        router['id'], channel_id))

        routers = yield api.router_store.get_router_list()
        routers = yield gatherResults([
            api.router_store.get_router_config(r) for r in routers])
        for router in routers:
            check_router_channel(router)
Exemple #26
0
    def setup(self, redis=None, message_sender=None):
        if redis is None:
            redis = yield TxRedisManager.from_config(self.redis_config)

        if message_sender is None:
            message_sender = MessageSender(
                'amqp-spec-0-8.xml', self.amqp_config)

        self.redis = redis
        self.message_sender = message_sender
        self.message_sender.setServiceParent(self.service)

        self.inbounds = InboundMessageStore(
            self.redis, self.config.inbound_message_ttl)

        self.outbounds = OutboundMessageStore(
            self.redis, self.config.outbound_message_ttl)

        self.message_rate = MessageRateStore(self.redis)

        self.plugins = []
        for plugin_config in self.config.plugins:
            cls = load_class_by_string(plugin_config['type'])
            plugin = cls()
            yield plugin.start_plugin(plugin_config, self.config)
            self.plugins.append(plugin)

        yield Channel.start_all_channels(
            self.redis, self.config, self.service, self.plugins)
Exemple #27
0
 def delete_channel(self, request, channel_id):
     '''Delete the channel'''
     channel = yield Channel.from_id(self.redis, self.config, channel_id,
                                     self.service, self.plugins)
     yield channel.stop()
     yield channel.delete()
     returnValue(response(request, 'channel deleted', {}))
Exemple #28
0
    def send_message(self, request, body, channel_id):
        '''Send an outbound (mobile terminated) message'''
        if 'to' not in body and 'reply_to' not in body:
            raise ApiUsageError('Either "to" or "reply_to" must be specified')

        if 'to' in body and 'reply_to' in body:
            raise ApiUsageError(
                'Only one of "to" and "reply_to" may be specified')

        if 'from' in body and 'reply_to' in body:
            raise ApiUsageError(
                'Only one of "from" and "reply_to" may be specified')

        channel = yield Channel.from_id(self.redis, self.config, channel_id,
                                        self.service, self.plugins)

        if 'to' in body:
            msg = yield channel.send_message(self.message_sender,
                                             self.outbounds, body)
        else:
            msg = yield channel.send_reply_message(self.message_sender,
                                                   self.outbounds,
                                                   self.inbounds, body)

        yield self.message_rate.increment(channel_id, 'outbound',
                                          self.config.metric_window)

        returnValue(response(request, 'message sent', msg))
Exemple #29
0
    def setup(self, redis=None, message_sender=None):
        if redis is None:
            redis = yield TxRedisManager.from_config(self.redis_config)

        if message_sender is None:
            message_sender = MessageSender('amqp-spec-0-8.xml',
                                           self.amqp_config)

        self.redis = redis
        self.message_sender = message_sender
        self.message_sender.setServiceParent(self.service)

        self.inbounds = InboundMessageStore(self.redis,
                                            self.config.inbound_message_ttl)

        self.outbounds = OutboundMessageStore(self.redis,
                                              self.config.outbound_message_ttl)

        self.message_rate = MessageRateStore(self.redis)

        self.plugins = []
        for plugin_config in self.config.plugins:
            cls = load_class_by_string(plugin_config['type'])
            plugin = cls()
            yield plugin.start_plugin(plugin_config, self.config)
            self.plugins.append(plugin)

        yield Channel.start_all_channels(self.redis, self.config, self.service,
                                         self.plugins)
Exemple #30
0
    def test_send_message_message_rate(self):
        '''Sending a message should increment the message rate counter'''
        clock = yield self.patch_message_rate_clock()
        channel = Channel(
            (yield self.get_redis()), (yield self.create_channel_config()),
            self.create_channel_properties(), id='test-channel')
        yield channel.save()
        yield channel.start(self.service)

        yield self.post('/channels/test-channel/messages/', {
            'to': '+1234', 'content': 'foo', 'from': None})
        clock.advance(channel.config.metric_window)

        rate = yield self.api.message_rate.get_messages_per_second(
            'test-channel', 'outbound', channel.config.metric_window)
        self.assertEqual(rate, 1.0 / channel.config.metric_window)
    def test_send_reply_message_event_url(self):
        '''Sending a message with a specified event url should store the event
        url for sending events in the future'''
        yield self.create_channel(
            self.service, self.redis, TelnetServerTransport, id='channel-id')

        in_msg = TransportUserMessage(
            from_addr='+2789',
            to_addr='+1234',
            transport_name='channel-id',
            transport_type='_',
            transport_metadata={'foo': 'bar'})

        yield self.api.inbounds.store_vumi_message('channel-id', in_msg)

        msg = yield Channel.send_reply_message(
            'channel-id', self.message_sender, self.outbounds, self.inbounds, {
                'reply_to': in_msg['message_id'],
                'content': 'testcontent',
                'event_url': 'http://test.org',
            })

        event_url = yield self.outbounds.load_event_url(
            'channel-id', msg['message_id'])

        self.assertEqual(event_url, 'http://test.org')
Exemple #32
0
 def modify_channel(self, request, body, channel_id):
     '''Mondify the channel configuration'''
     channel = yield Channel.from_id(
         self.redis, self.config, channel_id, self.service, self.plugins)
     resp = yield channel.update(body)
     returnValue(response(
         request, 'channel updated', resp))
Exemple #33
0
 def restart_channel(self, request, channel_id):
     '''Restart a channel.'''
     channel = yield Channel.from_id(
         self.redis, self.config, channel_id, self.service, self.plugins)
     yield channel.stop()
     yield channel.start(self.service)
     returnValue(response(request, 'channel restarted', {}))
Exemple #34
0
 def get_channel(self, request, channel_id):
     '''Return the channel configuration and a nested status object'''
     channel = yield Channel.from_id(
         self.redis, self.config, channel_id, self.service)
     resp = yield channel.status()
     returnValue(response(
         request, 'channel found', resp))
Exemple #35
0
 def get_channel(self, request, channel_id):
     '''Return the channel configuration and a nested status object'''
     channel = yield Channel.from_id(
         self.redis, self.config, channel_id, self.service, self.plugins)
     resp = yield channel.status()
     returnValue(response(
         request, 'channel found', resp))
Exemple #36
0
 def modify_channel(self, request, body, channel_id):
     '''Mondify the channel configuration'''
     channel = yield Channel.from_id(
         self.redis, self.config, channel_id, self.service)
     resp = yield channel.update(body)
     returnValue(response(
         request, 'channel updated', resp))
    def test_send_reply_message(self):
        '''send_reply_message should place the correct reply message on the
        correct queue'''
        yield self.create_channel(
            self.service, self.redis, TelnetServerTransport, id='channel-id')

        in_msg = TransportUserMessage(
            from_addr='+2789',
            to_addr='+1234',
            transport_name='channel-id',
            transport_type='_',
            transport_metadata={'foo': 'bar'})

        yield self.api.inbounds.store_vumi_message('channel-id', in_msg)

        msg = yield Channel.send_reply_message(
            'channel-id', self.message_sender, self.outbounds, self.inbounds, {
                'reply_to': in_msg['message_id'],
                'content': 'testcontent',
            })

        expected = in_msg.reply(content='testcontent')
        expected = conjoin(api_from_message(expected), {
            'timestamp': msg['timestamp'],
            'message_id': msg['message_id']
        })

        self.assertEqual(msg, expected)

        [dispatched] = self.get_dispatched_messages('channel-id.outbound')
        self.assertEqual(msg['message_id'], dispatched['message_id'])
        self.assertEqual(api_from_message(dispatched), expected)
Exemple #38
0
    def test_start_all_channels(self):
        yield Channel.start_all_channels(self.redis, self.config, self.service)

        channel1 = yield self.create_channel(self.service, self.redis)
        self.assertTrue(channel1.id in self.service.namedServices)
        yield channel1.stop()
        self.assertFalse(channel1.id in self.service.namedServices)
        yield Channel.start_all_channels(self.redis, self.config, self.service)
        self.assertTrue(channel1.id in self.service.namedServices)

        channel2 = yield self.create_channel(self.service, self.redis)
        self.assertTrue(channel2.id in self.service.namedServices)
        yield channel2.stop()
        self.assertFalse(channel2.id in self.service.namedServices)
        yield Channel.start_all_channels(self.redis, self.config, self.service)
        self.assertTrue(channel1.id in self.service.namedServices)
        self.assertTrue(channel2.id in self.service.namedServices)
Exemple #39
0
 def delete_channel(self, request, channel_id):
     '''Delete the channel'''
     channel = yield Channel.from_id(
         self.redis, self.config, channel_id, self.service)
     yield channel.stop()
     yield channel.delete()
     returnValue(response(
         request, 'channel deleted', {}))
Exemple #40
0
    def test_modify_channel_config_change(self):
        redis = yield self.get_redis()
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()

        channel = Channel(redis, config, properties, 'test-channel')
        yield channel.save()
        yield channel.start(self.service)

        properties['config']['name'] = 'bar'
        resp = yield self.post('/channels/test-channel', properties)

        yield self.assert_response(
            resp, http.OK, 'channel updated', conjoin(properties, {
                'status': {},
                'id': 'test-channel',
            }))
Exemple #41
0
 def test_transport_class_name_overridden(self):
     config = yield self.create_channel_config(channels={'foo': 'bar.baz'},
                                               replace_channels=True)
     properties = self.create_channel_properties(type='telnet')
     channel = Channel(self.redis, config, properties)
     err = self.assertRaises(InvalidChannelType, getattr, channel,
                             '_transport_cls_name')
     self.assertTrue(all(cls in err.message for cls in ['telnet', 'foo']))
Exemple #42
0
    def test_modify_channel_config_change(self):
        redis = yield self.get_redis()
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()

        channel = Channel(redis, config, properties, id='test-channel')
        yield channel.save()
        yield channel.start(self.service)

        properties['config']['name'] = 'bar'
        resp = yield self.post('/channels/test-channel', properties)

        yield self.assert_response(
            resp, http.OK, 'channel updated',
            conjoin(properties, {
                'status': self.generate_status(),
                'id': 'test-channel',
            }))
Exemple #43
0
    def test_modify_channel_no_config_change(self):
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()
        redis = yield self.get_redis()

        channel = Channel(redis, config, properties, 'test-channel')
        yield channel.save()
        yield channel.start(self.service)

        resp = yield self.post(
            '/channels/test-channel', {'metadata': {'foo': 'bar'}})

        yield self.assert_response(
            resp, http.OK, 'channel updated', conjoin(properties, {
                'status': {},
                'id': 'test-channel',
                'metadata': {'foo': 'bar'},
            }))
Exemple #44
0
 def get_logs(self, request, channel_id):
     '''Get the last N logs for a channel, sorted reverse
     chronologically.'''
     n = request.args.get('n', None)
     if n is not None:
         n = int(n[0])
     channel = yield Channel.from_id(
         self.redis, self.config, channel_id, self.service, self.plugins)
     logs = yield channel.get_logs(n)
     returnValue(response(request, 'logs retrieved', logs))
Exemple #45
0
    def test_send_message_message_rate(self):
        '''Sending a message should increment the message rate counter'''
        clock = yield self.patch_message_rate_clock()
        channel = Channel((yield self.get_redis()),
                          (yield self.create_channel_config()),
                          self.create_channel_properties(),
                          id='test-channel')
        yield channel.save()
        yield channel.start(self.service)

        yield self.post('/channels/test-channel/messages/', {
            'to': '+1234',
            'content': 'foo',
            'from': None
        })
        clock.advance(channel.config.metric_window)

        rate = yield self.api.message_rate.get_messages_per_second(
            'test-channel', 'outbound', channel.config.metric_window)
        self.assertEqual(rate, 1.0 / channel.config.metric_window)
    def test_send_reply_message_inbound_not_found(self):
        '''send_reply_message should raise an error if the inbound message is
        not found'''
        yield self.create_channel(
            self.service, self.redis, TelnetServerTransport, id='channel-id')

        self.assertFailure(Channel.send_reply_message(
            'channel-id', self.message_sender, self.outbounds, self.inbounds, {
                'reply_to': 'i-do-not-exist',
                'content': 'testcontent',
            }), MessageNotFound)
Exemple #47
0
 def test_send_message_under_character_limit(self):
     '''If the content length is under the character limit, no errors should
     be returned'''
     properties = self.create_channel_properties(character_limit=100)
     config = yield self.create_channel_config()
     redis = yield self.get_redis()
     channel = Channel(redis, config, properties, id='test-channel')
     yield channel.save()
     yield channel.start(self.service)
     resp = yield self.post('/channels/test-channel/messages/', {
         'to': '+1234', 'content': 'Under the character limit.',
         'from': None})
     yield self.assert_response(
         resp, http.OK, 'message sent', {
             'to': '+1234',
             'channel_id': 'test-channel',
             'from': None,
             'reply_to': None,
             'channel_data': {},
             'content': 'Under the character limit.',
         }, ignore=['timestamp', 'message_id'])
Exemple #48
0
    def health_status(self, request):
        if self.config.rabbitmq_management_interface:

            def get_queues(channel_ids):

                gets = []

                for channel_id in channel_ids:
                    for sub in ['inbound', 'outbound', 'event']:
                        queue_name = "%s.%s" % (channel_id, sub)

                        get = self.rabbitmq_management_client.get_queue(
                            self.amqp_config['vhost'], queue_name)
                        gets.append(get)

                return gets

            def return_queue_results(results):
                queues = []
                stuck = False

                for result in results:
                    queue = result[1]

                    if ('messages' in queue):
                        details = {
                            'name': queue['name'],
                            'stuck': False,
                            'messages': queue.get('messages'),
                            'rate': queue['messages_details']['rate']
                        }
                        if (details['messages'] > 0 and details['rate'] == 0):
                            stuck = True
                            details['stuck'] = True

                        queues.append(details)

                status = 'queues ok'
                code = http.OK
                if stuck:
                    status = "queues stuck"
                    code = http.INTERNAL_SERVER_ERROR

                return response(request, status, queues, code=code)

            d = Channel.get_all(self.redis)
            d.addCallback(get_queues)
            d.addCallback(defer.DeferredList)
            d.addCallback(return_queue_results)
            return d
        else:
            return response(request, 'health ok', {})
Exemple #49
0
 def test_send_message_over_character_limit(self):
     '''If the content length is over the character limit, an error should
     be returned'''
     properties = self.create_channel_properties(character_limit=10)
     config = yield self.create_channel_config()
     redis = yield self.get_redis()
     channel = Channel(redis, config, properties, id='test-channel')
     yield channel.save()
     yield channel.start(self.service)
     resp = yield self.post('/channels/test-channel/messages/', {
         'to': '+1234', 'content': 'Over the character limit.',
         'from': None})
     yield self.assert_response(
         resp, http.BAD_REQUEST, 'message too long', {
             'errors': [{
                 'message':
                     "Message content u'Over the character limit.' "
                     "is of length 25, which is greater than the character "
                     "limit of 10",
                 'type': 'MessageTooLong',
             }],
         })
Exemple #50
0
    def test_get_channel_list(self):
        redis = yield self.get_redis()
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()

        resp = yield self.get('/channels/')
        yield self.assert_response(resp, http.OK, 'channels listed', [])

        yield Channel(redis, config, properties, id=u'test-channel-1').save()

        resp = yield self.get('/channels/')
        yield self.assert_response(resp, http.OK, 'channels listed', [
            u'test-channel-1',
        ])

        yield Channel(redis, config, properties, id=u'test-channel-2').save()

        resp = yield self.get('/channels/')
        yield self.assert_response(resp, http.OK, 'channels listed', [
            u'test-channel-1',
            u'test-channel-2',
        ])
Exemple #51
0
    def test_start_all_channels(self):
        yield Channel.start_all_channels(
            self.redis, self.config, self.service)

        channel1 = yield self.create_channel(
            self.service, self.redis)
        self.assertTrue(channel1.id in self.service.namedServices)
        yield channel1.stop()
        self.assertFalse(channel1.id in self.service.namedServices)
        yield Channel.start_all_channels(
            self.redis, self.config, self.service)
        self.assertTrue(channel1.id in self.service.namedServices)

        channel2 = yield self.create_channel(
            self.service, self.redis)
        self.assertTrue(channel2.id in self.service.namedServices)
        yield channel2.stop()
        self.assertFalse(channel2.id in self.service.namedServices)
        yield Channel.start_all_channels(
            self.redis, self.config, self.service)
        self.assertTrue(channel1.id in self.service.namedServices)
        self.assertTrue(channel2.id in self.service.namedServices)
Exemple #52
0
    def test_send_message_reply(self):
        '''Sending a reply message should fetch the relevant inbound message,
        use it to construct a reply message, and place the reply message on the
        queue for the channel'''
        channel = Channel(
            redis_manager=(yield self.get_redis()),
            config=(yield self.create_channel_config()),
            properties=self.create_channel_properties(),
            id='test-channel')

        yield channel.save()
        yield channel.start(self.service)

        in_msg = TransportUserMessage(
            from_addr='+2789',
            to_addr='+1234',
            transport_name='test-channel',
            transport_type='_',
            transport_metadata={'foo': 'bar'})

        yield self.api.inbounds.store_vumi_message('test-channel', in_msg)
        expected = in_msg.reply(content='testcontent')
        expected = api_from_message(expected)

        resp = yield self.post('/channels/test-channel/messages/', {
            'reply_to': in_msg['message_id'],
            'content': 'testcontent',
        })

        yield self.assert_response(
            resp, http.OK,
            'message sent',
            omit(expected, 'timestamp', 'message_id'),
            ignore=['timestamp', 'message_id'])

        [message] = self.get_dispatched_messages('test-channel.outbound')
        message_id = (yield resp.json())['result']['message_id']
        self.assertEqual(message['message_id'], message_id)
Exemple #53
0
    def test_send_message_reply(self):
        '''Sending a reply message should fetch the relevant inbound message,
        use it to construct a reply message, and place the reply message on the
        queue for the channel'''
        channel = Channel(redis_manager=(yield self.get_redis()),
                          config=(yield self.create_channel_config()),
                          properties=self.create_channel_properties(),
                          id='test-channel')

        yield channel.save()
        yield channel.start(self.service)

        in_msg = TransportUserMessage(from_addr='+2789',
                                      to_addr='+1234',
                                      transport_name='test-channel',
                                      transport_type='_',
                                      transport_metadata={'foo': 'bar'})

        yield self.api.inbounds.store_vumi_message('test-channel', in_msg)
        expected = in_msg.reply(content='testcontent')
        expected = api_from_message(expected)

        resp = yield self.post('/channels/test-channel/messages/', {
            'reply_to': in_msg['message_id'],
            'content': 'testcontent',
        })

        yield self.assert_response(resp,
                                   http.OK,
                                   'message sent',
                                   omit(expected, 'timestamp', 'message_id'),
                                   ignore=['timestamp', 'message_id'])

        [message] = self.get_dispatched_messages('test-channel.outbound')
        message_id = (yield resp.json())['result']['message_id']
        self.assertEqual(message['message_id'], message_id)
Exemple #54
0
    def test_modify_channel_no_config_change(self):
        properties = self.create_channel_properties()
        config = yield self.create_channel_config()
        redis = yield self.get_redis()

        channel = Channel(redis, config, properties, id='test-channel')
        yield channel.save()
        yield channel.start(self.service)

        resp = yield self.post('/channels/test-channel',
                               {'metadata': {
                                   'foo': 'bar'
                               }})

        yield self.assert_response(
            resp, http.OK, 'channel updated',
            conjoin(
                properties, {
                    'status': self.generate_status(),
                    'id': 'test-channel',
                    'metadata': {
                        'foo': 'bar'
                    },
                }))
Exemple #55
0
    def test_plugin_channel_stopped(self):
        '''Stores the name of the function call and arguments in calls'''
        plugin = FakeJunebugPlugin()
        config = yield self.create_channel_config()
        yield plugin.start_plugin({'test': 'plugin_config'}, config)
        plugin.calls = []

        redis = yield self.get_redis()
        channel = Channel(redis, config,
                          deepcopy(self.default_channel_properties))
        yield plugin.channel_stopped(channel)

        [(name, [channel_arg])] = plugin.calls
        self.assertEqual(name, 'channel_stopped')
        self.assertEqual(channel_arg, channel)
Exemple #56
0
    def send_message(self, request, body, channel_id):
        '''Send an outbound (mobile terminated) message'''
        if 'to' not in body and 'reply_to' not in body:
            raise ApiUsageError(
                'Either "to" or "reply_to" must be specified')

        channel = yield Channel.from_id(
            self.redis, self.config, channel_id, self.service, self.plugins)

        if 'reply_to' in body:
            msg = yield channel.send_reply_message(
                self.message_sender, self.outbounds, self.inbounds, body,
                allow_expired_replies=self.config.allow_expired_replies)
        else:
            msg = yield channel.send_message(
                self.message_sender, self.outbounds, body)

        yield self.message_rate.increment(
            channel_id, 'outbound', self.config.metric_window)

        returnValue(response(
            request, 'message submitted', msg, code=http.CREATED))