refactor: move xmodule folder to root
- Moving xmodule folder to root as we're dissolving sub-projects of common folder in edx-platform
- More info: https://openedx.atlassian.net/browse/BOM-2579
- -e common/lib/xmodule has been removed from the requirements as xmodule has itself become the part of edx-platform and not being installed through requirements
- The test files common/lib/xmodule/test_files/ have been removed as they are not being used anymore
This commit is contained in:
104
xmodule/mongo_utils.py
Normal file
104
xmodule/mongo_utils.py
Normal file
@@ -0,0 +1,104 @@
|
||||
"""
|
||||
Common MongoDB connection functions.
|
||||
"""
|
||||
|
||||
|
||||
import logging
|
||||
|
||||
import pymongo
|
||||
from mongodb_proxy import MongoProxy
|
||||
from pymongo.read_preferences import ( # lint-amnesty, pylint: disable=unused-import
|
||||
ReadPreference,
|
||||
_MONGOS_MODES,
|
||||
_MODES
|
||||
)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
|
||||
|
||||
# This will yeld a map of all available Mongo modes and their name
|
||||
MONGO_READ_PREFERENCE_MAP = dict(zip(_MONGOS_MODES, _MODES))
|
||||
|
||||
|
||||
def connect_to_mongodb(
|
||||
db, host,
|
||||
port=27017, tz_aware=True, user=None, password=None,
|
||||
retry_wait_time=0.1, proxy=True, **kwargs
|
||||
):
|
||||
"""
|
||||
Returns a MongoDB Database connection, optionally wrapped in a proxy. The proxy
|
||||
handles AutoReconnect errors by retrying read operations, since these exceptions
|
||||
typically indicate a temporary step-down condition for MongoDB.
|
||||
"""
|
||||
# If the MongoDB server uses a separate authentication database that should be specified here
|
||||
auth_source = kwargs.get('authsource', '') or None
|
||||
|
||||
# sanitize a kwarg which may be present and is no longer expected
|
||||
# AED 2020-03-02 TODO: Remove this when 'auth_source' will no longer exist in kwargs
|
||||
if 'auth_source' in kwargs:
|
||||
kwargs.pop('auth_source')
|
||||
|
||||
# If read_preference is given as a name of a valid ReadPreference.<NAME>
|
||||
# constant such as "SECONDARY_PREFERRED" or a mongo mode such as
|
||||
# "secondaryPreferred", convert it. Otherwise pass it through unchanged.
|
||||
if 'read_preference' in kwargs:
|
||||
read_preference = MONGO_READ_PREFERENCE_MAP.get(
|
||||
kwargs['read_preference'],
|
||||
kwargs['read_preference']
|
||||
)
|
||||
|
||||
read_preference = getattr(ReadPreference, read_preference, None)
|
||||
if read_preference is not None:
|
||||
kwargs['read_preference'] = read_preference
|
||||
|
||||
mongo_conn = pymongo.database.Database(
|
||||
pymongo.MongoClient(
|
||||
host=host,
|
||||
port=port,
|
||||
tz_aware=tz_aware,
|
||||
document_class=dict,
|
||||
**kwargs
|
||||
),
|
||||
db
|
||||
)
|
||||
|
||||
if proxy:
|
||||
mongo_conn = MongoProxy(
|
||||
mongo_conn,
|
||||
wait_time=retry_wait_time
|
||||
)
|
||||
# If credentials were provided, authenticate the user.
|
||||
if user is not None and password is not None:
|
||||
mongo_conn.authenticate(user, password, source=auth_source)
|
||||
|
||||
return mongo_conn
|
||||
|
||||
|
||||
def create_collection_index(
|
||||
collection, keys,
|
||||
ignore_created=True, ignore_created_opts=True, **kwargs
|
||||
):
|
||||
"""
|
||||
Create a MongoDB index in a collection. Optionally,
|
||||
ignore errors related to the index already existing.
|
||||
"""
|
||||
# For an explanation of the error codes:
|
||||
# https://github.com/mongodb/mongo/blob/v3.0/src/mongo/db/catalog/index_catalog.cpp#L542-L583
|
||||
# https://github.com/mongodb/mongo/blob/v3.0/src/mongo/base/error_codes.err#L70-L87
|
||||
# pylint: disable=invalid-name
|
||||
INDEX_ALREADY_EXISTS = 68
|
||||
INDEX_OPTIONS_CONFLICT = 85
|
||||
try:
|
||||
collection.create_index(keys, **kwargs)
|
||||
except pymongo.errors.OperationFailure as exc:
|
||||
errors_to_ignore = []
|
||||
if ignore_created:
|
||||
errors_to_ignore.append(INDEX_ALREADY_EXISTS)
|
||||
if ignore_created_opts:
|
||||
errors_to_ignore.append(INDEX_OPTIONS_CONFLICT)
|
||||
if exc.code in errors_to_ignore:
|
||||
logger.warning("Existing index in collection '{}' remained unchanged!: {}".format(
|
||||
collection.full_name, exc.details['errmsg'])
|
||||
)
|
||||
else:
|
||||
raise exc
|
||||
Reference in New Issue
Block a user