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. """ # The MongoReplicaSetClient class is deprecated in Mongo 3.x, in favor of using # the MongoClient class for all connections. Update/simplify this code when using # PyMongo 3.x. if kwargs.get('replicaSet'): # Enable reading from secondary nodes in the MongoDB replicaset by using the # MongoReplicaSetClient class. # The 'replicaSet' parameter in kwargs is required for secondary reads. # The read_preference should be set to a proper value, like SECONDARY_PREFERRED. mongo_client_class = pymongo.MongoReplicaSetClient else: # No 'replicaSet' in kwargs - so no secondary reads. mongo_client_class = pymongo.MongoClient # 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( mongo_client_class(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 __init__(self, db, collection, host, port=27017, tz_aware=True, user=None, password=None, asset_collection=None, retry_wait_time=0.1, **kwargs): """ Create & open the connection, authenticate, and provide pointers to the collections """ self.database = MongoProxy(pymongo.database.Database( pymongo.MongoClient(host=host, port=port, tz_aware=tz_aware, **kwargs), db), wait_time=retry_wait_time) if user is not None and password is not None: self.database.authenticate(user, password) self.course_index = self.database[collection + '.active_versions'] self.structures = self.database[collection + '.structures'] self.definitions = self.database[collection + '.definitions'] # every app has write access to the db (v having a flag to indicate r/o v write) # Force mongo to report errors, at the expense of performance # pymongo docs suck but explanation: # http://api.mongodb.org/java/2.10.1/com/mongodb/WriteConcern.html self.course_index.write_concern = {'w': 1} self.structures.write_concern = {'w': 1} self.definitions.write_concern = {'w': 1}
def test_no_exceptions1(self): mongo_connection = MongoProxy( MongoConnection(), methods_needing_retry={MongoConnection: [ 'find', ]}) self.assertEqual(mongo_connection.find(), "Finished.") self.assertEqual(mongo_connection.call_count, 1)
def test_exceptions2(self): mongo_connection = MongoProxy( MongoConnection( exceptions_to_raise=[AutoReconnect, AutoReconnect]), methods_needing_retry={MongoConnection: [ 'find', ]}) self.assertEqual(mongo_connection.find(), "Finished.") self.assertEqual(mongo_connection.call_count, 3)
def test_exceptions1(self): mongo_connection = MongoProxy( MongoConnection(exceptions_to_raise=[ValueError]), methods_needing_retry={MongoConnection: [ 'find', ]}) with self.assertRaises(ValueError): mongo_connection.find() self.assertEqual(mongo_connection.call_count, 1)
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. """ # The MongoReplicaSetClient class is deprecated in Mongo 3.x, in favor of using # the MongoClient class for all connections. Update/simplify this code when using # PyMongo 3.x. if kwargs.get('replicaSet'): # Enable reading from secondary nodes in the MongoDB replicaset by using the # MongoReplicaSetClient class. # The 'replicaSet' parameter in kwargs is required for secondary reads. # The read_preference should be set to a proper value, like SECONDARY_PREFERRED. mongo_client_class = pymongo.MongoReplicaSetClient else: # 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.<NAME> 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, 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) return mongo_conn
def _connect_replica_set(self): return MongoProxy( pymongo.MongoReplicaSetClient(self.mongo_uri, self._replicaSet))
def _connect_server(self): return MongoProxy(pymongo.MongoClient(self.mongo_uri))