Merge "Versioned objects - Resource"

This commit is contained in:
Jenkins 2015-03-13 09:52:00 +00:00 committed by Gerrit Code Review
commit 45be90bb22
9 changed files with 192 additions and 30 deletions

View File

@ -30,7 +30,6 @@ from heat.common.i18n import _LW
from heat.common import identifier from heat.common import identifier
from heat.common import short_id from heat.common import short_id
from heat.common import timeutils from heat.common import timeutils
from heat.db import api as db_api
from heat.engine import attributes from heat.engine import attributes
from heat.engine import event from heat.engine import event
from heat.engine import function from heat.engine import function
@ -39,6 +38,7 @@ from heat.engine import resources
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import scheduler from heat.engine import scheduler
from heat.engine import support from heat.engine import support
from heat.objects import resource as resource_objects
from heat.objects import resource_data as resource_data_objects from heat.objects import resource_data as resource_data_objects
from heat.rpc import client as rpc_client from heat.rpc import client as rpc_client
@ -243,7 +243,7 @@ class Resource(object):
return self.t.metadata() return self.t.metadata()
if self._rsrc_metadata is not None: if self._rsrc_metadata is not None:
return self._rsrc_metadata return self._rsrc_metadata
rs = db_api.resource_get(self.stack.context, self.id) rs = resource_objects.Resource.get_obj(self.stack.context, self.id)
rs.refresh(attrs=['rsrc_metadata']) rs.refresh(attrs=['rsrc_metadata'])
self._rsrc_metadata = rs.rsrc_metadata self._rsrc_metadata = rs.rsrc_metadata
return rs.rsrc_metadata return rs.rsrc_metadata
@ -251,7 +251,7 @@ class Resource(object):
def metadata_set(self, metadata): def metadata_set(self, metadata):
if self.id is None: if self.id is None:
raise exception.ResourceNotAvailable(resource_name=self.name) raise exception.ResourceNotAvailable(resource_name=self.name)
rs = db_api.resource_get(self.stack.context, self.id) rs = resource_objects.Resource.get_obj(self.stack.context, self.id)
rs.update_and_save({'rsrc_metadata': metadata}) rs.update_and_save({'rsrc_metadata': metadata})
self._rsrc_metadata = metadata self._rsrc_metadata = metadata
@ -877,7 +877,7 @@ class Resource(object):
return return
try: try:
db_api.resource_get(self.context, self.id).delete() resource_objects.Resource.delete(self.context, self.id)
except exception.NotFound: except exception.NotFound:
# Don't fail on delete if the db entry has # Don't fail on delete if the db entry has
# not been created yet. # not been created yet.
@ -889,7 +889,7 @@ class Resource(object):
self.resource_id = inst self.resource_id = inst
if self.id is not None: if self.id is not None:
try: try:
rs = db_api.resource_get(self.context, self.id) rs = resource_objects.Resource.get_obj(self.context, self.id)
rs.update_and_save({'nova_instance': self.resource_id}) rs.update_and_save({'nova_instance': self.resource_id})
except Exception as ex: except Exception as ex:
LOG.warn(_LW('db error %s'), ex) LOG.warn(_LW('db error %s'), ex)
@ -908,7 +908,7 @@ class Resource(object):
'properties_data': self._stored_properties_data, 'properties_data': self._stored_properties_data,
'stack_name': self.stack.name} 'stack_name': self.stack.name}
new_rs = db_api.resource_create(self.context, rs) new_rs = resource_objects.Resource.create(self.context, rs)
self.id = new_rs.id self.id = new_rs.id
self.uuid = new_rs.uuid self.uuid = new_rs.uuid
self.created_time = new_rs.created_at self.created_time = new_rs.created_at
@ -931,7 +931,7 @@ class Resource(object):
if self.id is not None: if self.id is not None:
try: try:
rs = db_api.resource_get(self.context, self.id) rs = resource_objects.Resource.get_obj(self.context, self.id)
rs.update_and_save({ rs.update_and_save({
'action': self.action, 'action': self.action,
'status': self.status, 'status': self.status,

View File

@ -51,6 +51,7 @@ from heat.engine import stack_lock
from heat.engine import template as templatem from heat.engine import template as templatem
from heat.engine import watchrule from heat.engine import watchrule
from heat.engine import worker from heat.engine import worker
from heat.objects import resource as resource_objects
from heat.objects import stack as stack_object from heat.objects import stack as stack_object
from heat.openstack.common import service from heat.openstack.common import service
from heat.openstack.common import threadgroup from heat.openstack.common import threadgroup
@ -1136,8 +1137,9 @@ class EngineService(service.Service):
:param cnxt: RPC context. :param cnxt: RPC context.
:param physical_resource_id: The physical resource ID to look up. :param physical_resource_id: The physical resource ID to look up.
""" """
rs = db_api.resource_get_by_physical_resource_id(cnxt, rs = resource_objects.Resource.get_by_physical_resource_id(
physical_resource_id) cnxt,
physical_resource_id)
if not rs: if not rs:
raise exception.PhysicalResourceNotFound( raise exception.PhysicalResourceNotFound(
resource_id=physical_resource_id) resource_id=physical_resource_id)

4
heat/engine/stack.py Normal file → Executable file
View File

@ -41,6 +41,7 @@ from heat.engine import resources
from heat.engine import scheduler from heat.engine import scheduler
from heat.engine import template as tmpl from heat.engine import template as tmpl
from heat.engine import update from heat.engine import update
from heat.objects import resource as resource_objects
from heat.objects import stack as stack_object from heat.objects import stack as stack_object
from heat.rpc import api as rpc_api from heat.rpc import api as rpc_api
@ -218,8 +219,9 @@ class Stack(collections.Mapping):
return None return None
if self._db_resources is None: if self._db_resources is None:
try: try:
self._db_resources = db_api.resource_get_all_by_stack( _db_resources = resource_objects.Resource.get_all_by_stack(
self.context, self.id) self.context, self.id)
self._db_resources = _db_resources
except exception.NotFound: except exception.NotFound:
return None return None
return self._db_resources.get(name) return self._db_resources.get(name)

View File

@ -15,10 +15,10 @@ from oslo_log import log as logging
import six import six
from heat.common.i18n import _LI from heat.common.i18n import _LI
from heat.db import api as db_api
from heat.engine import dependencies from heat.engine import dependencies
from heat.engine import resource from heat.engine import resource
from heat.engine import scheduler from heat.engine import scheduler
from heat.objects import resource as resource_objects
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -84,8 +84,8 @@ class StackUpdate(object):
@staticmethod @staticmethod
def _exchange_stacks(existing_res, prev_res): def _exchange_stacks(existing_res, prev_res):
db_api.resource_exchange_stacks(existing_res.stack.context, resource_objects.Resource.exchange_stacks(existing_res.stack.context,
existing_res.id, prev_res.id) existing_res.id, prev_res.id)
prev_stack, existing_stack = prev_res.stack, existing_res.stack prev_stack, existing_stack = prev_res.stack, existing_res.stack
prev_stack.add_resource(existing_res) prev_stack.add_resource(existing_res)
existing_stack.add_resource(prev_res) existing_stack.add_resource(prev_res)

153
heat/objects/resource.py Executable file
View File

@ -0,0 +1,153 @@
# Copyright 2014 Intel Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Resource object
"""
from oslo_versionedobjects import base
from oslo_versionedobjects import fields
from heat.db import api as db_api
from heat.objects import fields as heat_fields
from heat.objects import resource_data
from heat.objects import stack
class Resource(
base.VersionedObject,
base.VersionedObjectDictCompat,
base.ComparableVersionedObject,
):
fields = {
'id': fields.IntegerField(),
'uuid': fields.StringField(),
'stack_id': fields.StringField(nullable=False),
'created_at': fields.DateTimeField(read_only=True),
'updated_at': fields.DateTimeField(nullable=True),
'nova_instance': fields.StringField(nullable=True),
'name': fields.StringField(nullable=True),
'status': fields.StringField(nullable=True),
'status_reason': fields.StringField(nullable=True),
'action': fields.StringField(nullable=True),
'rsrc_metadata': heat_fields.JsonField(nullable=True),
'properties_data': heat_fields.JsonField(nullable=True),
'data': fields.ListOfObjectsField(
resource_data.ResourceData,
nullable=True
),
'stack': fields.ObjectField(stack.Stack, nullable=False),
'engine_id': fields.StringField(nullable=True),
'atomic_key': fields.IntegerField(nullable=True),
}
@staticmethod
def _from_db_object(resource, context, db_resource):
if db_resource is None:
return None
for field in resource.fields:
if field == 'data':
resource['data'] = map(
lambda resd: resource_data.ResourceData._from_db_object(
resource_data.ResourceData(context), resd
),
db_resource.data
)
else:
resource[field] = db_resource[field]
resource._context = context
resource.obj_reset_changes()
return resource
@classmethod
def get_obj(cls, context, resource_id):
resource_db = db_api.resource_get(context, resource_id)
resource = cls._from_db_object(cls(context), context, resource_db)
return resource
@classmethod
def get_all(cls, context):
resources_db = db_api.resource_get_all(context)
resources = [
(
resource_name,
cls._from_db_object(cls(context), context, resource_db)
)
for resource_name, resource_db in resources_db.iteritems()
]
return dict(resources)
@classmethod
def create(cls, context, values):
return db_api.resource_create(context, values)
@classmethod
def delete(cls, context, resource_id):
resource_db = db_api.resource_get(context, resource_id)
resource_db.delete()
@classmethod
def exchange_stacks(cls, context, resource_id1, resource_id2):
return db_api.resource_exchange_stacks(
context,
resource_id1,
resource_id2)
@classmethod
def get_all_by_stack(cls, context, stack_id):
resources_db = db_api.resource_get_all_by_stack(context, stack_id)
resources = [
(
resource_name,
cls._from_db_object(cls(context), context, resource_db)
)
for resource_name, resource_db in resources_db.iteritems()
]
return dict(resources)
@classmethod
def get_by_name_and_stack(cls, context, resource_name, stack_id):
resource_db = db_api.resource_get_by_name_and_stack(
context,
resource_name,
stack_id)
resource = cls._from_db_object(cls(context), context, resource_db)
return resource
@classmethod
def get_by_physical_resource_id(cls, context, physical_resource_id):
resource_db = db_api.resource_get_by_physical_resource_id(
context,
physical_resource_id)
resource = cls._from_db_object(cls(context), context, resource_db)
return resource
def update_and_save(cls, values):
resource_db = db_api.resource_get(cls._context, cls.id)
resource_db.update_and_save(values)
cls._refresh()
return resource_db
def _refresh(self):
return self.__class__._from_db_object(
self,
self._context,
self.__class__.get_obj(self._context, self.id))
def refresh(self, attrs=None):
resource_db = db_api.resource_get(self._context, self.id)
resource_db.refresh(attrs=attrs)
return self._refresh()

View File

@ -23,12 +23,12 @@ import six
from heat.common import exception from heat.common import exception
from heat.common import identifier from heat.common import identifier
from heat.common import template_format from heat.common import template_format
from heat.db import api as db_api
from heat.engine import environment from heat.engine import environment
from heat.engine import parser from heat.engine import parser
from heat.engine.resources.aws.cfn import wait_condition_handle as aws_wch from heat.engine.resources.aws.cfn import wait_condition_handle as aws_wch
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import scheduler from heat.engine import scheduler
from heat.objects import resource as resource_objects
from heat.tests import common from heat.tests import common
from heat.tests import utils from heat.tests import utils
@ -128,8 +128,8 @@ class WaitConditionTest(common.HeatTestCase):
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), self.assertEqual((rsrc.CREATE, rsrc.COMPLETE),
rsrc.state) rsrc.state)
r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle', r = resource_objects.Resource.get_by_name_and_stack(
self.stack.id) None, 'WaitHandle', self.stack.id)
self.assertEqual('WaitHandle', r.name) self.assertEqual('WaitHandle', r.name)
self.m.VerifyAll() self.m.VerifyAll()
@ -148,8 +148,8 @@ class WaitConditionTest(common.HeatTestCase):
reason = rsrc.status_reason reason = rsrc.status_reason
self.assertTrue(reason.startswith('WaitConditionFailure:')) self.assertTrue(reason.startswith('WaitConditionFailure:'))
r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle', r = resource_objects.Resource.get_by_name_and_stack(
self.stack.id) None, 'WaitHandle', self.stack.id)
self.assertEqual('WaitHandle', r.name) self.assertEqual('WaitHandle', r.name)
self.m.VerifyAll() self.m.VerifyAll()
@ -171,8 +171,8 @@ class WaitConditionTest(common.HeatTestCase):
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), self.assertEqual((rsrc.CREATE, rsrc.COMPLETE),
rsrc.state) rsrc.state)
r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle', r = resource_objects.Resource.get_by_name_and_stack(
self.stack.id) None, 'WaitHandle', self.stack.id)
self.assertEqual('WaitHandle', r.name) self.assertEqual('WaitHandle', r.name)
self.m.VerifyAll() self.m.VerifyAll()
@ -192,8 +192,8 @@ class WaitConditionTest(common.HeatTestCase):
reason = rsrc.status_reason reason = rsrc.status_reason
self.assertTrue(reason.startswith('WaitConditionFailure:')) self.assertTrue(reason.startswith('WaitConditionFailure:'))
r = db_api.resource_get_by_name_and_stack(None, 'WaitHandle', r = resource_objects.Resource.get_by_name_and_stack(
self.stack.id) None, 'WaitHandle', self.stack.id)
self.assertEqual('WaitHandle', r.name) self.assertEqual('WaitHandle', r.name)
self.m.VerifyAll() self.m.VerifyAll()

View File

@ -19,12 +19,12 @@ import six
from heat.common import identifier from heat.common import identifier
from heat.common import template_format from heat.common import template_format
from heat.db import api as db_api
from heat.engine.clients.os import heat_plugin from heat.engine.clients.os import heat_plugin
from heat.engine import environment from heat.engine import environment
from heat.engine import parser from heat.engine import parser
from heat.engine import resource from heat.engine import resource
from heat.engine.resources.openstack.heat import wait_condition_handle as h_wch from heat.engine.resources.openstack.heat import wait_condition_handle as h_wch
from heat.objects import resource as resource_objects
from heat.tests import common from heat.tests import common
from heat.tests import utils from heat.tests import utils
@ -125,8 +125,8 @@ class HeatWaitConditionTest(common.HeatTestCase):
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), self.assertEqual((rsrc.CREATE, rsrc.COMPLETE),
rsrc.state) rsrc.state)
r = db_api.resource_get_by_name_and_stack(None, 'wait_handle', r = resource_objects.Resource.get_by_name_and_stack(
self.stack.id) None, 'wait_handle', self.stack.id)
self.assertEqual('wait_handle', r.name) self.assertEqual('wait_handle', r.name)
self.m.VerifyAll() self.m.VerifyAll()
@ -149,8 +149,8 @@ class HeatWaitConditionTest(common.HeatTestCase):
reason = rsrc.status_reason reason = rsrc.status_reason
self.assertTrue(reason.startswith('WaitConditionFailure:')) self.assertTrue(reason.startswith('WaitConditionFailure:'))
r = db_api.resource_get_by_name_and_stack(None, 'wait_handle', r = resource_objects.Resource.get_by_name_and_stack(
self.stack.id) None, 'wait_handle', self.stack.id)
self.assertEqual('wait_handle', r.name) self.assertEqual('wait_handle', r.name)
self.m.VerifyAll() self.m.VerifyAll()

View File

@ -48,6 +48,7 @@ from heat.engine import stack_lock
from heat.engine import template as templatem from heat.engine import template as templatem
from heat.engine import watchrule from heat.engine import watchrule
from heat.engine import worker from heat.engine import worker
from heat.objects import resource as resource_objects
from heat.objects import stack as stack_object from heat.objects import stack as stack_object
from heat.openstack.common import threadgroup from heat.openstack.common import threadgroup
from heat.rpc import api as rpc_api from heat.rpc import api as rpc_api
@ -3572,7 +3573,8 @@ class SoftwareConfigServiceTest(common.HeatTestCase):
self.ctx, server_id=server.resource_id) self.ctx, server_id=server.resource_id)
self.assertEqual([deployment], deployments) self.assertEqual([deployment], deployments)
rs = db_api.resource_get_by_physical_resource_id(self.ctx, server_id) rs = resource_objects.Resource.get_by_physical_resource_id(
self.ctx, server_id)
self.assertEqual(deployment['config_id'], self.assertEqual(deployment['config_id'],
rs.rsrc_metadata.get('deployments')[0]['id']) rs.rsrc_metadata.get('deployments')[0]['id'])
@ -3618,7 +3620,8 @@ class SoftwareConfigServiceTest(common.HeatTestCase):
# assert that metadata via metadata_software_deployments matches # assert that metadata via metadata_software_deployments matches
# metadata via server resource # metadata via server resource
rs = db_api.resource_get_by_physical_resource_id(self.ctx, server_id) rs = resource_objects.Resource.get_by_physical_resource_id(
self.ctx, server_id)
self.assertEqual(metadata, self.assertEqual(metadata,
rs.rsrc_metadata.get('deployments')) rs.rsrc_metadata.get('deployments'))

View File

@ -34,6 +34,7 @@ from heat.engine import resources
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import scheduler from heat.engine import scheduler
from heat.engine import template from heat.engine import template
from heat.objects import resource as resource_objects
from heat.objects import resource_data as resource_data_object from heat.objects import resource_data as resource_data_object
from heat.tests import common from heat.tests import common
from heat.tests import generic_resource as generic_rsrc from heat.tests import generic_resource as generic_rsrc
@ -329,7 +330,7 @@ class ResourceTest(common.HeatTestCase):
self.assertEqual(res.IN_PROGRESS, res.status) self.assertEqual(res.IN_PROGRESS, res.status)
self.assertEqual('test_store', res.status_reason) self.assertEqual('test_store', res.status_reason)
db_res = db_api.resource_get(res.context, res.id) db_res = resource_objects.Resource.get_obj(res.context, res.id)
self.assertEqual(res.CREATE, db_res.action) self.assertEqual(res.CREATE, db_res.action)
self.assertEqual(res.IN_PROGRESS, db_res.status) self.assertEqual(res.IN_PROGRESS, db_res.status)
self.assertEqual('test_store', db_res.status_reason) self.assertEqual('test_store', db_res.status_reason)
@ -338,6 +339,7 @@ class ResourceTest(common.HeatTestCase):
self.assertEqual(res.CREATE, res.action) self.assertEqual(res.CREATE, res.action)
self.assertEqual(res.COMPLETE, res.status) self.assertEqual(res.COMPLETE, res.status)
self.assertEqual('test_update', res.status_reason) self.assertEqual('test_update', res.status_reason)
db_res.refresh()
self.assertEqual(res.CREATE, db_res.action) self.assertEqual(res.CREATE, db_res.action)
self.assertEqual(res.COMPLETE, db_res.status) self.assertEqual(res.COMPLETE, db_res.status)
self.assertEqual('test_update', db_res.status_reason) self.assertEqual('test_update', db_res.status_reason)