Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
e38fc826
Commit
e38fc826
authored
Sep 14, 2015
by
Peter Fogg
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9752 from edx/peter-fogg/handle-elasticsearch-errors
Add error handling for elastic search.
parents
74757ed7
ca124354
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
83 additions
and
6 deletions
+83
-6
lms/djangoapps/teams/errors.py
+6
-1
lms/djangoapps/teams/search_indexes.py
+16
-3
lms/djangoapps/teams/tests/test_views.py
+49
-0
lms/djangoapps/teams/views.py
+12
-2
No files found.
lms/djangoapps/teams/errors.py
View file @
e38fc826
...
...
@@ -16,6 +16,11 @@ class AlreadyOnTeamInCourse(TeamAPIRequestError):
pass
class
ElasticSearchConnectionError
(
TeamAPIRequestError
):
"""The system was unable to connect to the configured elasticsearch instance."""
pass
class
ImmutableMembershipFieldException
(
Exception
):
"""An attempt was made to change an immutable field on a CourseTeamMembership model"""
"""An attempt was made to change an immutable field on a CourseTeamMembership model
.
"""
pass
lms/djangoapps/teams/search_indexes.py
View file @
e38fc826
""" Search index used to load data into elasticsearch"""
import
logging
from
elasticsearch.exceptions
import
ConnectionError
from
django.conf
import
settings
from
django.db.models.signals
import
post_delete
,
post_save
from
django.dispatch
import
receiver
...
...
@@ -8,6 +11,7 @@ from functools import wraps
from
search.search_engine_base
import
SearchEngine
from
.errors
import
ElasticSearchConnectionError
from
.serializers
import
CourseTeamSerializer
,
CourseTeam
...
...
@@ -103,8 +107,11 @@ class CourseTeamIndexer(object):
"""
Return course team search engine (if feature is enabled).
"""
if
cls
.
search_is_enabled
()
:
try
:
return
SearchEngine
.
get_search_engine
(
index
=
cls
.
INDEX_NAME
)
except
ConnectionError
as
err
:
logging
.
error
(
'Error connecting to elasticsearch:
%
s'
,
err
)
raise
ElasticSearchConnectionError
@classmethod
def
search_is_enabled
(
cls
):
...
...
@@ -119,7 +126,10 @@ def course_team_post_save_callback(**kwargs):
"""
Reindex object after save.
"""
CourseTeamIndexer
.
index
(
kwargs
[
'instance'
])
try
:
CourseTeamIndexer
.
index
(
kwargs
[
'instance'
])
except
ElasticSearchConnectionError
:
pass
@receiver
(
post_delete
,
sender
=
CourseTeam
,
dispatch_uid
=
'teams.signals.course_team_post_delete_callback'
)
...
...
@@ -127,4 +137,7 @@ def course_team_post_delete_callback(**kwargs): # pylint: disable=invalid-name
"""
Reindex object after delete.
"""
CourseTeamIndexer
.
remove
(
kwargs
[
'instance'
])
try
:
CourseTeamIndexer
.
remove
(
kwargs
[
'instance'
])
except
ElasticSearchConnectionError
:
pass
lms/djangoapps/teams/tests/test_views.py
View file @
e38fc826
...
...
@@ -5,6 +5,9 @@ import pytz
from
datetime
import
datetime
from
dateutil
import
parser
import
ddt
from
elasticsearch.exceptions
import
ConnectionError
from
mock
import
patch
from
search.search_engine_base
import
SearchEngine
from
django.core.urlresolvers
import
reverse
from
django.conf
import
settings
...
...
@@ -1397,3 +1400,49 @@ class TestDeleteMembershipAPI(EventTestMixin, TeamAPITestCase):
def
test_missing_membership
(
self
):
self
.
delete_membership
(
self
.
wind_team
.
team_id
,
self
.
users
[
'student_enrolled'
]
.
username
,
404
)
class
TestElasticSearchErrors
(
TeamAPITestCase
):
"""Test that the Team API is robust to Elasticsearch connection errors."""
ES_ERROR
=
ConnectionError
(
'N/A'
,
'connection error'
,
{})
@patch.object
(
SearchEngine
,
'get_search_engine'
,
side_effect
=
ES_ERROR
)
def
test_list_teams
(
self
,
__
):
"""Test that text searches return a 503 when Elasticsearch is down.
The endpoint should still return 200 when a search is not supplied."""
self
.
get_teams_list
(
expected_status
=
503
,
data
=
{
'course_id'
:
self
.
test_course_1
.
id
,
'text_search'
:
'zoinks'
},
user
=
'staff'
)
self
.
get_teams_list
(
expected_status
=
200
,
data
=
{
'course_id'
:
self
.
test_course_1
.
id
},
user
=
'staff'
)
@patch.object
(
SearchEngine
,
'get_search_engine'
,
side_effect
=
ES_ERROR
)
def
test_create_team
(
self
,
__
):
"""Test that team creation is robust to Elasticsearch errors."""
self
.
post_create_team
(
expected_status
=
200
,
data
=
self
.
build_team_data
(
name
=
'zoinks'
),
user
=
'staff'
)
@patch.object
(
SearchEngine
,
'get_search_engine'
,
side_effect
=
ES_ERROR
)
def
test_delete_team
(
self
,
__
):
"""Test that team deletion is robust to Elasticsearch errors."""
self
.
delete_team
(
self
.
wind_team
.
team_id
,
204
,
user
=
'staff'
)
@patch.object
(
SearchEngine
,
'get_search_engine'
,
side_effect
=
ES_ERROR
)
def
test_patch_team
(
self
,
__
):
"""Test that team updates are robust to Elasticsearch errors."""
self
.
patch_team_detail
(
self
.
wind_team
.
team_id
,
200
,
data
=
{
'description'
:
'new description'
},
user
=
'staff'
)
lms/djangoapps/teams/views.py
View file @
e38fc826
...
...
@@ -58,7 +58,7 @@ from .serializers import (
add_team_count
)
from
.search_indexes
import
CourseTeamIndexer
from
.errors
import
AlreadyOnTeamInCourse
,
NotEnrolledInCourseForTeam
from
.errors
import
AlreadyOnTeamInCourse
,
ElasticSearchConnectionError
,
NotEnrolledInCourseForTeam
TEAM_MEMBERSHIPS_PER_PAGE
=
2
TOPICS_PER_PAGE
=
12
...
...
@@ -293,6 +293,9 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
example, the course_id may not reference a real course or the page
number may be beyond the last page.
If the server is unable to connect to Elasticsearch, and
the text_search parameter is supplied, a 503 error is returned.
**Response Values for POST**
Any logged in user who has verified their email address can create
...
...
@@ -366,7 +369,14 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
return
Response
(
error
,
status
=
status
.
HTTP_400_BAD_REQUEST
)
result_filter
.
update
({
'topic_id'
:
topic_id
})
if
text_search
and
CourseTeamIndexer
.
search_is_enabled
():
search_engine
=
CourseTeamIndexer
.
engine
()
try
:
search_engine
=
CourseTeamIndexer
.
engine
()
except
ElasticSearchConnectionError
:
return
Response
(
build_api_error
(
ugettext_noop
(
'Error connecting to elasticsearch'
)),
status
=
status
.
HTTP_503_SERVICE_UNAVAILABLE
)
result_filter
.
update
({
'course_id'
:
course_id_string
})
search_results
=
search_engine
.
search
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment