Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions intelmq/bots/collectors/stomp/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
stomp = None
else:
import stomp.exception
from packaging.version import Version

from intelmq.lib.bot import CollectorBot
from intelmq.lib.mixins import StompMixin
from intelmq.lib.mixins.stomp import StompMixin, stomp_version


if stomp is not None:
Expand All @@ -28,7 +29,7 @@ def __init__(self, n6stompcollector, conn, destination, connect_kwargs=None):
self.connect_kwargs = connect_kwargs
self.destination = destination
super().__init__()
if stomp.__version__ >= (5, 0, 0):
if stomp_version() >= Version("5.0.0"):
# set the function directly, as the argument print_to_log logs to the generic logger
self._PrintingListener__print = n6stompcollector.logger.debug

Expand Down Expand Up @@ -112,13 +113,14 @@ def init(self):
self.stomp_bot_runtime_initial_check()

# (note: older versions of `stomp.py` do not play well with reconnects)
self._auto_reconnect = (stomp.__version__ >= (4, 1, 21))
installed_version = stomp_version()
self._auto_reconnect = (installed_version >= Version("4.1.21"))

self.__conn, connect_kwargs = self.prepare_stomp_connection()
self.__conn.set_listener('', StompListener(self, self.__conn, self.exchange,
connect_kwargs=connect_kwargs))
connect_and_subscribe(self.__conn, self.logger, self.exchange,
start=stomp.__version__ < (4, 1, 20),
start=installed_version < Version("4.1.20"),
connect_kwargs=connect_kwargs)

def shutdown(self):
Expand Down
5 changes: 3 additions & 2 deletions intelmq/bots/outputs/stomp/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
import stomp
except ImportError:
stomp = None
from packaging.version import Version

from intelmq.lib.bot import OutputBot
from intelmq.lib.mixins import StompMixin
from intelmq.lib.mixins.stomp import StompMixin, stomp_version


class StompOutputBot(OutputBot, StompMixin):
Expand Down Expand Up @@ -62,7 +63,7 @@ def connect(self):
self.logger.debug('Connecting.')
# based on the documentation at:
# https://github.com/jasonrbriggs/stomp.py/wiki/Simple-Example
if stomp.__version__ < (4, 1, 20):
if stomp_version() < Version("4.1.20"):
self._conn.start()
self._conn.connect(**self._connect_kwargs)
self.logger.debug('Connected.')
Expand Down
17 changes: 15 additions & 2 deletions intelmq/lib/mixins/stomp.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import os
import ssl
import sys
from importlib.metadata import PackageNotFoundError, version
from packaging.version import Version
from typing import (
Any,
Callable,
Expand All @@ -27,6 +29,16 @@
from intelmq.lib.exceptions import MissingDependencyError


def stomp_version() -> Version:
try:
return Version(version("stomp.py"))
except PackageNotFoundError:
stomp_module_version = stomp.__version__
if isinstance(stomp_module_version, tuple):
stomp_module_version = ".".join(str(part) for part in stomp_module_version)
return Version(stomp_module_version)


class StompMixin:

"""A mixin that provides certain common methods for STOMP bots."""
Expand Down Expand Up @@ -121,9 +133,10 @@ def __verify_dependency(cls) -> None:
if stomp is None:
raise MissingDependencyError('stomp',
additional_text=cls._DEPENDENCY_NAME_REMARK)
if stomp.__version__ < (4, 1, 12):
installed_version = stomp_version()
if installed_version < Version("4.1.12"):
raise MissingDependencyError('stomp', version="4.1.12",
installed=stomp.__version__,
installed=str(installed_version),
additional_text=cls._DEPENDENCY_NAME_REMARK)

@classmethod
Expand Down
21 changes: 21 additions & 0 deletions intelmq/tests/bots/outputs/stomp/test_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@

# -*- coding: utf-8 -*-
import os
from types import SimpleNamespace
from unittest.mock import Mock

from packaging.version import Version

if os.environ.get('INTELMQ_TEST_EXOTIC'):
import intelmq.bots.outputs.stomp.output

from intelmq.bots.outputs.stomp.output import StompOutputBot


def test_connect_with_string_stomp_version(monkeypatch):
bot = StompOutputBot.__new__(StompOutputBot)
bot.logger = Mock()
bot._connect_kwargs = {"wait": True}
bot._conn = SimpleNamespace(start=Mock(), connect=Mock())

monkeypatch.setattr("intelmq.bots.outputs.stomp.output.stomp_version",
lambda: Version("8.2.0"))

bot.connect()

bot._conn.start.assert_not_called()
bot._conn.connect.assert_called_once_with(wait=True)
27 changes: 27 additions & 0 deletions intelmq/tests/lib/test_stomp_mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: 2026 BharatDeva
#
# SPDX-License-Identifier: AGPL-3.0-or-later

from types import SimpleNamespace

from importlib.metadata import PackageNotFoundError
from packaging.version import Version

import intelmq.lib.mixins.stomp as stomp


def test_stomp_version_uses_distribution_metadata(monkeypatch):
monkeypatch.setattr(stomp, "version", lambda _: "8.2.0")
monkeypatch.setattr(stomp, "stomp", SimpleNamespace(__version__=(4, 1, 12)))

assert stomp.stomp_version() == Version("8.2.0")


def test_stomp_version_falls_back_to_tuple_module_version(monkeypatch):
def missing_distribution(_):
raise PackageNotFoundError

monkeypatch.setattr(stomp, "version", missing_distribution)
monkeypatch.setattr(stomp, "stomp", SimpleNamespace(__version__=(4, 1, 12)))

assert stomp.stomp_version() == Version("4.1.12")