From ecaaa3cc377888ddb5c58d7869e4c0bffdb59875 Mon Sep 17 00:00:00 2001 From: Enol Fernandez Date: Mon, 21 Mar 2016 11:25:33 +0100 Subject: [PATCH] Adapt Kind to OCCI 1.2 OCCI 1.2 uses "parent" instead of related in the Kind class. Adapt existing classes and rendering. Partially-Implements: blueprint occi-1-2-core Change-Id: I7f3c5ff57bf01c9a20991a72387c63056256251f --- ooi/occi/core/kind.py | 6 +-- ooi/occi/core/resource.py | 2 +- ooi/occi/helpers.py | 5 +++ ooi/occi/infrastructure/compute.py | 2 +- ooi/occi/infrastructure/network.py | 2 +- ooi/occi/infrastructure/network_link.py | 2 +- ooi/occi/infrastructure/storage.py | 2 +- ooi/occi/infrastructure/storage_link.py | 2 +- ooi/occi/rendering/headers.py | 14 +++++-- ooi/openstack/templates.py | 2 - ooi/tests/fakes.py | 4 -- .../middleware/test_compute_controller.py | 3 -- ooi/tests/unit/occi/test_occi_core.py | 37 ++++++------------- .../unit/occi/test_occi_infrastructure.py | 10 ++--- ooi/tests/unit/occi/test_openstack.py | 2 - ooi/wsgi/serializers.py | 2 +- 16 files changed, 42 insertions(+), 55 deletions(-) diff --git a/ooi/occi/core/kind.py b/ooi/occi/core/kind.py index 2e6f79b..ea9a04e 100644 --- a/ooi/occi/core/kind.py +++ b/ooi/occi/core/kind.py @@ -28,14 +28,14 @@ class Kind(category.Category): """ def __init__(self, scheme, term, title, attributes=None, location=None, - related=[], actions=[]): + parent=None, actions=[]): super(Kind, self).__init__(scheme, term, title, attributes=attributes, location=location) - helpers.check_type(related, Kind) + helpers.check_single_type(parent, Kind) helpers.check_type(actions, action.Action) - self.related = related + self.parent = parent self.actions = actions def _class_name(self): diff --git a/ooi/occi/core/resource.py b/ooi/occi/core/resource.py index ccdb983..c603cd9 100644 --- a/ooi/occi/core/resource.py +++ b/ooi/occi/core/resource.py @@ -37,7 +37,7 @@ class Resource(entity.Entity): kind = kind.Kind(helpers.build_scheme('core'), 'resource', 'resource', attributes, 'resource/', - related=[entity.Entity.kind]) + parent=entity.Entity.kind) def __init__(self, title, mixins, id=None, summary=None): super(Resource, self).__init__(title, mixins, id=id) diff --git a/ooi/occi/helpers.py b/ooi/occi/helpers.py index fb7dd97..68d4329 100644 --- a/ooi/occi/helpers.py +++ b/ooi/occi/helpers.py @@ -24,6 +24,11 @@ def build_scheme(category, prefix=_PREFIX): return '%s#' % scheme +def check_single_type(obj, obj_type): + if obj is not None and not isinstance(obj, obj_type): + raise TypeError('object must be of class %s' % obj_type) + + def check_type(obj_list, obj_type): if not isinstance(obj_list, (list, tuple)): raise TypeError('must be a list or tuple of objects') diff --git a/ooi/occi/infrastructure/compute.py b/ooi/occi/infrastructure/compute.py index 6a93272..7903d5e 100644 --- a/ooi/occi/infrastructure/compute.py +++ b/ooi/occi/infrastructure/compute.py @@ -44,7 +44,7 @@ class ComputeResource(resource.Resource): kind = kind.Kind(helpers.build_scheme('infrastructure'), 'compute', 'compute resource', attributes, 'compute/', actions=actions, - related=[resource.Resource.kind]) + parent=resource.Resource.kind) def __init__(self, title, summary=None, id=None, architecture=None, cores=None, hostname=None, speed=None, memory=None, diff --git a/ooi/occi/infrastructure/network.py b/ooi/occi/infrastructure/network.py index de41dc1..18d8ecf 100644 --- a/ooi/occi/infrastructure/network.py +++ b/ooi/occi/infrastructure/network.py @@ -36,7 +36,7 @@ class NetworkResource(resource.Resource): kind = kind.Kind(helpers.build_scheme('infrastructure'), 'network', 'network resource', attributes, 'network/', actions=actions, - related=[resource.Resource.kind]) + parent=resource.Resource.kind) def __init__(self, title, summary=None, id=None, vlan=None, label=None, state=None, mixins=[]): diff --git a/ooi/occi/infrastructure/network_link.py b/ooi/occi/infrastructure/network_link.py index d73d74a..0db715d 100644 --- a/ooi/occi/infrastructure/network_link.py +++ b/ooi/occi/infrastructure/network_link.py @@ -28,7 +28,7 @@ class NetworkInterface(link.Link): kind = kind.Kind(helpers.build_scheme('infrastructure'), 'networkinterface', 'network link resource', attributes, 'networklink/', - related=[link.Link.kind]) + parent=link.Link.kind) def __init__(self, mixins, source, target, id=None, interface=None, mac=None, state=None): diff --git a/ooi/occi/infrastructure/storage.py b/ooi/occi/infrastructure/storage.py index a1f8af6..cd2cafc 100644 --- a/ooi/occi/infrastructure/storage.py +++ b/ooi/occi/infrastructure/storage.py @@ -43,7 +43,7 @@ class StorageResource(resource.Resource): kind = kind.Kind(helpers.build_scheme('infrastructure'), 'storage', 'storage resource', attributes, 'storage/', actions=actions, - related=[resource.Resource.kind]) + parent=resource.Resource.kind) def __init__(self, title, summary=None, id=None, size=None, state=None): mixins = [] diff --git a/ooi/occi/infrastructure/storage_link.py b/ooi/occi/infrastructure/storage_link.py index fbffbd8..6a439f7 100644 --- a/ooi/occi/infrastructure/storage_link.py +++ b/ooi/occi/infrastructure/storage_link.py @@ -26,7 +26,7 @@ class StorageLink(link.Link): "occi.storagelink.state"]) kind = kind.Kind(helpers.build_scheme('infrastructure'), 'storagelink', 'storage link resource', attributes, 'storagelink/', - related=[link.Link.kind]) + parent=link.Link.kind) def __init__(self, source, target, deviceid=None, mountpoint=None, state=None): diff --git a/ooi/occi/rendering/headers.py b/ooi/occi/rendering/headers.py index 001c6ca..aaa9153 100644 --- a/ooi/occi/rendering/headers.py +++ b/ooi/occi/rendering/headers.py @@ -49,6 +49,9 @@ class CategoryRenderer(HeaderRenderer): return ['location="%s"' % loc] return [] + def _render_rel(self, env={}): + return [] + def render(self, env={}): d = { "term": self.obj.term, @@ -59,16 +62,19 @@ class CategoryRenderer(HeaderRenderer): ret = [] ret.append(('%(term)s; scheme="%(scheme)s"; class="%(class)s"; ' 'title="%(title)s"') % d) - for rel in getattr(self.obj, 'related', []): - d = {"scheme": rel.scheme, "term": rel.term} - ret.append('rel="%(scheme)s%(term)s"' % d) + ret.extend(self._render_rel(env)) ret.extend(self._render_location(env)) # FIXME(enolfc): missing attributes and actions return [('Category', "; ".join(ret))] class KindRenderer(CategoryRenderer): - pass + def _render_rel(self, env={}): + parent = getattr(self.obj, 'parent', None) + if parent is not None: + d = {"scheme": parent.scheme, "term": parent.term} + return ['rel="%(scheme)s%(term)s"' % d] + return [] class ActionRenderer(CategoryRenderer): diff --git a/ooi/openstack/templates.py b/ooi/openstack/templates.py index 9b7d4f2..2fd1d02 100644 --- a/ooi/openstack/templates.py +++ b/ooi/openstack/templates.py @@ -27,7 +27,6 @@ class OpenStackOSTemplate(templates.OCCIOSTemplate): super(OpenStackOSTemplate, self).__init__( uuid, name, - related=[templates.os_tpl], location=location) @@ -51,7 +50,6 @@ class OpenStackResourceTemplate(templates.OCCIResourceTemplate): super(OpenStackResourceTemplate, self).__init__( id, "Flavor: %s" % name, - related=[templates.resource_tpl], attributes=attrs, location=location) diff --git a/ooi/tests/fakes.py b/ooi/tests/fakes.py index 2bdc254..0e6ba1e 100644 --- a/ooi/tests/fakes.py +++ b/ooi/tests/fakes.py @@ -313,13 +313,11 @@ def fake_query_results(): 'bar; ' 'scheme="http://schemas.openstack.org/template/os#"; ' 'class="mixin"; title="bar"; ' - 'rel="http://schemas.ogf.org/occi/infrastructure#os_tpl"; ' 'location="%s/os_tpl/bar"' % application_url) cats.append( 'foo; ' 'scheme="http://schemas.openstack.org/template/os#"; ' 'class="mixin"; title="foo"; ' - 'rel="http://schemas.ogf.org/occi/infrastructure#os_tpl"; ' 'location="%s/os_tpl/foo"' % application_url) # OpenStack Flavors @@ -327,13 +325,11 @@ def fake_query_results(): '1; ' 'scheme="http://schemas.openstack.org/template/resource#"; ' 'class="mixin"; title="Flavor: foo"; ' - 'rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl"; ' 'location="%s/resource_tpl/1"' % application_url) cats.append( '2; ' 'scheme="http://schemas.openstack.org/template/resource#"; ' 'class="mixin"; title="Flavor: bar"; ' - 'rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl"; ' 'location="%s/resource_tpl/2"' % application_url) # OCCI Infrastructure Network diff --git a/ooi/tests/functional/middleware/test_compute_controller.py b/ooi/tests/functional/middleware/test_compute_controller.py index e361959..2cdbe77 100644 --- a/ooi/tests/functional/middleware/test_compute_controller.py +++ b/ooi/tests/functional/middleware/test_compute_controller.py @@ -48,14 +48,11 @@ def build_occi_server(server): cats.append('%s; ' 'scheme="http://schemas.openstack.org/template/os#"; ' 'class="mixin"; title="%s"; ' - 'rel="http://schemas.ogf.org/occi/infrastructure#os_tpl"; ' 'location="%s/os_tpl/%s"' % (image_id, image_id, app_url, image_id)), cats.append('%s; ' 'scheme="http://schemas.openstack.org/template/resource#"; ' 'class="mixin"; title="Flavor: %s"; ' - 'rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl"' - '; ' 'location="%s/resource_tpl/%s"' % (flavor_id, flavor_name, app_url, flavor_id)), diff --git a/ooi/tests/unit/occi/test_occi_core.py b/ooi/tests/unit/occi/test_occi_core.py index 424c87e..6fd6404 100644 --- a/ooi/tests/unit/occi/test_occi_core.py +++ b/ooi/tests/unit/occi/test_occi_core.py @@ -155,35 +155,22 @@ class TestCoreOCCIKind(BaseTestCoreOCCICategory): *self.args, actions=actions) - def test_related(self): - related = [self.obj(None, None, None)] - kind = self.obj(*self.args, related=related) + +def TestCoreOCCIKindRelations(TestCoreOCCIKind): + def test_parent(self): + parent = self.obj(None, None, None) + kind = self.obj(*self.args, parent=parent) for i in (self.args): self.assertEqual(i, getattr(kind, i)) - self.assertEqual(related, kind.related) + self.assertEqual(parent, kind.parent) - def test_related_empty(self): - related = [] - kind = self.obj(*self.args, related=related) - - for i in (self.args): - self.assertEqual(i, getattr(kind, i)) - self.assertEqual(related, kind.related) - - def test_related_invalid(self): - related = None + def test_parent_invalid(self): + parent = None self.assertRaises(TypeError, self.obj, *self.args, - related=related) - - def test_related_invalid_list(self): - related = [None] - self.assertRaises(TypeError, - self.obj, - *self.args, - related=related) + parent=parent) class TestCoreOCCIMixin(TestCoreOCCIKind): @@ -199,7 +186,7 @@ class TestCoreOCCIEntity(base.TestCase): e = entity.Entity self.assertIn("occi.core.id", e.attributes) self.assertIn("occi.core.title", e.attributes) - self.assertEqual([], e.kind.related) + self.assertIsNone(e.kind.parent) # TODO(aloga): We need to check that the attributes are actually set # after we get an object @@ -241,7 +228,7 @@ class TestCoreOCCIResource(base.TestCase): self.assertIn("occi.core.id", r.attributes) self.assertIn("occi.core.summary", r.attributes) self.assertIn("occi.core.title", r.attributes) - self.assertIn(entity.Entity.kind, r.kind.related) + self.assertEqual(entity.Entity.kind, r.kind.parent) # TODO(aloga): We need to check that the attributes are actually set # after we get an object @@ -253,7 +240,7 @@ class TestCoreOCCIResource(base.TestCase): self.assertEqual("bar", r.title) self.assertEqual("baz", r.summary) self.assertEqual(id, r.id) - self.assertIn(entity.Entity.kind, r.kind.related) + self.assertEqual(entity.Entity.kind, r.kind.parent) r.summary = "bazonk" self.assertEqual("bazonk", r.summary) diff --git a/ooi/tests/unit/occi/test_occi_infrastructure.py b/ooi/tests/unit/occi/test_occi_infrastructure.py index 56952f4..8e7ca29 100644 --- a/ooi/tests/unit/occi/test_occi_infrastructure.py +++ b/ooi/tests/unit/occi/test_occi_infrastructure.py @@ -44,7 +44,7 @@ class TestOCCICompute(base.TestCase): self.assertIn("occi.compute.memory", c.attributes) self.assertIn("occi.compute.speed", c.attributes) self.assertIn("occi.compute.state", c.attributes) - self.assertIn(resource.Resource.kind, c.kind.related) + self.assertEqual(resource.Resource.kind, c.kind.parent) self.assertEqual(c.kind.location, "compute/") # TODO(aloga): We need to check that the attributes are actually set # after we get an object (we have to check this for this but also for @@ -106,7 +106,7 @@ class TestOCCIStorage(base.TestCase): self.assertIn("occi.core.title", s.attributes) self.assertIn("occi.storage.size", s.attributes) self.assertIn("occi.storage.state", s.attributes) - self.assertIn(resource.Resource.kind, s.kind.related) + self.assertEqual(resource.Resource.kind, s.kind.parent) self.assertEqual(s.kind.location, "storage/") # TODO(aloga): We need to check that the attributes are actually set # after we get an object (we have to check this for this but also for @@ -144,7 +144,7 @@ class TestOCCIStorageLink(base.TestCase): self.assertIn("occi.storagelink.mountpoint", s.attributes) self.assertIn("occi.storagelink.deviceid", s.attributes) self.assertIn("occi.storagelink.state", s.attributes) - self.assertIn(link.Link.kind, s.kind.related) + self.assertEqual(link.Link.kind, s.kind.parent) self.assertEqual(s.kind.location, "storagelink/") def test_storagelink(self): @@ -217,7 +217,7 @@ class TestOCCINetwork(base.TestCase): self.assertIn("occi.network.vlan", n.attributes) self.assertIn("occi.network.label", n.attributes) self.assertIn("occi.network.state", n.attributes) - self.assertIn(resource.Resource.kind, n.kind.related) + self.assertEqual(resource.Resource.kind, n.kind.parent) self.assertEqual(n.kind.location, "network/") # TODO(aloga): We need to check that the attributes are actually set # after we get an object (we have to check this for this but also for @@ -283,7 +283,7 @@ class TestOCCINetworkInterface(base.TestCase): self.assertIn("occi.networkinterface.interface", l.attributes) self.assertIn("occi.networkinterface.mac", l.attributes) self.assertIn("occi.networkinterface.state", l.attributes) - self.assertIn(link.Link.kind, l.kind.related) + self.assertEqual(link.Link.kind, l.kind.parent) self.assertEqual(l.kind.location, "networklink/") def test_networkinterface(self): diff --git a/ooi/tests/unit/occi/test_openstack.py b/ooi/tests/unit/occi/test_openstack.py index 2ae3c75..6c422eb 100644 --- a/ooi/tests/unit/occi/test_openstack.py +++ b/ooi/tests/unit/occi/test_openstack.py @@ -38,7 +38,6 @@ class TestOpenStackOSTemplate(base.TestCase): self.assertEqual(id, tpl.term) self.assertEqual(title, tpl.title) self.assertTrue(tpl.scheme.startswith(helpers._PREFIX)) - self.assertIn(occi_templates.os_tpl, tpl.related) self.assertEqual(location, tpl.location) @@ -64,7 +63,6 @@ class TestOpenStackResourceTemplate(base.TestCase): self.assertEqual(id, tpl.term) self.assertEqual("Flavor: %s" % name, tpl.title) self.assertTrue(tpl.scheme.startswith(helpers._PREFIX)) - self.assertIn(occi_templates.resource_tpl, tpl.related) self.assertEqual(cores, tpl.cores) self.assertEqual(memory, tpl.memory) self.assertEqual(disk, tpl.disk) diff --git a/ooi/wsgi/serializers.py b/ooi/wsgi/serializers.py index 9e8c6e3..f5d837e 100644 --- a/ooi/wsgi/serializers.py +++ b/ooi/wsgi/serializers.py @@ -19,7 +19,7 @@ import collections from ooi.occi.rendering import headers as header_rendering from ooi.occi.rendering import text as text_rendering from ooi.occi.rendering import urilist as urilist_rendering -from ooi.wsgi import utils +from ooi import utils _MEDIA_TYPE_MAP = collections.OrderedDict([