Skip to content
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

Add support for mongodb+srv scheme #1976

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

H4ad
Copy link

@H4ad H4ad commented Apr 3, 2024

If we try run kombu with scheme mongodb+srv, it will break during URL parsing.

Fixes: #1786
Fixes: #858

Copy link
Member

@auvipy auvipy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please add some tests for the changes?

@H4ad
Copy link
Author

H4ad commented May 6, 2024

@auvipy Unless you have a valid connection using mongodb+srv, I don't think is possible to add tests due to how this scheme is resolved using DNS.

@Nusnus
Copy link
Member

Nusnus commented Jun 3, 2024

@auvipy Unless you have a valid connection using mongodb+srv, I don't think is possible to add tests due to how this scheme is resolved using DNS.

I understand - would it be ok to ask for you to do some manual testing and at least share here the logs so we can have at least a minimal confirmation of it working?

P.S
From a quick review it appears to be ok, but I’d want at least something to hold on to if we can’t add automatic testing 🙏

@Nusnus Nusnus force-pushed the feat/support-for-mongo-srv branch from c6d0ee9 to a89072c Compare June 3, 2024 23:11
@Nusnus Nusnus self-requested a review June 3, 2024 23:31
@H4ad
Copy link
Author

H4ad commented Jun 4, 2024

I did a monkey-patch on my code to use this change, I've been using since I opened this PR, this is the logs from yesterday:

Screenshot from 2024-06-04 09-47-47

My monkey patch code is basically this:

from kombu.transport.mongodb import Channel
from pymongo import uri_parser


def monkey_patch_channel_parse_uri(self, scheme="mongodb://"):
    # See mongodb uri documentation:
    # https://docs.mongodb.org/manual/reference/connection-string/
    client = self.connection.client
    hostname = client.hostname

    if hostname.startswith("srv://"):
        scheme = "mongodb+srv://"
        hostname = "mongodb+" + hostname
        client.hostname = hostname

    if not hostname.startswith(scheme):
        hostname = scheme + hostname

    if not hostname[len(scheme) :]:
        hostname += self.default_hostname

    if client.userid and "@" not in hostname:
        head, tail = hostname.split("://")

        credentials = client.userid
        if client.password:
            credentials += ":" + client.password

        hostname = head + "://" + credentials + "@" + tail

    port = client.port if client.port else self.default_port

    parsed = uri_parser.parse_uri(hostname, port)

    dbname = parsed["database"] or client.virtual_host

    if dbname in ("/", None):
        dbname = self.default_database

    options = {
        "auto_start_request": True,
        "ssl": self.ssl,
        "connectTimeoutMS": (
            int(self.connect_timeout * 1000) if self.connect_timeout else None
        ),
    }
    options.update(parsed["options"])
    options = self._prepare_client_options(options)

    if "tls" in options:
        options.pop("ssl")

    return hostname, dbname, options


def apply_kombu_monkey_patch():
    Channel._parse_uri = monkey_patch_channel_parse_uri

@Nusnus
Copy link
Member

Nusnus commented Jun 4, 2024

@H4ad Thank you! Much appreciated!

I did a monkey-patch on my code to use this change, I've been using since I opened this PR, this is the logs from yesterday:

Screenshot from 2024-06-04 09-47-47

My monkey patch code is basically this:

from kombu.transport.mongodb import Channel
from pymongo import uri_parser


def monkey_patch_channel_parse_uri(self, scheme="mongodb://"):
    # See mongodb uri documentation:
    # https://docs.mongodb.org/manual/reference/connection-string/
    client = self.connection.client
    hostname = client.hostname

    if hostname.startswith("srv://"):
        scheme = "mongodb+srv://"
        hostname = "mongodb+" + hostname
        client.hostname = hostname

    if not hostname.startswith(scheme):
        hostname = scheme + hostname

    if not hostname[len(scheme) :]:
        hostname += self.default_hostname

    if client.userid and "@" not in hostname:
        head, tail = hostname.split("://")

        credentials = client.userid
        if client.password:
            credentials += ":" + client.password

        hostname = head + "://" + credentials + "@" + tail

    port = client.port if client.port else self.default_port

    parsed = uri_parser.parse_uri(hostname, port)

    dbname = parsed["database"] or client.virtual_host

    if dbname in ("/", None):
        dbname = self.default_database

    options = {
        "auto_start_request": True,
        "ssl": self.ssl,
        "connectTimeoutMS": (
            int(self.connect_timeout * 1000) if self.connect_timeout else None
        ),
    }
    options.update(parsed["options"])
    options = self._prepare_client_options(options)

    if "tls" in options:
        options.pop("ssl")

    return hostname, dbname, options


def apply_kombu_monkey_patch():
    Channel._parse_uri = monkey_patch_channel_parse_uri

@auvipy I know you asked for tests, but I think this proves that it at least does what it is supposed to, in addition to also reviewing the code itself (which makes sense to me as-is).

I think we can go through and come back if someone reports an issue - what do you say?

Copy link
Member

@Nusnus Nusnus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM then. We’ll wait for @auvipy to review it as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants