Exemple #1
0
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
Exemple #2
0
    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}
Exemple #3
0
 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)
Exemple #4
0
 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)
Exemple #5
0
 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))