Skip to content

Commit

Permalink
Merge branch 'develop' into User_Model
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBurchLog authored Apr 1, 2024
2 parents 181557b + 15d2bec commit e2b2929
Show file tree
Hide file tree
Showing 17 changed files with 681 additions and 15 deletions.
55 changes: 55 additions & 0 deletions .github/workflows/develop_push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Develop Push

on:
push:
branches:
- develop

jobs:

CodeCoverage:

runs-on: ${{ matrix.os }}

strategy:
matrix:
python-version: ['3.12']
os: ['ubuntu-latest']

env:
OS: ${{ matrix.os }}
PYTHON: ${{ matrix.python-version }}

name: Code Coverage OS ${{ matrix.os }} - Python ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v2

- name: Setup python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

# Need to update if we support other OS's
- name: Cache PIP Install
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-${{ matrix.python-version }}-pip-coverage-${{ hashFiles('**/setup.py') }}-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-${{ matrix.python-version }}-pip-coverage
- name: Make Deps
run: |
make deps
pip install pytest
pip install pytest-cov
- name: Generate coverage report
continue-on-error: true
run: |
coverage run --source brewtils -m pytest test --tb=no
coverage report -m
coverage xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
30 changes: 30 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
Brewtils Changelog
==================

3.25.0
------
TBD

- Added Topic and Subscriber models and related access methods to easy client

3.24.4
------
3/11/2024

- Fixed bug client passed into Plugin would not initialize the commands for Remote Plugins

3.24.3
------
3/8/2024

- Fixed bug where Self Referencing SystemClients did not support `false` as default value when not provided

3.24.2
------
3/1/24

- Fixed bug where Self Referencing SystemClients did not inspect the command properly for default parameters

3.24.1
------
2/28/2024

- Self Referencing SystemClient now supports default values provided through the Parameter annotation

3.24.0
------
2/13/2024
Expand Down
2 changes: 1 addition & 1 deletion brewtils/__version__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-

__version__ = "3.24.0"
__version__ = "3.24.4"
75 changes: 74 additions & 1 deletion brewtils/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
"Resolvable",
"Role",
"User",
"Subscriber",
"Topic",
]


Expand Down Expand Up @@ -94,8 +96,11 @@ class Events(Enum):
COMMAND_PUBLISHING_BLOCKLIST_SYNC = 48
COMMAND_PUBLISHING_BLOCKLIST_REMOVE = 49
COMMAND_PUBLISHING_BLOCKLIST_UPDATE = 50
TOPIC_CREATED = 54
TOPIC_UPDATED = 55
TOPIC_REMOVED = 56

# Next: 54
# Next: 57


class BaseModel(object):
Expand Down Expand Up @@ -1706,3 +1711,71 @@ class RemoteUserMap(BaseModel):
def __init__(self, target_garden, username):
self.target_garden = target_garden
self.username = username

class Subscriber(BaseModel):
schema = "SubscriberSchema"

def __init__(
self,
garden=None,
namespace=None,
system=None,
version=None,
instance=None,
command=None,
):
self.garden = garden
self.namespace = namespace
self.system = system
self.version = version
self.instance = instance
self.command = command

def __str__(self):
return "%s" % self.__dict__

def __repr__(self):
return (
"<Subscriber: garden=%s, namespace=%s, system=%s, version=%s, instance=%s, "
"command=%s>"
% (
self.garden,
self.namespace,
self.system,
self.version,
self.instance,
self.command,
)
)

def __eq__(self, other):
if not isinstance(other, Subscriber):
# don't attempt to compare against unrelated types
return NotImplemented

return (
self.garden == other.garden
and self.namespace == other.namespace
and self.system == other.system
and self.version == other.version
and self.instance == other.instance
and self.command == other.command
)


class Topic(BaseModel):
schema = "TopicSchema"

def __init__(self, id=None, name=None, subscribers=None): # noqa # shadows built-in
self.id = id
self.name = name
self.subscribers = subscribers or []

def __str__(self):
return "%s: %s" % (self.name, [str(s) for s in self.subscribers])

def __repr__(self):
return "<Topic: name=%s, subscribers=%s>" % (
self.name,
self.subscribers,
)
6 changes: 4 additions & 2 deletions brewtils/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,7 @@ def __init__(self, client=None, system=None, logger=None, **kwargs):
global CLIENT
# Make sure this is set after self._system
if client:
self._client = client
CLIENT = client
self._set_client(client)
else:
self._client = None

Expand Down Expand Up @@ -272,6 +271,9 @@ def client(self, new_client):
if new_client is None:
return

self._set_client(new_client)

def _set_client(self, new_client):
# Several _system properties can come from the client, so update if needed
if not self._system.name:
self._system.name = getattr(new_client, "_bg_name") # noqa
Expand Down
9 changes: 9 additions & 0 deletions brewtils/request_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import six
from requests import ConnectionError as RequestsConnectionError

from brewtils.decorators import _parse_method
import brewtils.plugin
from brewtils.errors import (
BGGivesUpError,
Expand Down Expand Up @@ -62,6 +63,14 @@ def process_command(self, request):
request.parent = Request(id=str(parent_request.id))
request.has_parent = True

# check for kwargs on the target command
command = _parse_method(getattr(brewtils.plugin.CLIENT, request.command, None))
if command:
for parameter in command.parameters:
if parameter.default is not None:
if parameter.key not in request.parameters:
request.parameters[parameter.key] = parameter.default

request.status = "IN_PROGRESS"

request = self._ez_client.put_request(request)
Expand Down
68 changes: 68 additions & 0 deletions brewtils/rest/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ def __init__(self, *args, **kwargs):
self.user_url = self.base_url + "api/v1/users/"
self.admin_url = self.base_url + "api/v1/admin/"
self.forward_url = self.base_url + "api/v1/forward"
self.topic_url = self.base_url + "api/v1/topics/"

# Deprecated
self.logging_config_url = self.base_url + "api/v1/config/logging/"
Expand Down Expand Up @@ -943,3 +944,70 @@ def get_tokens(self, username=None, password=None):
self.session.headers["Authorization"] = "Bearer " + self.access_token

return response

@enable_auth
def get_topic(self, topic_id):
# type: (str, **Any) -> Response
"""Performs a GET on the Topic URL
Args:
topic_id: Topic id
Returns:
Requests Response object
"""
return self.session.get(self.topic_url + topic_id)

@enable_auth
def get_topics(self):
# type: () -> Response
"""Perform a GET on the Topic URL
Returns:
Requests Response object
"""
return self.session.get(self.topic_url)

@enable_auth
def post_topics(self, payload):
# type: (str) -> Response
"""Performs a POST on the Topic URL
Args:
payload: New Topic definition
Returns:
Requests Response object
"""
return self.session.post(
self.topic_url, data=payload, headers=self.JSON_HEADERS
)

@enable_auth
def patch_topic(self, topic_id, payload):
# type: (str, str) -> Response
"""Performs a PATCH on a Topic URL
Args:
topic_id: Topic id
payload: Serialized PatchOperation
Returns:
Requests Response object
"""
return self.session.patch(
self.topic_url + topic_id, data=payload, headers=self.JSON_HEADERS
)

@enable_auth
def delete_topic(self, topic_id):
# type: (str) -> Response
"""Performs a DELETE on a Topic URL
Args:
topic_id: Topic id
Returns:
Requests Response object
"""
return self.session.delete(self.topic_url + topic_id)
76 changes: 76 additions & 0 deletions brewtils/rest/easy_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1154,3 +1154,79 @@ def _check_chunked_file_validity(self, file_id):
return True, metadata_json
else:
return False, metadata_json

@wrap_response(parse_method="parse_topic", parse_many=False, default_exc=FetchError)
def get_topic(self, topic_id):
"""Get a topic
Args:
topic_id: Topic id
Returns:
The Topic
"""
return self.client.get_topic(topic_id)

@wrap_response(parse_method="parse_topic", parse_many=True, default_exc=FetchError)
def get_topics(self):
"""Get all Topics
Returns:
List[Topics]: List of Topics
"""
return self.client.get_topics()

@wrap_response(parse_method="parse_topic", parse_many=False, default_exc=SaveError)
def create_topic(self, topic):
"""Create a new Topic
Args:
system (Topic): The Topic to create
Returns:
Topic: The newly-created topic
"""
return self.client.post_topics(SchemaParser.serialize_topic(topic))

@wrap_response(return_boolean=True, raise_404=True)
def remove_topic(self, topic_id):
"""Remove a unique Topic
Args:
topic_id: Topic id
Returns:
bool: True if removal was successful
Raises:
NotFoundError: Couldn't find a Topic matching given parameters
"""
return self.client.delete_topic(topic_id)

@wrap_response(parse_method="parse_topic", parse_many=False, default_exc=SaveError)
def update_topic(self, topic_id, add=None, remove=None):
"""Update a Topic
Args:
topic_id (str): The Topic ID
add (Optional[str]): Add subscriber
remove (Optional[str]): Remove subscriber
Returns:
Topic: The updated topic
"""
operations = []

if add:
operations.append(PatchOperation("add", value=add))
if remove:
operations.append(PatchOperation("remove", value=remove))

return self.client.patch_topic(
topic_id, SchemaParser.serialize_patch(operations, many=True)
)
Loading

0 comments on commit e2b2929

Please sign in to comment.