Merge "Refactor resource.py/Resource"
This commit is contained in:
commit
cabd32674e
|
@ -11,10 +11,34 @@
|
|||
# under the License.
|
||||
|
||||
|
||||
from collections import namedtuple
|
||||
class Resource(object):
|
||||
__slots__ = ('type', 'id', 'name', 'extra_info')
|
||||
|
||||
_Resource = namedtuple("Resource", ('type', 'id', 'name', 'extra_info'))
|
||||
def __init__(self, type, id, name, extra_info=None):
|
||||
self.type = type
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.extra_info = extra_info
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
try:
|
||||
getattr(self, key)
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
raise AttributeError()
|
||||
|
||||
def Resource(type, id, name, extra_info=None):
|
||||
return _Resource(type, id, name, extra_info)
|
||||
return super(Resource, self).__setattr__(key, value)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.key)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.key == other.key
|
||||
|
||||
def to_dict(self):
|
||||
return {item: getattr(self, item) for item in self.__slots__}
|
||||
|
||||
@property
|
||||
def key(self):
|
||||
return (self.type, self.id, self.name)
|
||||
|
|
|
@ -40,15 +40,7 @@ class CompleteProtectTask(task.Task):
|
|||
|
||||
def get_flow(context, protectable_registry, workflow_engine, plan, provider,
|
||||
checkpoint):
|
||||
# The 'extra-info' field of resources in plan is optional
|
||||
# The extra_info field of the resource is a dict.
|
||||
# The dict can not be handled by build_graph. It will throw a
|
||||
# error. TypeError: unhashable type: 'dict'
|
||||
resources = set()
|
||||
for item in plan.get("resources"):
|
||||
item["extra_info"] = None
|
||||
resources.add(Resource(**item))
|
||||
|
||||
resources = set(Resource(**item) for item in plan.get("resources"))
|
||||
resource_graph = protectable_registry.build_graph(context,
|
||||
resources)
|
||||
checkpoint.resource_graph = resource_graph
|
||||
|
|
|
@ -219,7 +219,9 @@ def unpack_graph(packed_graph):
|
|||
|
||||
def serialize_resource_graph(resource_graph):
|
||||
packed_resource_graph = pack_graph(resource_graph)
|
||||
return jsonutils.dumps(packed_resource_graph)
|
||||
return jsonutils.dumps(
|
||||
packed_resource_graph,
|
||||
default=lambda r: (r.type, r.id, r.name, r.extra_info))
|
||||
|
||||
|
||||
def deserialize_resource_graph(serialized_resource_graph):
|
||||
|
|
|
@ -353,9 +353,7 @@ class ProtectionManager(manager.Manager):
|
|||
'err': six.text_type(err)})
|
||||
raise
|
||||
|
||||
return dict(id=resource_instance.id, name=resource_instance.name,
|
||||
type=resource_instance.type,
|
||||
extra_info=resource_instance.extra_info)
|
||||
return resource_instance.to_dict()
|
||||
|
||||
@messaging.expected_exceptions(exception.ListProtectableResourceFailed)
|
||||
def list_protectable_dependents(self, context,
|
||||
|
@ -367,7 +365,7 @@ class ProtectionManager(manager.Manager):
|
|||
'id': protectable_id})
|
||||
|
||||
parent_resource = Resource(type=protectable_type, id=protectable_id,
|
||||
name="", extra_info=None)
|
||||
name="")
|
||||
|
||||
registry = self.protectable_registry
|
||||
try:
|
||||
|
@ -379,13 +377,7 @@ class ProtectionManager(manager.Manager):
|
|||
'err': six.text_type(err)})
|
||||
raise
|
||||
|
||||
result = []
|
||||
for resource in dependent_resources:
|
||||
result.append(dict(type=resource.type, id=resource.id,
|
||||
name=resource.name,
|
||||
extra_info=resource.extra_info))
|
||||
|
||||
return result
|
||||
return [resource.to_dict() for resource in dependent_resources]
|
||||
|
||||
def list_providers(self, context, marker=None, limit=None,
|
||||
sort_keys=None, sort_dirs=None, filters=None):
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
from karbor import exception
|
||||
from karbor.i18n import _
|
||||
from karbor.resource import Resource
|
||||
from karbor.services.protection.graph import build_graph
|
||||
import six
|
||||
|
||||
|
@ -109,15 +108,7 @@ class ProtectableRegistry(object):
|
|||
|
||||
def build_graph(self, context, resources):
|
||||
def fetch_dependent_resources_context(resource):
|
||||
dependent_resources = self.fetch_dependent_resources(
|
||||
context, resource)
|
||||
# The extra_info field of the resource is a dict
|
||||
# The dict can not be handled by build_graph, it will throw a
|
||||
# error. TypeError: unhashable type: 'dict'
|
||||
return [Resource(type=dependent_resource.type,
|
||||
id=dependent_resource.id,
|
||||
name=dependent_resource.name, extra_info=None)
|
||||
for dependent_resource in dependent_resources]
|
||||
return self.fetch_dependent_resources(context, resource)
|
||||
|
||||
return build_graph(
|
||||
start_nodes=resources,
|
||||
|
|
|
@ -14,6 +14,7 @@ from oslo_serialization import jsonutils
|
|||
from oslo_serialization import msgpackutils
|
||||
|
||||
from karbor import exception
|
||||
from karbor import resource
|
||||
import karbor.services.protection.graph as graph
|
||||
from karbor.tests import base
|
||||
|
||||
|
@ -143,6 +144,25 @@ class GraphBuilderTest(base.TestCase):
|
|||
unserialized = graph.unpack_graph(fmt.loads(serialized))
|
||||
self.assertEqual(test_graph, unserialized)
|
||||
|
||||
def test_graph_serialize(self):
|
||||
resource_a = resource.Resource('server', 0, 'a', {'name': 'a'})
|
||||
resource_b = resource.Resource('volume', 1, 'b', {'name': 'b'})
|
||||
test_base = {
|
||||
resource_a: [resource_b],
|
||||
resource_b: []
|
||||
}
|
||||
test_graph = graph.build_graph(test_base.keys(), test_base.__getitem__)
|
||||
self.assertIn(
|
||||
graph.serialize_resource_graph(test_graph),
|
||||
[
|
||||
'[{"0x1": ["server", 0, "a", {"name": "a"}], '
|
||||
'"0x0": ["volume", 1, "b", {"name": "b"}]}, '
|
||||
'[["0x1", ["0x0"]]]]',
|
||||
'[{"0x0": ["volume", 1, "b", {"name": "b"}], '
|
||||
'"0x1": ["server", 0, "a", {"name": "a"}]}, '
|
||||
'[["0x1", ["0x0"]]]]'
|
||||
])
|
||||
|
||||
def test_graph_deserialize_unordered_adjacency(self):
|
||||
test_base = {
|
||||
"A1": ["B1", "B2"],
|
||||
|
|
Loading…
Reference in New Issue