diff --git a/common/lib/xmodule/xmodule/modulestore/django.py b/common/lib/xmodule/xmodule/modulestore/django.py index 094890c19443..43dc2ac112fc 100644 --- a/common/lib/xmodule/xmodule/modulestore/django.py +++ b/common/lib/xmodule/xmodule/modulestore/django.py @@ -24,7 +24,6 @@ import django.utils from django.utils.translation import get_language, to_locale -from pymongo import ReadPreference from xmodule.contentstore.django import contentstore from xmodule.modulestore.draft_and_published import BranchSettingMixin from xmodule.modulestore.mixed import MixedModuleStore @@ -276,9 +275,6 @@ def create_modulestore_instance( else: xb_user_service = None - if 'read_preference' in doc_store_config: - doc_store_config['read_preference'] = getattr(ReadPreference, doc_store_config['read_preference']) - xblock_field_data_wrappers = [load_function(path) for path in settings.XBLOCK_FIELD_DATA_WRAPPERS] def fetch_disabled_xblock_types(): diff --git a/common/lib/xmodule/xmodule/mongo_utils.py b/common/lib/xmodule/xmodule/mongo_utils.py index a36ce5cb2a84..ea6a37c9f68d 100644 --- a/common/lib/xmodule/xmodule/mongo_utils.py +++ b/common/lib/xmodule/xmodule/mongo_utils.py @@ -4,6 +4,7 @@ import logging import pymongo +from pymongo import ReadPreference from mongodb_proxy import MongoProxy logger = logging.getLogger(__name__) # pylint: disable=invalid-name @@ -33,6 +34,13 @@ def connect_to_mongodb( # No 'replicaSet' in kwargs - so no secondary reads. mongo_client_class = pymongo.MongoClient + # If read_preference is given as a name of a valid ReadPreference. constant + # such as "SECONDARY_PREFERRED", convert it. Otherwise pass it through unchanged. + if 'read_preference' in kwargs: + read_preference = getattr(ReadPreference, kwargs['read_preference'], None) + if read_preference is not None: + kwargs['read_preference'] = read_preference + mongo_conn = pymongo.database.Database( mongo_client_class( host=host, diff --git a/common/lib/xmodule/xmodule/tests/test_mongo_utils.py b/common/lib/xmodule/xmodule/tests/test_mongo_utils.py new file mode 100644 index 000000000000..6c6116148d61 --- /dev/null +++ b/common/lib/xmodule/xmodule/tests/test_mongo_utils.py @@ -0,0 +1,38 @@ +""" +Tests for methods defined in mongo_utils.py +""" +import ddt +import os +from unittest import TestCase +from uuid import uuid4 + +from pymongo import ReadPreference + +from django.conf import settings + +from xmodule.mongo_utils import connect_to_mongodb + + +@ddt.ddt +class MongoUtilsTests(TestCase): + """ + Tests for methods exposed in mongo_utils + """ + @ddt.data( + ('PRIMARY', 'primary', ReadPreference.PRIMARY), + ('SECONDARY_PREFERRED', 'secondaryPreferred', ReadPreference.SECONDARY_PREFERRED), + ('NEAREST', 'nearest', ReadPreference.NEAREST), + ) + @ddt.unpack + def test_connect_to_mongo_read_preference(self, enum_name, mongos_name, expected_read_preference): + """ + Test that read_preference parameter gets converted to a valid pymongo read preference. + """ + host = 'edx.devstack.mongo' if 'BOK_CHOY_HOSTNAME' in os.environ else 'localhost' + db = 'test_read_preference_%s' % uuid4().hex + # Support for read_preference given in constant name form (ie. PRIMARY, SECONDARY_PREFERRED) + connection = connect_to_mongodb(db, host, read_preference=enum_name) + self.assertEqual(connection.client.read_preference, expected_read_preference) + # Support for read_preference given as mongos name. + connection = connect_to_mongodb(db, host, read_preference=mongos_name) + self.assertEqual(connection.client.read_preference, expected_read_preference)