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

Reworking Garden Models #441

Merged
merged 21 commits into from
Feb 12, 2024
Merged
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
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Brewtils Changelog
==================

3.24.0
------
TBD

- Expanding Garden model to include children gardens
- Added Source/Target Garden labels on Request model
- Added Metadata to Garden model

3.23.1
------
TBD
Expand Down Expand Up @@ -28,6 +36,7 @@ TBD
- 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
------
11/16/2023
Expand Down
79 changes: 75 additions & 4 deletions brewtils/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"System",
"Instance",
"Command",
"Connection",
"Parameter",
"Request",
"PatchOperation",
Expand Down Expand Up @@ -64,6 +65,7 @@ class Events(Enum):
DB_UPDATE = 17
DB_DELETE = 18
GARDEN_CREATED = 19
GARDEN_CONFIGURED = 53
GARDEN_UPDATED = 20
GARDEN_REMOVED = 21
FILE_CREATED = 24
Expand Down Expand Up @@ -93,7 +95,7 @@ class Events(Enum):
COMMAND_PUBLISHING_BLOCKLIST_REMOVE = 49
COMMAND_PUBLISHING_BLOCKLIST_UPDATE = 50

# Next: 53
# Next: 54


class BaseModel(object):
Expand Down Expand Up @@ -655,6 +657,8 @@ def __init__(
status_updated_at=None,
has_parent=None,
requester=None,
source_garden=None,
target_garden=None,
):
super(Request, self).__init__(
system=system,
Expand All @@ -681,6 +685,8 @@ def __init__(
self.error_class = error_class
self.has_parent = has_parent
self.requester = requester
self.source_garden = source_garden
self.target_garden = target_garden

@classmethod
def from_template(cls, template, **kwargs):
Expand Down Expand Up @@ -1433,6 +1439,7 @@ class Garden(BaseModel):
"BLOCKED",
"STOPPED",
"NOT_CONFIGURED",
"CONFIGURATION_ERROR",
"UNREACHABLE",
"ERROR",
"UNKNOWN",
Expand All @@ -1447,7 +1454,12 @@ def __init__(
namespaces=None,
systems=None,
connection_type=None,
connection_params=None,
receiving_connections=None,
publishing_connections=None,
has_parent=None,
parent=None,
children=None,
metadata=None,
):
self.id = id
self.name = name
Expand All @@ -1457,13 +1469,70 @@ def __init__(
self.systems = systems or []

self.connection_type = connection_type
self.connection_params = connection_params
self.receiving_connections = receiving_connections or []
self.publishing_connections = publishing_connections or []

self.has_parent = has_parent
self.parent = parent
self.children = children
self.metadata = metadata or {}

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

def __repr__(self):
return "<Garden: garden_name=%s, status=%s>" % (self.name, self.status)
return (
"<Garden: garden_name=%s, status=%s, parent=%s, has_parent=%s, "
"connection_type=%s, receiving_connections=%s, publishing_connections=%s>"
% (
self.name,
self.status,
self.parent,
self.has_parent,
self.connection_type,
self.receiving_connections,
self.publishing_connections,
)
)


class Connection(BaseModel):
schema = "ConnectionSchema"

CONNECTION_STATUSES = {
"PUBLISHING",
"RECEIVING",
"DISABLED" # Stopped via config or API
"NOT_CONFIGURED", # Not enabled in configuration file
"MISSING_CONFIGURATION", # Missing configuration file
"CONFIGURATION_ERROR", # Unable to load configuration file
"UNREACHABLE", # Unable to send message
"UNRESPONSIVE", # Haven't seen a message in N timeframe
"ERROR", # Error occured, outside of unreachable
"UNKNOWN",
}

def __init__(
self,
api=None,
status=None,
status_info=None,
config=None,
):
self.api = api
self.status = status
self.status_info = status_info or {}
self.config = config or {}

def __str__(self):
return "%s %s" % (self.api, self.status)

def __repr__(self):
return "<Connection: api=%s, status=%s, config=%s>" % (
self.api,
self.status,
self.config,
)


class Operation(BaseModel):
Expand All @@ -1477,6 +1546,7 @@ def __init__(
kwargs=None,
target_garden_name=None,
source_garden_name=None,
source_api=None,
operation_type=None,
):
self.model = model
Expand All @@ -1485,6 +1555,7 @@ def __init__(
self.kwargs = kwargs or {}
self.target_garden_name = target_garden_name
self.source_garden_name = source_garden_name
self.source_api = source_api
self.operation_type = operation_type

def __str__(self):
Expand Down
37 changes: 37 additions & 0 deletions brewtils/schema_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class SchemaParser(object):
_models = {
"ChoicesSchema": brewtils.models.Choices,
"CommandSchema": brewtils.models.Command,
"ConnectionSchema": brewtils.models.Connection,
"CronTriggerSchema": brewtils.models.CronTrigger,
"DateTriggerSchema": brewtils.models.DateTrigger,
"EventSchema": brewtils.models.Event,
Expand Down Expand Up @@ -102,6 +103,22 @@ def parse_command(cls, command, from_string=False, **kwargs):
command, brewtils.models.Command, from_string=from_string, **kwargs
)

@classmethod
def parse_connection(cls, connection, from_string=False, **kwargs):
"""Convert raw JSON string or dictionary to a command model object

Args:
connection: The raw input
from_string: True if input is a JSON string, False if a dictionary
**kwargs: Additional parameters to be passed to the Schema (e.g. many=True)

Returns:
A Command object
"""
return cls.parse(
connection, brewtils.models.Connection, from_string=from_string, **kwargs
)

@classmethod
def parse_parameter(cls, parameter, from_string=False, **kwargs):
"""Convert raw JSON string or dictionary to a parameter model object
Expand Down Expand Up @@ -496,6 +513,26 @@ def serialize_command(cls, command, to_string=True, **kwargs):
**kwargs
)

@classmethod
def serialize_connection(cls, connection, to_string=True, **kwargs):
"""Convert a connection model into serialized form

Args:
connection: The connection object(s) to be serialized
to_string: True to generate a JSON-formatted string, False to generate a
dictionary
**kwargs: Additional parameters to be passed to the Schema (e.g. many=True)

Returns:
Serialized representation of connection
"""
return cls.serialize(
connection,
to_string=to_string,
schema_name=brewtils.models.Connection.schema,
**kwargs
)

@classmethod
def serialize_parameter(cls, parameter, to_string=True, **kwargs):
"""Convert a parameter model into serialized form
Expand Down
26 changes: 25 additions & 1 deletion brewtils/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"IntervalTriggerSchema",
"CronTriggerSchema",
"FileTriggerSchema",
"ConnectionSchema",
"GardenSchema",
"OperationSchema",
"UserSchema",
Expand Down Expand Up @@ -348,6 +349,8 @@ class RequestSchema(RequestTemplateSchema):
)
has_parent = fields.Bool(allow_none=True)
requester = fields.String(allow_none=True)
source_garden = fields.String(allow_none=True)
target_garden = fields.String(allow_none=True)


class StatusInfoSchema(BaseSchema):
Expand Down Expand Up @@ -486,15 +489,33 @@ class FileTriggerSchema(BaseSchema):
callbacks = fields.Dict(fields.Bool(), allow_none=True)


class ConnectionSchema(BaseSchema):
api = fields.Str(allow_none=True)
status = fields.Str(allow_none=True)
status_info = fields.Nested("StatusInfoSchema", allow_none=True)
config = fields.Dict(allow_none=True)


class GardenSchema(BaseSchema):
id = fields.Str(allow_none=True)
name = fields.Str(allow_none=True)
status = fields.Str(allow_none=True)
status_info = fields.Nested("StatusInfoSchema", allow_none=True)
connection_type = fields.Str(allow_none=True)
connection_params = fields.Dict(allow_none=True)
receiving_connections = fields.Nested(
"ConnectionSchema", many=True, allow_none=True
)
publishing_connections = fields.Nested(
"ConnectionSchema", many=True, allow_none=True
)
namespaces = fields.List(fields.Str(), allow_none=True)
systems = fields.Nested("SystemSchema", many=True, allow_none=True)
has_parent = fields.Bool(allow_none=True)
parent = fields.Str(allow_none=True)
children = fields.Nested(
"self", exclude=("parent"), many=True, default=None, allow_none=True
)
metadata = fields.Dict(allow_none=True)


class GardenDomainIdentifierSchema(BaseSchema):
Expand Down Expand Up @@ -551,6 +572,8 @@ class OperationSchema(BaseSchema):

target_garden_name = fields.Str(allow_none=True)
source_garden_name = fields.Str(allow_none=True)
source_api = fields.Str(allow_none=True)

operation_type = fields.Str(allow_none=True)


Expand Down Expand Up @@ -612,6 +635,7 @@ class UserListSchema(BaseSchema):
{
"Choices": ChoicesSchema,
"Command": CommandSchema,
"Connection": ConnectionSchema,
"CronTrigger": CronTriggerSchema,
"DateTrigger": DateTriggerSchema,
"Event": EventSchema,
Expand Down
8 changes: 7 additions & 1 deletion brewtils/test/comparable.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from brewtils.models import (
Choices,
Command,
Connection,
CronTrigger,
DateTrigger,
Event,
Expand Down Expand Up @@ -191,6 +192,7 @@ def _assert_wrapper(obj1, obj2, expected_type=None, do_raise=False, **kwargs):
assert_request_file_equal = partial(_assert_wrapper, expected_type=RequestFile)
assert_runner_equal = partial(_assert_wrapper, expected_type=Runner)
assert_resolvable_equal = partial(_assert_wrapper, expected_type=Resolvable)
assert_connection_equal = partial(_assert_wrapper, expected_type=Connection)


def assert_command_equal(obj1, obj2, do_raise=False):
Expand Down Expand Up @@ -379,6 +381,10 @@ def assert_garden_equal(obj1, obj2, do_raise=False):
obj1,
obj2,
expected_type=Garden,
deep_fields={"systems": partial(assert_system_equal, do_raise=True)},
deep_fields={
"systems": partial(assert_system_equal, do_raise=True),
"receiving_connections": partial(assert_connection_equal, do_raise=True),
"publishing_connections": partial(assert_connection_equal, do_raise=True),
},
do_raise=do_raise,
)
Loading
Loading