-
Notifications
You must be signed in to change notification settings - Fork 1.1k
PYTHON-2823 Allow custom service names with srvServiceName URI option #749
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 30 commits
4f4ce7f
9a89ed4
ef4db92
d88f1eb
fcaf49b
3e63bd5
029f222
9fdfb38
944786e
90466a4
1b48a20
459f5e7
be53d49
4a8b1d0
94e44c2
9c93a7a
ce2f48b
ad366dd
241e105
f415705
70dcb1f
c148364
57c19be
d3b210f
ec58a75
2cbd7ce
891446b
f54b120
e5c7e9d
b9dc33a
8a31961
e593759
edec74e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -201,7 +201,6 @@ def __init__( | |
| and decoding of custom types. | ||
|
|
||
| | **Other optional parameters can be passed as keyword arguments:** | ||
|
|
||
| - `directConnection` (optional): if ``True``, forces this client to | ||
ShaneHarvey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| connect directly to the specified MongoDB host as a standalone. | ||
| If ``false``, the client connects to the entire replica set of | ||
|
|
@@ -333,6 +332,10 @@ def __init__( | |
| a Unicode-related error occurs during BSON decoding that would | ||
| otherwise raise :exc:`UnicodeDecodeError`. Valid options include | ||
| 'strict', 'replace', and 'ignore'. Defaults to 'strict'. | ||
| - `srvServiceName`: A custom SRV service name. Use it like so:: | ||
|
||
|
|
||
| MongoClient("mongodb+srv://example.com/?srvServiceName=customname") | ||
|
|
||
|
|
||
| | **Write Concern options:** | ||
| | (Only set if passed. No default values.) | ||
|
|
@@ -503,6 +506,7 @@ def __init__( | |
| arguments. | ||
| The default for `uuidRepresentation` was changed from | ||
| ``pythonLegacy`` to ``unspecified``. | ||
| Added the ``srvServiceName`` URI and keyword argument. | ||
|
|
||
| .. versionchanged:: 3.12 | ||
| Added the ``server_api`` keyword argument. | ||
|
|
@@ -648,6 +652,8 @@ def __init__( | |
| dbase = None | ||
| opts = common._CaseInsensitiveDictionary() | ||
| fqdn = None | ||
| srv_service_name = keyword_opts.get("srvservicename", None) | ||
|
|
||
| for entity in host: | ||
| # A hostname can only include a-z, 0-9, '-' and '.'. If we find a '/' | ||
| # it must be a URI, | ||
|
|
@@ -660,7 +666,7 @@ def __init__( | |
| keyword_opts.cased_key("connecttimeoutms"), timeout) | ||
| res = uri_parser.parse_uri( | ||
| entity, port, validate=True, warn=True, normalize=False, | ||
| connect_timeout=timeout) | ||
| connect_timeout=timeout, srv_service_name=srv_service_name) | ||
| seeds.update(res["nodelist"]) | ||
| username = res["username"] or username | ||
| password = res["password"] or password | ||
|
|
@@ -690,6 +696,10 @@ def __init__( | |
|
|
||
| # Override connection string options with kwarg options. | ||
| opts.update(keyword_opts) | ||
|
|
||
| if srv_service_name is None: | ||
| srv_service_name = opts.get("srvServiceName", common.SRV_SERVICE_NAME) | ||
|
|
||
| # Handle security-option conflicts in combined options. | ||
| opts = _handle_security_options(opts) | ||
| # Normalize combined options. | ||
|
|
@@ -730,6 +740,7 @@ def __init__( | |
| server_selector=options.server_selector, | ||
| heartbeat_frequency=options.heartbeat_frequency, | ||
| fqdn=fqdn, | ||
| srv_service_name=srv_service_name, | ||
ShaneHarvey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| direct_connection=options.direct_connection, | ||
| load_balanced=options.load_balanced, | ||
| ) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ | |
| from urllib.parse import unquote_plus | ||
|
|
||
| from pymongo.common import ( | ||
| SRV_SERVICE_NAME, | ||
| get_validated_options, INTERNAL_URI_OPTION_NAME_MAP, | ||
| URI_OPTIONS_DEPRECATION_MAP, _CaseInsensitiveDictionary) | ||
| from pymongo.errors import ConfigurationError, InvalidURI | ||
|
|
@@ -373,7 +374,7 @@ def _check_options(nodes, options): | |
|
|
||
|
|
||
| def parse_uri(uri, default_port=DEFAULT_PORT, validate=True, warn=False, | ||
| normalize=True, connect_timeout=None): | ||
| normalize=True, connect_timeout=None, srv_service_name=None): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please update the docstring below to reflect the new srv_service_name param. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| """Parse and validate a MongoDB URI. | ||
|
|
||
| Returns a dict of the form:: | ||
|
|
@@ -468,6 +469,9 @@ def parse_uri(uri, default_port=DEFAULT_PORT, validate=True, warn=False, | |
| if opts: | ||
| options.update(split_options(opts, validate, warn, normalize)) | ||
|
|
||
| if srv_service_name is None: | ||
| srv_service_name = options.get("srvServiceName", SRV_SERVICE_NAME) | ||
|
|
||
| if '@' in host_part: | ||
| userinfo, _, hosts = host_part.rpartition('@') | ||
| user, passwd = parse_userinfo(userinfo) | ||
|
|
@@ -499,7 +503,7 @@ def parse_uri(uri, default_port=DEFAULT_PORT, validate=True, warn=False, | |
| # Use the connection timeout. connectTimeoutMS passed as a keyword | ||
| # argument overrides the same option passed in the connection string. | ||
| connect_timeout = connect_timeout or options.get("connectTimeoutMS") | ||
| dns_resolver = _SrvResolver(fqdn, connect_timeout=connect_timeout) | ||
| dns_resolver = _SrvResolver(fqdn, connect_timeout, srv_service_name) | ||
| nodes = dns_resolver.get_hosts() | ||
| dns_options = dns_resolver.get_options() | ||
| if dns_options: | ||
|
|
@@ -514,6 +518,9 @@ def parse_uri(uri, default_port=DEFAULT_PORT, validate=True, warn=False, | |
| options[opt] = val | ||
| if "tls" not in options and "ssl" not in options: | ||
| options["tls"] = True if validate else 'true' | ||
| elif not is_srv and options.get("srvServiceName") is not None: | ||
| raise ConfigurationError("The srvServiceName option is only allowed " | ||
| "with 'mongodb+srv://' URIs") | ||
| else: | ||
| nodes = split_hosts(hosts, default_port=default_port) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "uri": "mongodb+srv://test4.test.build.10gen.cc/?loadBalanced=true", | ||
| "seeds": [], | ||
| "hosts": [], | ||
| "error": true, | ||
| "comment": "Should fail because no SRV records are present for this URI." | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| { | ||
| "uri": "mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname", | ||
| "seeds": [ | ||
| "localhost.test.build.10gen.cc:27017", | ||
| "localhost.test.build.10gen.cc:27018" | ||
| ], | ||
| "hosts": [ | ||
| "localhost:27017", | ||
| "localhost:27018", | ||
| "localhost:27019" | ||
| ], | ||
| "options": { | ||
| "ssl": true, | ||
| "srvServiceName": "customname" | ||
ShaneHarvey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1601,6 +1601,19 @@ def test_network_error_message(self): | |
| with self.assertRaisesRegex(AutoReconnect, expected): | ||
| client.pymongo_test.test.find_one({}) | ||
|
|
||
| def test_service_name_from_kwargs(self): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| client = MongoClient( | ||
| 'mongodb+srv://user:[email protected]', | ||
| srvServiceName='customname', connect=False) | ||
| self.assertEqual(client._topology_settings._srv_service_name, | ||
| 'customname') | ||
| client = MongoClient( | ||
| 'mongodb+srv://user:[email protected]' | ||
| '/?srvServiceName=customname', | ||
| connect=False) | ||
| self.assertEqual(client._topology_settings._srv_service_name, | ||
| 'customname') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need a test which actually checks that the kwarg overrides the URI. Like this: client = MongoClient(
'mongodb+srv://user:[email protected]'
'/?srvServiceName=shouldBeOverridden',
srvServiceName='customname',
connect=False)
self.assertEqual(client._topology_settings._srv_service_name,
'customname')There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
|
||
|
|
||
| class TestExhaustCursor(IntegrationTest): | ||
| """Test that clients properly handle errors from exhaust cursors.""" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| { | ||
| "tests": [ | ||
| { | ||
| "description": "SRV URI with custom srvServiceName", | ||
| "uri": "mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname", | ||
| "valid": true, | ||
| "warning": false, | ||
| "hosts": null, | ||
| "auth": null, | ||
| "options": { | ||
| "srvServiceName": "customname" | ||
ShaneHarvey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| }, | ||
| { | ||
| "description": "Non-SRV URI with custom srvServiceName", | ||
| "uri": "mongodb://example.com/?srvServiceName=customname", | ||
| "valid": false, | ||
| "warning": true, | ||
| "hosts": null, | ||
| "auth": null, | ||
| "options": {} | ||
| } | ||
| ] | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please undo this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.