diff --git a/.github/workflows/pr-actions.yml b/.github/workflows/pr-actions.yml index 1b1a7a53..6477ba5c 100644 --- a/.github/workflows/pr-actions.yml +++ b/.github/workflows/pr-actions.yml @@ -37,7 +37,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ '3.8', '3.9', '3.10', '3.11','3.12'] + python-version: [ '3.8', '3.9', '3.10', '3.11'] os: ['ubuntu-latest'] name: PyTests OS ${{ matrix.os }} - Python ${{ matrix.python-version }} steps: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b09e45d2..590d5045 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,8 @@ Brewtils Changelog TBD - Added new KWARG input to @command for tag/tags. This can be utilized for filtering commands. +- Adding default topic for PublishClient to Plugins {Namespace}.{System}.{Version}.{Instance} +- Removed Python 12 support until we upgrade Marshmallow dependency to 3.15 or greater 3.21.0 ------ diff --git a/brewtils/rest/publish_client.py b/brewtils/rest/publish_client.py index f3571247..536f6adf 100644 --- a/brewtils/rest/publish_client.py +++ b/brewtils/rest/publish_client.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import logging +from brewtils.errors import BrewtilsException import brewtils.plugin from brewtils.models import Event, Events, Request from brewtils.rest.easy_client import EasyClient @@ -65,12 +66,19 @@ def __init__(self, *args, **kwargs): self._easy_client = EasyClient(*args, **kwargs) def publish( - self, _topic: str, _regex_only: bool = False, _propagate: bool = False, **kwargs + self, + _topic: str = None, + _regex_only: bool = False, + _propagate: bool = False, + **kwargs, ) -> bool: """Publishes event containing Request to be processed + Topic is added to request.metadata["_topic"] + Args: - _topic (str): The topic to publish to + _topic (str): The topic to publish to, default is Plugin level topic + {Namespace}.{System}.{Version}.{Instance} _regex_only (bool): If the request will be resolved against only annotated topics from the @subscribe command _propagate (bool): If the request will be pushed up to the parent to be resolved. @@ -79,6 +87,22 @@ def publish( """ + if _topic is None: + if ( + brewtils.plugin.CONFIG.name + and brewtils.plugin.CONFIG.version + and brewtils.plugin.CONFIG.instance_name + and brewtils.plugin.CONFIG.namespace + ): + _topic = "{0}.{1}.{2}.{3}".format( + brewtils.plugin.CONFIG.namespace, + brewtils.plugin.CONFIG.name, + brewtils.plugin.CONFIG.version, + brewtils.plugin.CONFIG.instance_name, + ) + else: + raise BrewtilsException("Unable to determine _topic to publish to") + comment = kwargs.pop("_comment", None) output_type = kwargs.pop("_output_type", None) metadata = kwargs.pop("_metadata", {}) diff --git a/test/rest/publish_client_test.py b/test/rest/publish_client_test.py new file mode 100644 index 00000000..14a43842 --- /dev/null +++ b/test/rest/publish_client_test.py @@ -0,0 +1,79 @@ +import pytest +from mock import Mock + +import brewtils.rest +from brewtils.errors import BrewtilsException +from brewtils.models import Event, Events, Request +from brewtils.rest.publish_client import PublishClient +from brewtils.schema_parser import SchemaParser + + +@pytest.fixture(autouse=True) +def easy_client(monkeypatch): + mock = Mock(name="easy_client") + mock.publish_event.return_value = True + + monkeypatch.setattr( + brewtils.rest.publish_client, "EasyClient", Mock(return_value=mock) + ) + + return mock + + +@pytest.fixture +def client(): + return PublishClient(bg_host="localhost", bg_port=3000) + + +class TestPublishClient(object): + def setup_config(self): + brewtils.plugin.CONFIG.namespace = "foo" + brewtils.plugin.CONFIG.name = "foo" + brewtils.plugin.CONFIG.version = "1.0.0" + brewtils.plugin.CONFIG.instance_name = "foo" + brewtils.plugin.CONFIG.bg_host = "localhost" + brewtils.plugin.CONFIG.bg_port = "3000" + + def test_publish(self, client): + assert client.publish(_topic="topic") + + def test_missing_topic(self, client): + with pytest.raises(BrewtilsException): + assert client.publish(not_topic="topic") + + def test_missing_topic_found(self, client, easy_client): + self.setup_config() + assert client.publish(no_topic="topic") + + easy_client.publish_event.assert_called() + called_event = easy_client.publish_event.call_args.args[0] + + assert called_event.metadata["topic"] == "foo.foo.1.0.0.foo" + + def test_verify_generated_request(self, client, easy_client): + assert client.publish( + _topic="topic", _comment="_comment", _parent=None, value="test" + ) + + event = Event( + name=Events.REQUEST_TOPIC_PUBLISH.name, + metadata={ + "topic": "topic", + "propagate": False, + "regex_only": False, + }, + payload=Request( + comment="_comment", + output_type=None, + parent=None, + metadata={"_topic": "topic"}, + parameters={"value": "test"}, + ), + payload_type="Request", + ) + + easy_client.publish_event.assert_called() + called_event = easy_client.publish_event.call_args.args[0] + assert SchemaParser.serialize_event( + called_event + ) == SchemaParser.serialize_event(event)