@@ -247,23 +247,57 @@ def close(self):
247247
248248
249249class _Encrypter (object ):
250- def __init__ (self , io_callbacks , opts ):
251- """Encrypts and decrypts MongoDB commands.
250+ """Encrypts and decrypts MongoDB commands.
252251
253- This class is used to support automatic encryption and decryption of
254- MongoDB commands.
252+ This class is used to support automatic encryption and decryption of
253+ MongoDB commands."""
254+ def __init__ (self , client , opts ):
255+ """Create a _Encrypter for a client.
255256
256257 :Parameters:
257- - `io_callbacks `: A :class:`MongoCryptCallback` .
258+ - `client `: The encrypted MongoClient .
258259 - `opts`: The encrypted client's :class:`AutoEncryptionOpts`.
259260 """
260261 if opts ._schema_map is None :
261262 schema_map = None
262263 else :
263264 schema_map = _dict_to_bson (opts ._schema_map , False , _DATA_KEY_OPTS )
265+ self ._bypass_auto_encryption = opts ._bypass_auto_encryption
266+ self ._internal_client = None
267+
268+ def _get_internal_client (encrypter , mongo_client ):
269+ if mongo_client .max_pool_size is None :
270+ # Unlimited pool size, use the same client.
271+ return mongo_client
272+ # Else - limited pool size, use an internal client.
273+ if encrypter ._internal_client is not None :
274+ return encrypter ._internal_client
275+ internal_client = mongo_client ._duplicate (
276+ minPoolSize = 0 , auto_encryption_opts = None )
277+ encrypter ._internal_client = internal_client
278+ return internal_client
279+
280+ if opts ._key_vault_client is not None :
281+ key_vault_client = opts ._key_vault_client
282+ else :
283+ key_vault_client = _get_internal_client (self , client )
284+
285+ if opts ._bypass_auto_encryption :
286+ metadata_client = None
287+ else :
288+ metadata_client = _get_internal_client (self , client )
289+
290+ db , coll = opts ._key_vault_namespace .split ('.' , 1 )
291+ key_vault_coll = key_vault_client [db ][coll ]
292+
293+ mongocryptd_client = MongoClient (
294+ opts ._mongocryptd_uri , connect = False ,
295+ serverSelectionTimeoutMS = _MONGOCRYPTD_TIMEOUT_MS )
296+
297+ io_callbacks = _EncryptionIO (
298+ metadata_client , key_vault_coll , mongocryptd_client , opts )
264299 self ._auto_encrypter = AutoEncrypter (io_callbacks , MongoCryptOptions (
265300 opts ._kms_providers , schema_map ))
266- self ._bypass_auto_encryption = opts ._bypass_auto_encryption
267301 self ._closed = False
268302
269303 def encrypt (self , database , cmd , check_keys , codec_options ):
@@ -313,29 +347,9 @@ def close(self):
313347 """Cleanup resources."""
314348 self ._closed = True
315349 self ._auto_encrypter .close ()
316-
317- @staticmethod
318- def create (client , opts ):
319- """Create a _CommandEncyptor for a client.
320-
321- :Parameters:
322- - `client`: The encrypted MongoClient.
323- - `opts`: The encrypted client's :class:`AutoEncryptionOpts`.
324-
325- :Returns:
326- A :class:`_CommandEncrypter` for this client.
327- """
328- key_vault_client = opts ._key_vault_client or client
329- db , coll = opts ._key_vault_namespace .split ('.' , 1 )
330- key_vault_coll = key_vault_client [db ][coll ]
331-
332- mongocryptd_client = MongoClient (
333- opts ._mongocryptd_uri , connect = False ,
334- serverSelectionTimeoutMS = _MONGOCRYPTD_TIMEOUT_MS )
335-
336- io_callbacks = _EncryptionIO (
337- client , key_vault_coll , mongocryptd_client , opts )
338- return _Encrypter (io_callbacks , opts )
350+ if self ._internal_client :
351+ self ._internal_client .close ()
352+ self ._internal_client = None
339353
340354
341355class Algorithm (object ):
0 commit comments