Skip to content

Commit

Permalink
Parse and reformat start and end parameters in message export resource.
Browse files Browse the repository at this point in the history
  • Loading branch information
jerith committed Nov 21, 2014
1 parent 26cb838 commit 5a4c287
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 9 deletions.
40 changes: 31 additions & 9 deletions vumi/components/message_store_resource.py
@@ -1,5 +1,7 @@
# -*- test-case-name: vumi.components.tests.test_message_store_resource -*-

import iso8601

from twisted.application.internet import StreamServerEndpointService
from twisted.internet.defer import DeferredList, inlineCallbacks
from twisted.web.resource import NoResource, Resource
Expand All @@ -10,6 +12,7 @@
from vumi.config import (
ConfigDict, ConfigText, ConfigServerEndpoint, ConfigInt,
ServerEndpointFallback)
from vumi.message import VUMI_DATE_FORMAT
from vumi.persist.txriak_manager import TxRiakManager
from vumi.persist.txredis_manager import TxRedisManager
from vumi.transports.httprpc import httprpc
Expand All @@ -25,6 +28,13 @@ def chunks(l, n):
yield l[i:i + n]


class TimestampParseError(Exception):
"""
Exception raised while trying to parse a timestamp.
"""
pass


class MessageStoreProxyResource(Resource):

isLeaf = True
Expand All @@ -36,24 +46,36 @@ def __init__(self, message_store, batch_id, formatter):
self.batch_id = batch_id
self.formatter = formatter

def render_GET(self, request):
self.formatter.add_http_headers(request)
self.formatter.write_row_header(request)
def _extract_date_arg(self, request, argname):
if argname not in request.args:
return None
[value] = request.args[argname]
try:
timestamp = iso8601.parse_date(value)
return timestamp.strftime(VUMI_DATE_FORMAT)
except iso8601.ParseError as e:
raise TimestampParseError(
"Invalid '%s' parameter: %s" % (argname, e.args[0]))

def render_GET(self, request):
if 'concurrency' in request.args:
concurrency = int(request.args['concurrency'][0])
else:
concurrency = self.default_concurrency

start = request.args.get('start')
end = request.args.get('end')
try:
start = self._extract_date_arg(request, 'start')
end = self._extract_date_arg(request, 'end')
except TimestampParseError as e:
request.setResponseCode(400)
return e.args[0]

self.formatter.add_http_headers(request)
self.formatter.write_row_header(request)

if not (start or end):
d = self.get_keys_page(self.message_store, self.batch_id)
else:
if start:
[start] = start
if end:
[end] = end
d = self.get_keys_page_for_time(
self.message_store, self.batch_id, start, end)
request.connection_has_been_closed = False
Expand Down
38 changes: 38 additions & 0 deletions vumi/components/tests/test_message_store_resource.py
Expand Up @@ -239,6 +239,25 @@ def test_get_inbound_for_time_range(self):
set([msg['message_id'] for msg in messages]),
set([msg2['message_id'], msg3['message_id']]))

@inlineCallbacks
def test_get_inbound_for_time_range_bad_args(self):
yield self.start_server()
batch_id = yield self.make_batch(('foo', 'bar'))

resp = yield self.make_request(
'GET', batch_id, 'inbound.json', start='foo')
self.assertEqual(resp.code, 400)
self.assertEqual(
resp.delivered_body,
"Invalid 'start' parameter: Unable to parse date string 'foo'")

resp = yield self.make_request(
'GET', batch_id, 'inbound.json', end='bar')
self.assertEqual(resp.code, 400)
self.assertEqual(
resp.delivered_body,
"Invalid 'end' parameter: Unable to parse date string 'bar'")

@inlineCallbacks
def test_get_inbound_for_time_range_no_start(self):
yield self.start_server()
Expand Down Expand Up @@ -313,6 +332,25 @@ def test_get_outbound_for_time_range(self):
set([msg['message_id'] for msg in messages]),
set([msg2['message_id'], msg3['message_id']]))

@inlineCallbacks
def test_get_outbound_for_time_range_bad_args(self):
yield self.start_server()
batch_id = yield self.make_batch(('foo', 'bar'))

resp = yield self.make_request(
'GET', batch_id, 'outbound.json', start='foo')
self.assertEqual(resp.code, 400)
self.assertEqual(
resp.delivered_body,
"Invalid 'start' parameter: Unable to parse date string 'foo'")

resp = yield self.make_request(
'GET', batch_id, 'outbound.json', end='bar')
self.assertEqual(resp.code, 400)
self.assertEqual(
resp.delivered_body,
"Invalid 'end' parameter: Unable to parse date string 'bar'")

@inlineCallbacks
def test_get_outbound_for_time_range_no_start(self):
yield self.start_server()
Expand Down

0 comments on commit 5a4c287

Please sign in to comment.