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)
def test_send_reply_message(self): '''send_reply_message should place the correct reply message on the correct queue''' channel = yield self.create_channel(self.service, self.redis, 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( 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)
def test_store_message(self): '''Stores the message under the correct key''' store = yield self.create_store() msg = TransportUserMessage.send(to_addr='+213', content='foo') yield store.store_message('channel_id', api_from_message(msg)) msg_json = yield self.redis.hget( 'channel_id:outbound_messages:{}'.format(msg['message_id']), 'message') self.assertEqual(msg_json, to_json(api_from_message(msg)))
def consume_user_message(self, message): '''Sends the vumi message as an HTTP request to the configured URL''' yield self.inbounds.store_vumi_message(self.channel_id, message) msg = api_from_message(message) if self.config.get('mo_message_url') is not None: config = self.get_static_config() (url, auth) = self._split_url_and_credentials( config.mo_message_url) # Construct token auth headers if configured auth_token = config.mo_message_url_auth_token if auth_token: headers = { 'Authorization': [ 'Token %s' % (auth_token,)] } else: headers = {} resp = yield post(url, msg, timeout=config.mo_message_url_timeout, auth=auth, headers=headers) if resp and request_failed(resp): logging.exception( 'Error sending message, received HTTP code %r with body %r' '. Message: %r' % (resp.code, (yield resp.content()), msg)) if self.config.get('message_queue') is not None: yield self.ro_connector.publish_inbound(message) yield self._increment_metric('inbound')
def consume_user_message(self, message): '''Sends the vumi message as an HTTP request to the configured URL''' yield self.inbounds.store_vumi_message(self.channel_id, message) msg = api_from_message(message) if self.config.get('mo_message_url') is not None: config = self.get_static_config() (url, auth) = self._split_url_and_credentials(config.mo_message_url) # Construct token auth headers if configured auth_token = config.mo_message_url_auth_token if auth_token: headers = {'Authorization': ['Token %s' % (auth_token, )]} else: headers = {} resp = yield post(url, msg, timeout=config.mo_message_url_timeout, auth=auth, headers=headers) if resp and request_failed(resp): logging.exception( 'Error sending message, received HTTP code %r with body %r' '. Message: %r' % (resp.code, (yield resp.content()), msg)) if self.config.get('message_queue') is not None: yield self.ro_connector.publish_inbound(message) yield self._increment_metric('inbound')
def send_message(self, sender, outbounds, msg): '''Sends a message.''' event_url = msg.get('event_url') msg = message_from_api(self.id, msg) msg = TransportUserMessage.send(**msg) msg = yield self._send_message(sender, outbounds, event_url, msg) returnValue(api_from_message(msg))
def handle_outbound_message(self, destinationid, message): config = self.get_static_config() channel_id = str(config.channel) d1 = self.outbounds.store_message( channel_id, api_from_message(message)) d2 = self.send_outbound_to_channel(channel_id, message) return gatherResults([d1, d2])
def _send_message(self, sender, outbounds, msg, msg_api): self._check_character_limit(msg['content']) msg_api.update(api_from_message(msg)) yield outbounds.store_message(self.id, msg_api) queue = self.OUTBOUND_QUEUE % (self.id, ) msg = yield sender.send_message(msg, routing_key=queue) returnValue(msg)
def _send_message(self, sender, outbounds, msg, msg_api): self._check_character_limit(msg['content']) msg_api.update(api_from_message(msg)) yield outbounds.store_message(self.id, msg_api) queue = self.OUTBOUND_QUEUE % (self.id,) msg = yield sender.send_message(msg, routing_key=queue) returnValue(msg)
def test_outbound_message_routing(self): """ Outbound messages should be routed to the configured channel, no matter which destination they came from. They should also be stored so that events can be routed correctly. """ worker = yield self.get_router_worker({ 'destinations': [{ 'id': "test-destination1", 'amqp_queue': "testqueue1", 'config': { 'regular_expression': '^1.*$' }, }, { 'id': "test-destination2", 'amqp_queue': "testqueue2", 'config': { 'regular_expression': '^2.*$' }, }], 'channel': '41e58f4a-2acc-442f-b3e5-3cf2b2f1cf14', }) outbound = self.messagehelper.make_outbound('test message') yield self.workerhelper.dispatch_outbound(outbound, 'testqueue1') [message] = yield self.workerhelper.wait_for_dispatched_outbound( connector_name='41e58f4a-2acc-442f-b3e5-3cf2b2f1cf14') self.assertEqual(outbound, message) stored_message = yield worker.outbounds.load_message( '41e58f4a-2acc-442f-b3e5-3cf2b2f1cf14', outbound['message_id']) self.assertEqual(api_from_message(outbound), stored_message) yield self.workerhelper.clear_dispatched_outbound( connector_name='41e58f4a-2acc-442f-b3e5-3cf2b2f1cf14') outbound = self.messagehelper.make_outbound('test message') yield self.workerhelper.dispatch_outbound(outbound, 'testqueue2') [message] = yield self.workerhelper.wait_for_dispatched_outbound( connector_name='41e58f4a-2acc-442f-b3e5-3cf2b2f1cf14') self.assertEqual(outbound, message) stored_message = yield worker.outbounds.load_message( '41e58f4a-2acc-442f-b3e5-3cf2b2f1cf14', outbound['message_id']) self.assertEqual(api_from_message(outbound), stored_message)
def consume_user_message(self, message): '''Sends the vumi message as an HTTP request to the configured URL''' yield self.inbounds.store_vumi_message(self.channel_id, message) msg = api_from_message(message) resp = yield post(self.config['mo_message_url'], msg) if request_failed(resp): logging.exception( 'Error sending message, received HTTP code %r with body %r. ' 'Message: %r' % (resp.code, (yield resp.content()), msg))
def test_load_event_auth_token(self): '''Returns the event auth token under the message ID''' store = yield self.create_store() vumi_msg = TransportUserMessage.send(to_addr='+213', content='foo') msg = {'event_auth_token': 'the-auth-token'} msg.update(api_from_message(vumi_msg)) yield store.store_message('channel_id', msg) event_auth_token = yield store.load_event_auth_token( 'channel_id', vumi_msg.get('message_id')) self.assertEqual(event_auth_token, "the-auth-token")
def test_load_event_url(self): '''Returns a vumi message from the stored json''' store = yield self.create_store() vumi_msg = TransportUserMessage.send(to_addr='+213', content='foo') msg = {'event_url': "http://test.org"} msg.update(api_from_message(vumi_msg)) yield store.store_message('channel_id', msg) event_url = yield store.load_event_url( 'channel_id', vumi_msg.get('message_id')) self.assertEqual(event_url, 'http://test.org')
def send_reply_message(self, sender, outbounds, inbounds, msg): '''Sends a reply message.''' in_msg = yield inbounds.load_vumi_message(self.id, msg['reply_to']) if in_msg is None: raise MessageNotFound( "Inbound message with id %s not found" % (msg['reply_to'],)) event_url = msg.get('event_url') msg = message_from_api(self.id, msg) msg = in_msg.reply(**msg) msg = yield self._send_message(sender, outbounds, event_url, msg) returnValue(api_from_message(msg))
def consume_user_message(self, message): '''Sends the vumi message as an HTTP request to the configured URL''' yield self.inbounds.store_vumi_message(self.channel_id, message) msg = api_from_message(message) if self.config.get('mo_message_url') is not None: config = self.get_static_config() # Parse the basic auth username & password if available username = config.mo_message_url.username password = config.mo_message_url.password if any([username, password]): url = urlunparse(( config.mo_message_url.scheme, '%s%s' % (config.mo_message_url.hostname, (':%s' % (config.mo_message_url.port, ) if config.mo_message_url.port is not None else '')), config.mo_message_url.path, config.mo_message_url.params, config.mo_message_url.query, config.mo_message_url.fragment, )) auth = (username, password) else: url = config.mo_message_url.geturl() auth = None # Construct token auth headers if configured auth_token = config.mo_message_url_auth_token if auth_token: headers = {'Authorization': ['Token %s' % (auth_token, )]} else: headers = {} resp = yield post(url, msg, timeout=config.mo_message_url_timeout, auth=auth, headers=headers) if resp and request_failed(resp): logging.exception( 'Error sending message, received HTTP code %r with body %r' '. Message: %r' % (resp.code, (yield resp.content()), msg)) if self.config.get('message_queue') is not None: yield self.ro_connector.publish_inbound(message) yield self._increment_metric('inbound')
def consume_user_message(self, message): '''Sends the vumi message as an HTTP request to the configured URL''' yield self.inbounds.store_vumi_message(self.channel_id, message) msg = api_from_message(message) if self.config.get('mo_message_url') is not None: resp = yield post(self.config['mo_message_url'], msg) if request_failed(resp): logging.exception( 'Error sending message, received HTTP code %r with body %r' '. Message: %r' % (resp.code, (yield resp.content()), msg)) if self.config.get('message_queue') is not None: yield self.ro_connector.publish_inbound(message) yield self._increment_metric('inbound')
def send_reply_message(self, sender, outbounds, inbounds, msg, allow_expired_replies=False): '''Sends a reply message.''' in_msg = yield inbounds.load_vumi_message(self.id, msg['reply_to']) # NOTE: If we have a `reply_to` that cannot be found but also are # given a `to` and the config says we can send expired # replies then pop the `reply_to` from the message # and handle it like a normal outbound message. if in_msg is None and msg.get('to') and allow_expired_replies: msg.pop('reply_to') returnValue((yield self.send_message(sender, outbounds, msg))) elif in_msg is None: raise MessageNotFound( "Inbound message with id %s not found" % (msg['reply_to'],)) vumi_msg = message_from_api(self.id, msg) vumi_msg = in_msg.reply(**vumi_msg) vumi_msg = yield self._send_message(sender, outbounds, vumi_msg, msg) returnValue(api_from_message(vumi_msg))
def test_api_from_message(self): '''The api from message function should take a vumi message, and return a dict with the appropriate values''' message = TransportUserMessage.send( content=None, from_addr='+1234', to_addr='+5432', transport_name='testtransport', continue_session=True, helper_metadata={'voice': {}}) dct = api_from_message(message) [dct.pop(f) for f in ['timestamp', 'message_id']] self.assertEqual(dct, { 'channel_data': { 'continue_session': True, 'voice': {}, }, 'from': '+1234', 'to': '+5432', 'channel_id': 'testtransport', 'content': None, 'reply_to': None, })
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)
def test_api_from_message(self): '''The api from message function should take a vumi message, and return a dict with the appropriate values''' message = TransportUserMessage.send(content=None, from_addr='+1234', to_addr='+5432', transport_name='testtransport', continue_session=True, helper_metadata={'voice': {}}) dct = api_from_message(message) [dct.pop(f) for f in ['timestamp', 'message_id']] self.assertEqual( dct, { 'channel_data': { 'continue_session': True, 'voice': {}, }, 'from': '+1234', 'to': '+5432', 'channel_id': 'testtransport', 'content': None, 'reply_to': None, })
def send_reply_message(self, sender, outbounds, inbounds, msg, allow_expired_replies=False): '''Sends a reply message.''' in_msg = yield inbounds.load_vumi_message(self.id, msg['reply_to']) # NOTE: If we have a `reply_to` that cannot be found but also are # given a `to` and the config says we can send expired # replies then pop the `reply_to` from the message # and handle it like a normal outbound message. if in_msg is None and msg.get('to') and allow_expired_replies: msg.pop('reply_to') returnValue((yield self.send_message(sender, outbounds, msg))) elif in_msg is None: raise MessageNotFound("Inbound message with id %s not found" % (msg['reply_to'], )) vumi_msg = message_from_api(self.id, msg) vumi_msg = in_msg.reply(**vumi_msg) vumi_msg = yield self._send_message(sender, outbounds, vumi_msg, msg) returnValue(api_from_message(vumi_msg))
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)
def send_message(self, sender, outbounds, msg): '''Sends a message.''' vumi_msg = message_from_api(self.id, msg) vumi_msg = TransportUserMessage.send(**vumi_msg) vumi_msg = yield self._send_message(sender, outbounds, vumi_msg, msg) returnValue(api_from_message(vumi_msg))