Commit bb2508ac by Calen Pennington

Merge pull request #3062 from cpennington/comment-client-metrics

Add metrics to comment_client requests
parents f4e55ccb 6dd6f0c7
...@@ -51,7 +51,6 @@ class @DiscussionUtil ...@@ -51,7 +51,6 @@ class @DiscussionUtil
follow_discussion : "/courses/#{$$course_id}/discussion/#{param}/follow" follow_discussion : "/courses/#{$$course_id}/discussion/#{param}/follow"
unfollow_discussion : "/courses/#{$$course_id}/discussion/#{param}/unfollow" unfollow_discussion : "/courses/#{$$course_id}/discussion/#{param}/unfollow"
create_thread : "/courses/#{$$course_id}/discussion/#{param}/threads/create" create_thread : "/courses/#{$$course_id}/discussion/#{param}/threads/create"
search_similar_threads : "/courses/#{$$course_id}/discussion/#{param}/threads/search_similar"
update_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/update" update_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/update"
create_comment : "/courses/#{$$course_id}/discussion/threads/#{param}/reply" create_comment : "/courses/#{$$course_id}/discussion/threads/#{param}/reply"
delete_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/delete" delete_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/delete"
......
...@@ -23,9 +23,16 @@ log = logging.getLogger(__name__) ...@@ -23,9 +23,16 @@ log = logging.getLogger(__name__)
CS_PREFIX = "http://localhost:4567/api/v1" CS_PREFIX = "http://localhost:4567/api/v1"
class MockRequestSetupMixin(object):
def _set_mock_request_data(self, mock_request, data):
mock_request.return_value.text = json.dumps(data)
mock_request.return_value.json.return_value = data
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
@patch('lms.lib.comment_client.utils.requests.request') @patch('lms.lib.comment_client.utils.requests.request')
class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase): class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase, MockRequestSetupMixin):
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) @patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
def setUp(self): def setUp(self):
...@@ -63,26 +70,35 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -63,26 +70,35 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase):
def test_create_thread(self, mock_request): def test_create_thread(self, mock_request):
mock_request.return_value.status_code = 200 mock_request.return_value.status_code = 200
mock_request.return_value.text = u'{"title":"Hello",\ self._set_mock_request_data(mock_request, {
"body":"this is a post",\ "title": "Hello",
"course_id":"MITx/999/Robot_Super_Course",\ "body": "this is a post",
"anonymous":false,\ "course_id": "MITx/999/Robot_Super_Course",
"anonymous_to_peers":false,\ "anonymous": False,
"commentable_id":"i4x-MITx-999-course-Robot_Super_Course",\ "anonymous_to_peers": False,
"created_at":"2013-05-10T18:53:43Z",\ "commentable_id": "i4x-MITx-999-course-Robot_Super_Course",
"updated_at":"2013-05-10T18:53:43Z",\ "created_at": "2013-05-10T18:53:43Z",
"at_position_list":[],\ "updated_at": "2013-05-10T18:53:43Z",
"closed":false,\ "at_position_list": [],
"id":"518d4237b023791dca00000d",\ "closed": False,
"user_id":"1","username":"robot",\ "id": "518d4237b023791dca00000d",
"votes":{"count":0,"up_count":0,\ "user_id": "1",
"down_count":0,"point":0},\ "username": "robot",
"abuse_flaggers":[],\ "votes": {
"type":"thread","group_id":null,\ "count": 0,
"pinned":false,\ "up_count": 0,
"endorsed":false,\ "down_count": 0,
"unread_comments_count":0,\ "point": 0
"read":false,"comments_count":0}' },
"abuse_flaggers": [],
"type": "thread",
"group_id": None,
"pinned": False,
"endorsed": False,
"unread_comments_count": 0,
"read": False,
"comments_count": 0,
})
thread = {"body": ["this is a post"], thread = {"body": ["this is a post"],
"anonymous_to_peers": ["false"], "anonymous_to_peers": ["false"],
"auto_subscribe": ["false"], "auto_subscribe": ["false"],
...@@ -110,7 +126,7 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -110,7 +126,7 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase):
assert_equal(response.status_code, 200) assert_equal(response.status_code, 200)
def test_delete_comment(self, mock_request): def test_delete_comment(self, mock_request):
mock_request.return_value.text = json.dumps({ self._set_mock_request_data(mock_request, {
"user_id": str(self.student.id), "user_id": str(self.student.id),
"closed": False, "closed": False,
}) })
...@@ -138,7 +154,7 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -138,7 +154,7 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase):
} }
if include_depth: if include_depth:
data["depth"] = 0 data["depth"] = 0
mock_request.return_value.text = json.dumps(data) self._set_mock_request_data(mock_request, data)
def _test_request_error(self, view_name, view_kwargs, data, mock_request): def _test_request_error(self, view_name, view_kwargs, data, mock_request):
""" """
...@@ -290,26 +306,34 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -290,26 +306,34 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase):
def test_flag_thread(self, mock_request): def test_flag_thread(self, mock_request):
mock_request.return_value.status_code = 200 mock_request.return_value.status_code = 200
mock_request.return_value.text = u'{"title":"Hello",\ self._set_mock_request_data(mock_request, {
"body":"this is a post",\ "title": "Hello",
"course_id":"MITx/999/Robot_Super_Course",\ "body": "this is a post",
"anonymous":false,\ "course_id": "MITx/999/Robot_Super_Course",
"anonymous_to_peers":false,\ "anonymous": False,
"commentable_id":"i4x-MITx-999-course-Robot_Super_Course",\ "anonymous_to_peers": False,
"created_at":"2013-05-10T18:53:43Z",\ "commentable_id": "i4x-MITx-999-course-Robot_Super_Course",
"updated_at":"2013-05-10T18:53:43Z",\ "created_at": "2013-05-10T18:53:43Z",
"at_position_list":[],\ "updated_at": "2013-05-10T18:53:43Z",
"closed":false,\ "at_position_list": [],
"id":"518d4237b023791dca00000d",\ "closed": False,
"user_id":"1","username":"robot",\ "id": "518d4237b023791dca00000d",
"votes":{"count":0,"up_count":0,\ "user_id": "1","username": "robot",
"down_count":0,"point":0},\ "votes": {
"abuse_flaggers":[1],\ "count": 0,
"type":"thread","group_id":null,\ "up_count": 0,
"pinned":false,\ "down_count": 0,
"endorsed":false,\ "point": 0
"unread_comments_count":0,\ },
"read":false,"comments_count":0}' "abuse_flaggers": [1],
"type": "thread",
"group_id": None,
"pinned": False,
"endorsed": False,
"unread_comments_count": 0,
"read": False,
"comments_count": 0,
})
url = reverse('flag_abuse_for_thread', kwargs={'thread_id': '518d4237b023791dca00000d', 'course_id': self.course_id}) url = reverse('flag_abuse_for_thread', kwargs={'thread_id': '518d4237b023791dca00000d', 'course_id': self.course_id})
response = self.client.post(url) response = self.client.post(url)
assert_true(mock_request.called) assert_true(mock_request.called)
...@@ -350,26 +374,35 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -350,26 +374,35 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase):
def test_un_flag_thread(self, mock_request): def test_un_flag_thread(self, mock_request):
mock_request.return_value.status_code = 200 mock_request.return_value.status_code = 200
mock_request.return_value.text = u'{"title":"Hello",\ self._set_mock_request_data(mock_request, {
"body":"this is a post",\ "title": "Hello",
"course_id":"MITx/999/Robot_Super_Course",\ "body": "this is a post",
"anonymous":false,\ "course_id": "MITx/999/Robot_Super_Course",
"anonymous_to_peers":false,\ "anonymous": False,
"commentable_id":"i4x-MITx-999-course-Robot_Super_Course",\ "anonymous_to_peers": False,
"created_at":"2013-05-10T18:53:43Z",\ "commentable_id": "i4x-MITx-999-course-Robot_Super_Course",
"updated_at":"2013-05-10T18:53:43Z",\ "created_at": "2013-05-10T18:53:43Z",
"at_position_list":[],\ "updated_at": "2013-05-10T18:53:43Z",
"closed":false,\ "at_position_list": [],
"id":"518d4237b023791dca00000d",\ "closed": False,
"user_id":"1","username":"robot",\ "id": "518d4237b023791dca00000d",
"votes":{"count":0,"up_count":0,\ "user_id": "1",
"down_count":0,"point":0},\ "username": "robot",
"abuse_flaggers":[],\ "votes": {
"type":"thread","group_id":null,\ "count": 0,
"pinned":false,\ "up_count": 0,
"endorsed":false,\ "down_count": 0,
"unread_comments_count":0,\ "point": 0
"read":false,"comments_count":0}' },
"abuse_flaggers": [],
"type": "thread",
"group_id": None,
"pinned": False,
"endorsed": False,
"unread_comments_count": 0,
"read": False,
"comments_count": 0
})
url = reverse('un_flag_abuse_for_thread', kwargs={'thread_id': '518d4237b023791dca00000d', 'course_id': self.course_id}) url = reverse('un_flag_abuse_for_thread', kwargs={'thread_id': '518d4237b023791dca00000d', 'course_id': self.course_id})
response = self.client.post(url) response = self.client.post(url)
assert_true(mock_request.called) assert_true(mock_request.called)
...@@ -410,22 +443,29 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -410,22 +443,29 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase):
def test_flag_comment(self, mock_request): def test_flag_comment(self, mock_request):
mock_request.return_value.status_code = 200 mock_request.return_value.status_code = 200
mock_request.return_value.text = u'{"body":"this is a comment",\ self._set_mock_request_data(mock_request, {
"course_id":"MITx/999/Robot_Super_Course",\ "body": "this is a comment",
"anonymous":false,\ "course_id": "MITx/999/Robot_Super_Course",
"anonymous_to_peers":false,\ "anonymous": False,
"commentable_id":"i4x-MITx-999-course-Robot_Super_Course",\ "anonymous_to_peers": False,
"created_at":"2013-05-10T18:53:43Z",\ "commentable_id": "i4x-MITx-999-course-Robot_Super_Course",
"updated_at":"2013-05-10T18:53:43Z",\ "created_at": "2013-05-10T18:53:43Z",
"at_position_list":[],\ "updated_at": "2013-05-10T18:53:43Z",
"closed":false,\ "at_position_list": [],
"id":"518d4237b023791dca00000d",\ "closed": False,
"user_id":"1","username":"robot",\ "id": "518d4237b023791dca00000d",
"votes":{"count":0,"up_count":0,\ "user_id": "1",
"down_count":0,"point":0},\ "username": "robot",
"abuse_flaggers":[1],\ "votes": {
"type":"comment",\ "count": 0,
"endorsed":false}' "up_count": 0,
"down_count": 0,
"point": 0
},
"abuse_flaggers": [1],
"type": "comment",
"endorsed": False
})
url = reverse('flag_abuse_for_comment', kwargs={'comment_id': '518d4237b023791dca00000d', 'course_id': self.course_id}) url = reverse('flag_abuse_for_comment', kwargs={'comment_id': '518d4237b023791dca00000d', 'course_id': self.course_id})
response = self.client.post(url) response = self.client.post(url)
assert_true(mock_request.called) assert_true(mock_request.called)
...@@ -466,22 +506,29 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -466,22 +506,29 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase):
def test_un_flag_comment(self, mock_request): def test_un_flag_comment(self, mock_request):
mock_request.return_value.status_code = 200 mock_request.return_value.status_code = 200
mock_request.return_value.text = u'{"body":"this is a comment",\ self._set_mock_request_data(mock_request, {
"course_id":"MITx/999/Robot_Super_Course",\ "body": "this is a comment",
"anonymous":false,\ "course_id": "MITx/999/Robot_Super_Course",
"anonymous_to_peers":false,\ "anonymous": False,
"commentable_id":"i4x-MITx-999-course-Robot_Super_Course",\ "anonymous_to_peers": False,
"created_at":"2013-05-10T18:53:43Z",\ "commentable_id": "i4x-MITx-999-course-Robot_Super_Course",
"updated_at":"2013-05-10T18:53:43Z",\ "created_at": "2013-05-10T18:53:43Z",
"at_position_list":[],\ "updated_at": "2013-05-10T18:53:43Z",
"closed":false,\ "at_position_list": [],
"id":"518d4237b023791dca00000d",\ "closed": False,
"user_id":"1","username":"robot",\ "id": "518d4237b023791dca00000d",
"votes":{"count":0,"up_count":0,\ "user_id": "1",
"down_count":0,"point":0},\ "username": "robot",
"abuse_flaggers":[],\ "votes": {
"type":"comment",\ "count": 0,
"endorsed":false}' "up_count": 0,
"down_count": 0,
"point": 0
},
"abuse_flaggers": [],
"type": "comment",
"endorsed": False
})
url = reverse('un_flag_abuse_for_comment', kwargs={'comment_id': '518d4237b023791dca00000d', 'course_id': self.course_id}) url = reverse('un_flag_abuse_for_comment', kwargs={'comment_id': '518d4237b023791dca00000d', 'course_id': self.course_id})
response = self.client.post(url) response = self.client.post(url)
assert_true(mock_request.called) assert_true(mock_request.called)
...@@ -522,7 +569,7 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -522,7 +569,7 @@ class ViewsTestCase(UrlResetMixin, ModuleStoreTestCase):
@patch("lms.lib.comment_client.utils.requests.request") @patch("lms.lib.comment_client.utils.requests.request")
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase): class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase, MockRequestSetupMixin):
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) @patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
def setUp(self): def setUp(self):
super(ViewPermissionsTestCase, self).setUp() super(ViewPermissionsTestCase, self).setUp()
...@@ -536,7 +583,7 @@ class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -536,7 +583,7 @@ class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase):
self.moderator.roles.add(Role.objects.get(name="Moderator", course_id=self.course.id)) self.moderator.roles.add(Role.objects.get(name="Moderator", course_id=self.course.id))
def test_pin_thread_as_student(self, mock_request): def test_pin_thread_as_student(self, mock_request):
mock_request.return_value.text = "{}" self._set_mock_request_data(mock_request, {})
self.client.login(username=self.student.username, password=self.password) self.client.login(username=self.student.username, password=self.password)
response = self.client.post( response = self.client.post(
reverse("pin_thread", kwargs={"course_id": self.course.id, "thread_id": "dummy"}) reverse("pin_thread", kwargs={"course_id": self.course.id, "thread_id": "dummy"})
...@@ -544,7 +591,7 @@ class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -544,7 +591,7 @@ class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase):
self.assertEqual(response.status_code, 401) self.assertEqual(response.status_code, 401)
def test_pin_thread_as_moderator(self, mock_request): def test_pin_thread_as_moderator(self, mock_request):
mock_request.return_value.text = "{}" self._set_mock_request_data(mock_request, {})
self.client.login(username=self.moderator.username, password=self.password) self.client.login(username=self.moderator.username, password=self.password)
response = self.client.post( response = self.client.post(
reverse("pin_thread", kwargs={"course_id": self.course.id, "thread_id": "dummy"}) reverse("pin_thread", kwargs={"course_id": self.course.id, "thread_id": "dummy"})
...@@ -552,7 +599,7 @@ class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -552,7 +599,7 @@ class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_un_pin_thread_as_student(self, mock_request): def test_un_pin_thread_as_student(self, mock_request):
mock_request.return_value.text = "{}" self._set_mock_request_data(mock_request, {})
self.client.login(username=self.student.username, password=self.password) self.client.login(username=self.student.username, password=self.password)
response = self.client.post( response = self.client.post(
reverse("un_pin_thread", kwargs={"course_id": self.course.id, "thread_id": "dummy"}) reverse("un_pin_thread", kwargs={"course_id": self.course.id, "thread_id": "dummy"})
...@@ -560,7 +607,7 @@ class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -560,7 +607,7 @@ class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase):
self.assertEqual(response.status_code, 401) self.assertEqual(response.status_code, 401)
def test_un_pin_thread_as_moderator(self, mock_request): def test_un_pin_thread_as_moderator(self, mock_request):
mock_request.return_value.text = "{}" self._set_mock_request_data(mock_request, {})
self.client.login(username=self.moderator.username, password=self.password) self.client.login(username=self.moderator.username, password=self.password)
response = self.client.post( response = self.client.post(
reverse("un_pin_thread", kwargs={"course_id": self.course.id, "thread_id": "dummy"}) reverse("un_pin_thread", kwargs={"course_id": self.course.id, "thread_id": "dummy"})
...@@ -569,7 +616,7 @@ class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase): ...@@ -569,7 +616,7 @@ class ViewPermissionsTestCase(UrlResetMixin, ModuleStoreTestCase):
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class CreateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): class CreateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockRequestSetupMixin):
def setUp(self): def setUp(self):
self.course = CourseFactory.create() self.course = CourseFactory.create()
seed_permissions_roles(self.course.id) seed_permissions_roles(self.course.id)
...@@ -578,7 +625,7 @@ class CreateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): ...@@ -578,7 +625,7 @@ class CreateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin):
@patch('lms.lib.comment_client.utils.requests.request') @patch('lms.lib.comment_client.utils.requests.request')
def _test_unicode_data(self, text, mock_request): def _test_unicode_data(self, text, mock_request):
mock_request.return_value.text = "{}" self._set_mock_request_data(mock_request, {})
request = RequestFactory().post("dummy_url", {"body": text, "title": text}) request = RequestFactory().post("dummy_url", {"body": text, "title": text})
request.user = self.student request.user = self.student
request.view_name = "create_thread" request.view_name = "create_thread"
...@@ -591,7 +638,7 @@ class CreateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): ...@@ -591,7 +638,7 @@ class CreateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin):
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockRequestSetupMixin):
def setUp(self): def setUp(self):
self.course = CourseFactory.create() self.course = CourseFactory.create()
seed_permissions_roles(self.course.id) seed_permissions_roles(self.course.id)
...@@ -600,7 +647,7 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): ...@@ -600,7 +647,7 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin):
@patch('lms.lib.comment_client.utils.requests.request') @patch('lms.lib.comment_client.utils.requests.request')
def _test_unicode_data(self, text, mock_request): def _test_unicode_data(self, text, mock_request):
mock_request.return_value.text = json.dumps({ self._set_mock_request_data(mock_request, {
"user_id": str(self.student.id), "user_id": str(self.student.id),
"closed": False, "closed": False,
}) })
...@@ -616,7 +663,7 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): ...@@ -616,7 +663,7 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin):
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class CreateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): class CreateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockRequestSetupMixin):
def setUp(self): def setUp(self):
self.course = CourseFactory.create() self.course = CourseFactory.create()
seed_permissions_roles(self.course.id) seed_permissions_roles(self.course.id)
...@@ -625,7 +672,7 @@ class CreateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): ...@@ -625,7 +672,7 @@ class CreateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin):
@patch('lms.lib.comment_client.utils.requests.request') @patch('lms.lib.comment_client.utils.requests.request')
def _test_unicode_data(self, text, mock_request): def _test_unicode_data(self, text, mock_request):
mock_request.return_value.text = json.dumps({ self._set_mock_request_data(mock_request, {
"closed": False, "closed": False,
}) })
request = RequestFactory().post("dummy_url", {"body": text}) request = RequestFactory().post("dummy_url", {"body": text})
...@@ -639,7 +686,7 @@ class CreateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): ...@@ -639,7 +686,7 @@ class CreateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin):
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class UpdateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): class UpdateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockRequestSetupMixin):
def setUp(self): def setUp(self):
self.course = CourseFactory.create() self.course = CourseFactory.create()
seed_permissions_roles(self.course.id) seed_permissions_roles(self.course.id)
...@@ -648,7 +695,7 @@ class UpdateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): ...@@ -648,7 +695,7 @@ class UpdateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin):
@patch('lms.lib.comment_client.utils.requests.request') @patch('lms.lib.comment_client.utils.requests.request')
def _test_unicode_data(self, text, mock_request): def _test_unicode_data(self, text, mock_request):
mock_request.return_value.text = json.dumps({ self._set_mock_request_data(mock_request, {
"user_id": str(self.student.id), "user_id": str(self.student.id),
"closed": False, "closed": False,
}) })
...@@ -663,7 +710,7 @@ class UpdateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): ...@@ -663,7 +710,7 @@ class UpdateCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin):
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class CreateSubCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): class CreateSubCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockRequestSetupMixin):
def setUp(self): def setUp(self):
self.course = CourseFactory.create() self.course = CourseFactory.create()
seed_permissions_roles(self.course.id) seed_permissions_roles(self.course.id)
...@@ -672,7 +719,7 @@ class CreateSubCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin): ...@@ -672,7 +719,7 @@ class CreateSubCommentUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin):
@patch('lms.lib.comment_client.utils.requests.request') @patch('lms.lib.comment_client.utils.requests.request')
def _test_unicode_data(self, text, mock_request): def _test_unicode_data(self, text, mock_request):
mock_request.return_value.text = json.dumps({ self._set_mock_request_data(mock_request, {
"closed": False, "closed": False,
"depth": 1, "depth": 1,
}) })
......
...@@ -25,8 +25,6 @@ urlpatterns = patterns('django_comment_client.base.views', # nopep8 ...@@ -25,8 +25,6 @@ urlpatterns = patterns('django_comment_client.base.views', # nopep8
url(r'comments/(?P<comment_id>[\w\-]+)/flagAbuse$', 'flag_abuse_for_comment', name='flag_abuse_for_comment'), url(r'comments/(?P<comment_id>[\w\-]+)/flagAbuse$', 'flag_abuse_for_comment', name='flag_abuse_for_comment'),
url(r'comments/(?P<comment_id>[\w\-]+)/unFlagAbuse$', 'un_flag_abuse_for_comment', name='un_flag_abuse_for_comment'), url(r'comments/(?P<comment_id>[\w\-]+)/unFlagAbuse$', 'un_flag_abuse_for_comment', name='un_flag_abuse_for_comment'),
url(r'^(?P<commentable_id>[\w\-.]+)/threads/create$', 'create_thread', name='create_thread'), url(r'^(?P<commentable_id>[\w\-.]+)/threads/create$', 'create_thread', name='create_thread'),
# TODO should we search within the board?
url(r'^(?P<commentable_id>[\w\-.]+)/threads/search_similar$', 'search_similar_threads', name='search_similar_threads'),
url(r'^(?P<commentable_id>[\w\-.]+)/follow$', 'follow_commentable', name='follow_commentable'), url(r'^(?P<commentable_id>[\w\-.]+)/follow$', 'follow_commentable', name='follow_commentable'),
url(r'^(?P<commentable_id>[\w\-.]+)/unfollow$', 'unfollow_commentable', name='unfollow_commentable'), url(r'^(?P<commentable_id>[\w\-.]+)/unfollow$', 'unfollow_commentable', name='unfollow_commentable'),
) )
...@@ -521,27 +521,6 @@ def unfollow_user(request, course_id, followed_user_id): ...@@ -521,27 +521,6 @@ def unfollow_user(request, course_id, followed_user_id):
return JsonResponse({}) return JsonResponse({})
@require_GET
def search_similar_threads(request, course_id, commentable_id):
"""
given a course id and commentable id, run query given in text get param
of request
"""
text = request.GET.get('text', None)
if text:
query_params = {
'text': text,
'commentable_id': commentable_id,
}
threads = cc.search_similar_threads(course_id, recursive=False, query_params=query_params)
else:
theads = []
context = {'threads': map(utils.extend_content, threads)}
return JsonResponse({
'html': render_to_string('discussion/_similar_posts.html', context)
})
@require_POST @require_POST
@login_required @login_required
@csrf.csrf_exempt @csrf.csrf_exempt
......
...@@ -109,26 +109,18 @@ def make_mock_request_impl(text, thread_id=None): ...@@ -109,26 +109,18 @@ def make_mock_request_impl(text, thread_id=None):
def mock_request_impl(*args, **kwargs): def mock_request_impl(*args, **kwargs):
url = args[1] url = args[1]
if url.endswith("threads"): if url.endswith("threads"):
return Mock( data = {
status_code=200, "collection": [make_mock_thread_data(text, "dummy_thread_id", False)]
text=json.dumps({ }
"collection": [make_mock_thread_data(text, "dummy_thread_id", False)]
})
)
elif thread_id and url.endswith(thread_id): elif thread_id and url.endswith(thread_id):
return Mock( data = make_mock_thread_data(text, thread_id, True)
status_code=200,
text=json.dumps(make_mock_thread_data(text, thread_id, True))
)
else: # user query else: # user query
return Mock( data = {
status_code=200, "upvoted_ids": [],
text=json.dumps({ "downvoted_ids": [],
"upvoted_ids": [], "subscribed_thread_ids": [],
"downvoted_ids": [], }
"subscribed_thread_ids": [], return Mock(status_code=200, text=json.dumps(data), json=Mock(return_value=data))
})
)
return mock_request_impl return mock_request_impl
......
...@@ -196,12 +196,6 @@ def forum_form_discussion(request, course_id): ...@@ -196,12 +196,6 @@ def forum_form_discussion(request, course_id):
'page': query_params['page'], 'page': query_params['page'],
}) })
else: else:
#recent_active_threads = cc.search_recent_active_threads(
# course_id,
# recursive=False,
# query_params={'follower_id': request.user.id},
#)
with newrelic.agent.FunctionTrace(nr_transaction, "get_cohort_info"): with newrelic.agent.FunctionTrace(nr_transaction, "get_cohort_info"):
cohorts = get_course_cohorts(course_id) cohorts = get_course_cohorts(course_id)
cohorted_commentables = get_cohorted_commentables(course_id) cohorted_commentables = get_cohorted_commentables(course_id)
...@@ -283,12 +277,6 @@ def single_thread(request, course_id, discussion_id, thread_id): ...@@ -283,12 +277,6 @@ def single_thread(request, course_id, discussion_id, thread_id):
threads = [utils.safe_content(thread) for thread in threads] threads = [utils.safe_content(thread) for thread in threads]
#recent_active_threads = cc.search_recent_active_threads(
# course_id,
# recursive=False,
# query_params={'follower_id': request.user.id},
#)
with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"): with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"):
annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info) annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info)
......
...@@ -21,6 +21,8 @@ class Comment(models.Model): ...@@ -21,6 +21,8 @@ class Comment(models.Model):
initializable_fields = updatable_fields initializable_fields = updatable_fields
metrics_tag_fields = ['course_id', 'endorsed', 'closed']
base_url = "{prefix}/comments".format(prefix=settings.PREFIX) base_url = "{prefix}/comments".format(prefix=settings.PREFIX)
type = 'comment' type = 'comment'
...@@ -50,7 +52,13 @@ class Comment(models.Model): ...@@ -50,7 +52,13 @@ class Comment(models.Model):
else: else:
raise CommentClientRequestError("Can only flag/unflag threads or comments") raise CommentClientRequestError("Can only flag/unflag threads or comments")
params = {'user_id': user.id} params = {'user_id': user.id}
request = perform_request('put', url, params) request = perform_request(
'put',
url,
params,
metric_tags=self._metric_tags,
metric_action='comment.abuse.flagged'
)
voteable.update_attributes(request) voteable.update_attributes(request)
def unFlagAbuse(self, user, voteable, removeAll): def unFlagAbuse(self, user, voteable, removeAll):
...@@ -65,7 +73,13 @@ class Comment(models.Model): ...@@ -65,7 +73,13 @@ class Comment(models.Model):
if removeAll: if removeAll:
params['all'] = True params['all'] = True
request = perform_request('put', url, params) request = perform_request(
'put',
url,
params,
metric_tags=self._metric_tags,
metric_action='comment.abuse.unflagged'
)
voteable.update_attributes(request) voteable.update_attributes(request)
......
...@@ -4,27 +4,3 @@ from .comment import Comment ...@@ -4,27 +4,3 @@ from .comment import Comment
from .thread import Thread from .thread import Thread
from .user import User from .user import User
from .commentable import Commentable from .commentable import Commentable
from .utils import perform_request
import settings
def search_similar_threads(course_id, recursive=False, query_params={}, *args, **kwargs):
default_params = {'course_id': course_id, 'recursive': recursive}
attributes = dict(default_params.items() + query_params.items())
return perform_request('get', _url_for_search_similar_threads(), attributes, *args, **kwargs)
def search_recent_active_threads(course_id, recursive=False, query_params={}, *args, **kwargs):
default_params = {'course_id': course_id, 'recursive': recursive}
attributes = dict(default_params.items() + query_params.items())
return perform_request('get', _url_for_search_recent_active_threads(), attributes, *args, **kwargs)
def _url_for_search_similar_threads():
return "{prefix}/search/threads/more_like_this".format(prefix=settings.PREFIX)
def _url_for_search_recent_active_threads():
return "{prefix}/search/threads/recent_active".format(prefix=settings.PREFIX)
...@@ -8,6 +8,7 @@ class Model(object): ...@@ -8,6 +8,7 @@ class Model(object):
initializable_fields = ['id'] initializable_fields = ['id']
base_url = None base_url = None
default_retrieve_params = {} default_retrieve_params = {}
metric_tag_fields = []
DEFAULT_ACTIONS_WITH_ID = ['get', 'put', 'delete'] DEFAULT_ACTIONS_WITH_ID = ['get', 'put', 'delete']
DEFAULT_ACTIONS_WITHOUT_ID = ['get_all', 'post'] DEFAULT_ACTIONS_WITHOUT_ID = ['get_all', 'post']
...@@ -62,9 +63,32 @@ class Model(object): ...@@ -62,9 +63,32 @@ class Model(object):
def _retrieve(self, *args, **kwargs): def _retrieve(self, *args, **kwargs):
url = self.url(action='get', params=self.attributes) url = self.url(action='get', params=self.attributes)
response = perform_request('get', url, self.default_retrieve_params) response = perform_request(
'get',
url,
self.default_retrieve_params,
metric_tags=self._metric_tags,
metric_action='model.retrieve'
)
self.update_attributes(**response) self.update_attributes(**response)
@property
def _metric_tags(self):
"""
Returns a list of tags to be used when recording metrics about this model.
Each field named in ``self.metric_tag_fields`` is used as a tag value,
under the key ``<class>.<metric_field>``. The tag model_class is used to
record the class name of the model.
"""
tags = [
u'{}.{}:{}'.format(self.__class__.__name__, attr, self[attr])
for attr in self.metric_tag_fields
if attr in self.attributes
]
tags.append(u'model_class:{}'.format(self.__class__.__name__))
return tags
@classmethod @classmethod
def find(cls, id): def find(cls, id):
return cls(id=id) return cls(id=id)
...@@ -94,17 +118,29 @@ class Model(object): ...@@ -94,17 +118,29 @@ class Model(object):
self.before_save(self) self.before_save(self)
if self.id: # if we have id already, treat this as an update if self.id: # if we have id already, treat this as an update
url = self.url(action='put', params=self.attributes) url = self.url(action='put', params=self.attributes)
response = perform_request('put', url, self.updatable_attributes()) response = perform_request(
'put',
url,
self.updatable_attributes(),
metric_tags=self._metric_tags,
metric_action='model.update'
)
else: # otherwise, treat this as an insert else: # otherwise, treat this as an insert
url = self.url(action='post', params=self.attributes) url = self.url(action='post', params=self.attributes)
response = perform_request('post', url, self.initializable_attributes()) response = perform_request(
'post',
url,
self.initializable_attributes(),
metric_tags=self._metric_tags,
metric_action='model.insert'
)
self.retrieved = True self.retrieved = True
self.update_attributes(**response) self.update_attributes(**response)
self.after_save(self) self.after_save(self)
def delete(self): def delete(self):
url = self.url(action='delete', params=self.attributes) url = self.url(action='delete', params=self.attributes)
response = perform_request('delete', url) response = perform_request('delete', url, metric_tags=self._metric_tags, metric_action='model.delete')
self.retrieved = True self.retrieved = True
self.update_attributes(**response) self.update_attributes(**response)
......
...@@ -20,6 +20,11 @@ class Thread(models.Model): ...@@ -20,6 +20,11 @@ class Thread(models.Model):
'closed', 'user_id', 'commentable_id', 'group_id', 'group_name', 'pinned' 'closed', 'user_id', 'commentable_id', 'group_id', 'group_name', 'pinned'
] ]
metric_tag_fields = [
'course_id', 'group_id', 'pinned', 'closed', 'anonymous', 'anonymous_to_peers',
'endorsed', 'read'
]
initializable_fields = updatable_fields initializable_fields = updatable_fields
base_url = "{prefix}/threads".format(prefix=settings.PREFIX) base_url = "{prefix}/threads".format(prefix=settings.PREFIX)
...@@ -27,7 +32,7 @@ class Thread(models.Model): ...@@ -27,7 +32,7 @@ class Thread(models.Model):
type = 'thread' type = 'thread'
@classmethod @classmethod
def search(cls, query_params, *args, **kwargs): def search(cls, query_params):
default_params = {'page': 1, default_params = {'page': 1,
'per_page': 20, 'per_page': 20,
...@@ -41,7 +46,14 @@ class Thread(models.Model): ...@@ -41,7 +46,14 @@ class Thread(models.Model):
url = cls.url(action='get_all', params=extract(params, 'commentable_id')) url = cls.url(action='get_all', params=extract(params, 'commentable_id'))
if params.get('commentable_id'): if params.get('commentable_id'):
del params['commentable_id'] del params['commentable_id']
response = perform_request('get', url, params, *args, **kwargs) response = perform_request(
'get',
url,
params,
metric_tags=[u'course_id:{}'.format(query_params['course_id'])],
metric_action='thread.search',
paged_results=True
)
return response.get('collection', []), response.get('page', 1), response.get('num_pages', 1) return response.get('collection', []), response.get('page', 1), response.get('num_pages', 1)
@classmethod @classmethod
...@@ -79,7 +91,13 @@ class Thread(models.Model): ...@@ -79,7 +91,13 @@ class Thread(models.Model):
} }
request_params = strip_none(request_params) request_params = strip_none(request_params)
response = perform_request('get', url, request_params) response = perform_request(
'get',
url,
request_params,
metric_action='model.retrieve',
metric_tags=self._metric_tags
)
self.update_attributes(**response) self.update_attributes(**response)
def flagAbuse(self, user, voteable): def flagAbuse(self, user, voteable):
...@@ -90,7 +108,13 @@ class Thread(models.Model): ...@@ -90,7 +108,13 @@ class Thread(models.Model):
else: else:
raise CommentClientRequestError("Can only flag/unflag threads or comments") raise CommentClientRequestError("Can only flag/unflag threads or comments")
params = {'user_id': user.id} params = {'user_id': user.id}
request = perform_request('put', url, params) request = perform_request(
'put',
url,
params,
metric_action='thread.abuse.flagged',
metric_tags=self._metric_tags
)
voteable.update_attributes(request) voteable.update_attributes(request)
def unFlagAbuse(self, user, voteable, removeAll): def unFlagAbuse(self, user, voteable, removeAll):
...@@ -105,19 +129,37 @@ class Thread(models.Model): ...@@ -105,19 +129,37 @@ class Thread(models.Model):
if removeAll: if removeAll:
params['all'] = True params['all'] = True
request = perform_request('put', url, params) request = perform_request(
'put',
url,
params,
metric_tags=self._metric_tags,
metric_action='thread.abuse.unflagged'
)
voteable.update_attributes(request) voteable.update_attributes(request)
def pin(self, user, thread_id): def pin(self, user, thread_id):
url = _url_for_pin_thread(thread_id) url = _url_for_pin_thread(thread_id)
params = {'user_id': user.id} params = {'user_id': user.id}
request = perform_request('put', url, params) request = perform_request(
'put',
url,
params,
metric_tags=self._metric_tags,
metric_action='thread.pin'
)
self.update_attributes(request) self.update_attributes(request)
def un_pin(self, user, thread_id): def un_pin(self, user, thread_id):
url = _url_for_un_pin_thread(thread_id) url = _url_for_un_pin_thread(thread_id)
params = {'user_id': user.id} params = {'user_id': user.id}
request = perform_request('put', url, params) request = perform_request(
'put',
url,
params,
metric_tags=self._metric_tags,
metric_action='thread.unpin'
)
self.update_attributes(request) self.update_attributes(request)
......
...@@ -16,6 +16,8 @@ class User(models.Model): ...@@ -16,6 +16,8 @@ class User(models.Model):
updatable_fields = ['username', 'external_id', 'email', 'default_sort_key'] updatable_fields = ['username', 'external_id', 'email', 'default_sort_key']
initializable_fields = updatable_fields initializable_fields = updatable_fields
metric_tag_fields = ['course_id']
base_url = "{prefix}/users".format(prefix=settings.PREFIX) base_url = "{prefix}/users".format(prefix=settings.PREFIX)
default_retrieve_params = {'complete': True} default_retrieve_params = {'complete': True}
type = 'user' type = 'user'
...@@ -29,11 +31,23 @@ class User(models.Model): ...@@ -29,11 +31,23 @@ class User(models.Model):
def follow(self, source): def follow(self, source):
params = {'source_type': source.type, 'source_id': source.id} params = {'source_type': source.type, 'source_id': source.id}
response = perform_request('post', _url_for_subscription(self.id), params) response = perform_request(
'post',
_url_for_subscription(self.id),
params,
metric_action='user.follow',
metric_tags=self._metric_tags + ['target.type:{}'.format(source.type)],
)
def unfollow(self, source): def unfollow(self, source):
params = {'source_type': source.type, 'source_id': source.id} params = {'source_type': source.type, 'source_id': source.id}
response = perform_request('delete', _url_for_subscription(self.id), params) response = perform_request(
'delete',
_url_for_subscription(self.id),
params,
metric_action='user.unfollow',
metric_tags=self._metric_tags + ['target.type:{}'.format(source.type)],
)
def vote(self, voteable, value): def vote(self, voteable, value):
if voteable.type == 'thread': if voteable.type == 'thread':
...@@ -43,7 +57,13 @@ class User(models.Model): ...@@ -43,7 +57,13 @@ class User(models.Model):
else: else:
raise CommentClientRequestError("Can only vote / unvote for threads or comments") raise CommentClientRequestError("Can only vote / unvote for threads or comments")
params = {'user_id': self.id, 'value': value} params = {'user_id': self.id, 'value': value}
request = perform_request('put', url, params) request = perform_request(
'put',
url,
params,
metric_action='user.vote',
metric_tags=self._metric_tags + ['target.type:{}'.format(voteable.type)],
)
voteable.update_attributes(request) voteable.update_attributes(request)
def unvote(self, voteable): def unvote(self, voteable):
...@@ -54,7 +74,13 @@ class User(models.Model): ...@@ -54,7 +74,13 @@ class User(models.Model):
else: else:
raise CommentClientRequestError("Can only vote / unvote for threads or comments") raise CommentClientRequestError("Can only vote / unvote for threads or comments")
params = {'user_id': self.id} params = {'user_id': self.id}
request = perform_request('delete', url, params) request = perform_request(
'delete',
url,
params,
metric_action='user.unvote',
metric_tags=self._metric_tags + ['target.type:{}'.format(voteable.type)],
)
voteable.update_attributes(request) voteable.update_attributes(request)
def active_threads(self, query_params={}): def active_threads(self, query_params={}):
...@@ -63,7 +89,14 @@ class User(models.Model): ...@@ -63,7 +89,14 @@ class User(models.Model):
url = _url_for_user_active_threads(self.id) url = _url_for_user_active_threads(self.id)
params = {'course_id': self.course_id} params = {'course_id': self.course_id}
params = merge_dict(params, query_params) params = merge_dict(params, query_params)
response = perform_request('get', url, params) response = perform_request(
'get',
url,
params,
metric_action='user.active_threads',
metric_tags=self._metric_tags,
paged_results=True,
)
return response.get('collection', []), response.get('page', 1), response.get('num_pages', 1) return response.get('collection', []), response.get('page', 1), response.get('num_pages', 1)
def subscribed_threads(self, query_params={}): def subscribed_threads(self, query_params={}):
...@@ -72,7 +105,14 @@ class User(models.Model): ...@@ -72,7 +105,14 @@ class User(models.Model):
url = _url_for_user_subscribed_threads(self.id) url = _url_for_user_subscribed_threads(self.id)
params = {'course_id': self.course_id} params = {'course_id': self.course_id}
params = merge_dict(params, query_params) params = merge_dict(params, query_params)
response = perform_request('get', url, params) response = perform_request(
'get',
url,
params,
metric_action='user.subscribed_threads',
metric_tags=self._metric_tags,
paged_results=True
)
return response.get('collection', []), response.get('page', 1), response.get('num_pages', 1) return response.get('collection', []), response.get('page', 1), response.get('num_pages', 1)
def _retrieve(self, *args, **kwargs): def _retrieve(self, *args, **kwargs):
...@@ -81,13 +121,25 @@ class User(models.Model): ...@@ -81,13 +121,25 @@ class User(models.Model):
if self.attributes.get('course_id'): if self.attributes.get('course_id'):
retrieve_params['course_id'] = self.course_id retrieve_params['course_id'] = self.course_id
try: try:
response = perform_request('get', url, retrieve_params) response = perform_request(
'get',
url,
retrieve_params,
metric_action='model.retrieve',
metric_tags=self._metric_tags,
)
except CommentClientRequestError as e: except CommentClientRequestError as e:
if e.status_code == 404: if e.status_code == 404:
# attempt to gracefully recover from a previous failure # attempt to gracefully recover from a previous failure
# to sync this user to the comments service. # to sync this user to the comments service.
self.save() self.save()
response = perform_request('get', url, retrieve_params) response = perform_request(
'get',
url,
retrieve_params,
metric_action='model.retrieve',
metric_tags=self._metric_tags,
)
else: else:
raise raise
self.update_attributes(**response) self.update_attributes(**response)
......
...@@ -33,12 +33,13 @@ def merge_dict(dic1, dic2): ...@@ -33,12 +33,13 @@ def merge_dict(dic1, dic2):
@contextmanager @contextmanager
def request_timer(request_id, method, url): def request_timer(request_id, method, url, tags=None):
start = time() start = time()
yield with dog_stats_api.timer('comment_client.request.time', tags=tags):
yield
end = time() end = time()
duration = end - start duration = end - start
dog_stats_api.histogram('comment_client.request.time', duration, end)
log.info( log.info(
"comment_client_request_log: request_id={request_id}, method={method}, " "comment_client_request_log: request_id={request_id}, method={method}, "
"url={url}, duration={duration}".format( "url={url}, duration={duration}".format(
...@@ -50,7 +51,16 @@ def request_timer(request_id, method, url): ...@@ -50,7 +51,16 @@ def request_timer(request_id, method, url):
) )
def perform_request(method, url, data_or_params=None, *args, **kwargs): def perform_request(method, url, data_or_params=None, raw=False,
metric_action=None, metric_tags=None, paged_results=False):
if metric_tags is None:
metric_tags = []
metric_tags.append(u'method:{}'.format(method))
if metric_action:
metric_tags.append(u'action:{}'.format(metric_action))
if data_or_params is None: if data_or_params is None:
data_or_params = {} data_or_params = {}
headers = { headers = {
...@@ -66,7 +76,7 @@ def perform_request(method, url, data_or_params=None, *args, **kwargs): ...@@ -66,7 +76,7 @@ def perform_request(method, url, data_or_params=None, *args, **kwargs):
else: else:
data = None data = None
params = merge_dict(data_or_params, request_id_dict) params = merge_dict(data_or_params, request_id_dict)
with request_timer(request_id, method, url): with request_timer(request_id, method, url, metric_tags):
response = requests.request( response = requests.request(
method, method,
url, url,
...@@ -76,6 +86,14 @@ def perform_request(method, url, data_or_params=None, *args, **kwargs): ...@@ -76,6 +86,14 @@ def perform_request(method, url, data_or_params=None, *args, **kwargs):
timeout=5 timeout=5
) )
metric_tags.append(u'status_code:{}'.format(response.status_code))
if response.status_code > 200:
metric_tags.append(u'result:failure')
else:
metric_tags.append(u'result:success')
dog_stats_api.increment('comment_client.request.count', tags=metric_tags)
if 200 < response.status_code < 500: if 200 < response.status_code < 500:
raise CommentClientRequestError(response.text, response.status_code) raise CommentClientRequestError(response.text, response.status_code)
# Heroku returns a 503 when an application is in maintenance mode # Heroku returns a 503 when an application is in maintenance mode
...@@ -84,10 +102,27 @@ def perform_request(method, url, data_or_params=None, *args, **kwargs): ...@@ -84,10 +102,27 @@ def perform_request(method, url, data_or_params=None, *args, **kwargs):
elif response.status_code == 500: elif response.status_code == 500:
raise CommentClient500Error(response.text) raise CommentClient500Error(response.text)
else: else:
if kwargs.get("raw", False): if raw:
return response.text return response.text
else: else:
return json.loads(response.text) data = response.json()
if paged_results:
dog_stats_api.histogram(
'comment_client.request.paged.result_count',
value=len(data.get('collection', [])),
tags=metric_tags
)
dog_stats_api.histogram(
'comment_client.request.paged.page',
value=data.get('page', 1),
tags=metric_tags
)
dog_stats_api.histogram(
'comment_client.request.paged.num_pages',
value=data.get('num_pages', 1),
tags=metric_tags
)
return data
class CommentClientError(Exception): class CommentClientError(Exception):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment