Port existing rpc calls to use the new RPC client API.

Patch 2/2, this implements github heat issue 181.

test_api_v1 was modified to handle the extra rpc arguments.

metadata_register_address hasn't been included in EngineAPI, and it
possibly doesn't deserve to. This means that bin/heat-metadata has the
only remaining raw rpc call.
This commit is contained in:
Steve Baker 2012-08-02 17:32:07 +12:00
parent e05f39c37b
commit c8b47d80ed
4 changed files with 130 additions and 121 deletions

View File

@ -29,6 +29,7 @@ from heat.common import wsgi
from heat.common import config
from heat.common import context
from heat import utils
from heat.engine import rpcapi as engine_rpcapi
import heat.engine.api as engine_api
from heat.openstack.common import rpc
@ -47,6 +48,7 @@ class StackController(object):
def __init__(self, options):
self.options = options
self.engine_rpcapi = engine_rpcapi.EngineAPI()
def _stackid_addprefix(self, resp):
"""
@ -168,10 +170,9 @@ class StackController(object):
try:
# Note show_stack returns details for all stacks when called with
# no stack_name, we only use a subset of the result here though
stack_list = rpc.call(con, 'engine',
{'method': 'show_stack',
'args': {'stack_name': None,
'params': parms}})
stack_list = self.engine_rpcapi.show_stack(con,
stack_name=None,
params=parms)
except rpc_common.RemoteError as ex:
return self._remote_error(ex)
@ -243,10 +244,9 @@ class StackController(object):
stack_name = req.params['StackName']
try:
stack_list = rpc.call(con, 'engine',
{'method': 'show_stack',
'args': {'stack_name': stack_name,
'params': parms}})
stack_list = self.engine_rpcapi.show_stack(con,
stack_name=stack_name,
params=parms)
except rpc_common.RemoteError as ex:
return self._remote_error(ex)
@ -318,8 +318,8 @@ class StackController(object):
# This should not happen, so return HeatInternalFailureError
return exception.HeatInternalFailureError(detail=msg)
engine_action = {self.CREATE_STACK: "create_stack",
self.UPDATE_STACK: "update_stack"}
engine_action = {self.CREATE_STACK: self.engine_rpcapi.create_stack,
self.UPDATE_STACK: self.engine_rpcapi.update_stack}
con = req.context
@ -346,12 +346,11 @@ class StackController(object):
return exception.HeatInvalidParameterValueError(detail=msg)
try:
res = rpc.call(con, 'engine',
{'method': engine_action[action],
'args': {'stack_name': req.params['StackName'],
'template': stack,
'params': stack_parms,
'args': create_args}})
res = engine_action[action](con,
stack_name=req.params['StackName'],
template=stack,
params=stack_parms,
args=create_args)
except rpc_common.RemoteError as ex:
return self._remote_error(ex)
@ -368,10 +367,9 @@ class StackController(object):
logger.info('get_template')
try:
templ = rpc.call(con, 'engine',
{'method': 'get_template',
'args': {'stack_name': req.params['StackName'],
'params': parms}})
templ = self.engine_rpcapi.get_template(con,
stack_name=req.params['StackName'],
params=parms)
except rpc_common.RemoteError as ex:
return self._remote_error(ex)
@ -415,10 +413,9 @@ class StackController(object):
logger.info('validate_template')
try:
return rpc.call(con, 'engine',
{'method': 'validate_template',
'args': {'template': stack,
'params': parms}})
return self.engine_rpcapi.validate_template(con,
template=stack,
params=parms)
except rpc_common.RemoteError as ex:
return self._remote_error(ex)
@ -431,10 +428,10 @@ class StackController(object):
parms = dict(req.params)
try:
res = rpc.call(con, 'engine',
{'method': 'delete_stack',
'args': {'stack_name': req.params['StackName'],
'params': parms}})
res = self.engine_rpcapi.delete_stack(con,
stack_name=req.params['StackName'],
params=parms,
cast=False)
except rpc_common.RemoteError as ex:
return self._remote_error(ex)
@ -475,10 +472,9 @@ class StackController(object):
stack_name = req.params.get('StackName', None)
try:
event_res = rpc.call(con, 'engine',
{'method': 'list_events',
'args': {'stack_name': stack_name,
'params': parms}})
event_res = self.engine_rpcapi.list_events(con,
stack_name=stack_name,
params=parms)
except rpc_common.RemoteError as ex:
return self._remote_error(ex)
@ -517,15 +513,11 @@ class StackController(object):
return self._stackid_addprefix(result)
con = req.context
args = {
'stack_name': req.params.get('StackName'),
'resource_name': req.params.get('LogicalResourceId'),
}
try:
resource_details = rpc.call(con, 'engine',
{'method': 'describe_stack_resource',
'args': args})
resource_details = self.engine_rpcapi.describe_stack_resource(con,
stack_name=req.params.get('StackName'),
resource_name=req.params.get('LogicalResourceId'))
except rpc_common.RemoteError as ex:
return self._remote_error(ex)
@ -579,16 +571,11 @@ class StackController(object):
msg = 'Use `StackName` or `PhysicalResourceId` but not both'
return exception.HeatInvalidParameterCombinationError(detail=msg)
args = {
'stack_name': stack_name,
'physical_resource_id': physical_resource_id,
'logical_resource_id': req.params.get('LogicalResourceId'),
}
try:
resources = rpc.call(con, 'engine',
{'method': 'describe_stack_resources',
'args': args})
resources = self.engine_rpcapi.describe_stack_resources(con,
stack_name=stack_name,
physical_resource_id=physical_resource_id,
logical_resource_id=req.params.get('LogicalResourceId'))
except rpc_common.RemoteError as ex:
return self._remote_error(ex)
@ -621,10 +608,8 @@ class StackController(object):
con = req.context
try:
resources = rpc.call(con, 'engine', {
'method': 'list_stack_resources',
'args': {'stack_name': req.params.get('StackName')}
})
resources = self.engine_rpcapi.list_stack_resources(con,
stack_name=req.params.get('StackName'))
except rpc_common.RemoteError as ex:
return self._remote_error(ex)

View File

@ -91,13 +91,15 @@ cfg.IntOpt('sql_idle_timeout',
help='timeout before idle sql connections are reaped'),
]
engine_opts = [
cfg.StrOpt('host',
default=socket.gethostname(),
help='Name of this node. This can be an opaque identifier. '
'It is not necessarily a hostname, FQDN, or IP address.'),
cfg.StrOpt('instance_driver',
default='heat.engine.nova',
help='Driver to use for controlling instances'),
help='Driver to use for controlling instances')
]
rpc_opts = [
cfg.StrOpt('host',
default=socket.gethostname(),
help='Name of the engine node. This can be an opaque identifier.'
'It is not necessarily a hostname, FQDN, or IP address.'),
cfg.StrOpt('engine_topic',
default='engine',
help='the topic engine nodes listen on')
@ -107,16 +109,19 @@ cfg.StrOpt('engine_topic',
def register_metadata_opts():
cfg.CONF.register_opts(service_opts)
cfg.CONF.register_opts(bind_opts)
cfg.CONF.register_opts(rpc_opts)
def register_api_opts():
cfg.CONF.register_opts(bind_opts)
cfg.CONF.register_opts(rpc_opts)
def register_engine_opts():
cfg.CONF.register_opts(engine_opts)
cfg.CONF.register_opts(db_opts)
cfg.CONF.register_opts(service_opts)
cfg.CONF.register_opts(rpc_opts)
def setup_logging():

View File

@ -19,6 +19,7 @@ from webob.exc import Response
from heat.common import wsgi
from heat.common import context
from heat.engine import rpcapi as engine_rpcapi
from heat.openstack.common import rpc
@ -39,6 +40,7 @@ def json_error(http_status, message):
class MetadataController:
def __init__(self, options):
self.options = options
self.engine_rpcapi = engine_rpcapi.EngineAPI()
def entry_point(self, req):
return {
@ -48,15 +50,13 @@ class MetadataController:
def list_stacks(self, req):
con = context.get_admin_context()
resp = rpc.call(con, 'engine',
{'method': 'metadata_list_stacks'})
resp = self.engine_rpcapi.metadata_list_stacks(con)
return resp
def list_resources(self, req, stack_name):
con = context.get_admin_context()
resources = rpc.call(con, 'engine',
{'method': 'metadata_list_resources',
'args': {'stack_name': stack_name}})
resources = self.engine_rpcapi.metadata_list_resources(con,
stack_name=stack_name)
if resources:
return resources
else:
@ -65,11 +65,9 @@ class MetadataController:
def get_resource(self, req, stack_name, resource_name):
con = context.get_admin_context()
[error, metadata] = rpc.call(con, 'engine',
{'method': 'metadata_get_resource',
'args': {'stack_name': stack_name,
'resource_name': resource_name}
})
[error, metadata] = self.engine_rpcapi.metadata_get_resource(con,
stack_name=stack_name,
resource_name=resource_name)
if error:
if error == 'stack':
return json_error(404,
@ -81,11 +79,10 @@ class MetadataController:
def update_metadata(self, req, body, stack_id, resource_name):
con = context.get_admin_context()
[error, metadata] = rpc.call(con, 'engine',
{'method': 'metadata_update',
'args': {'stack_id': stack_id,
'resource_name': resource_name,
'metadata': body}})
[error, metadata] = self.engine_rpcapi.metadata_update(con,
stack_id=stack_id,
resource_name=resource_name,
metadata=body)
if error:
if error == 'stack':
return json_error(404,
@ -100,28 +97,24 @@ class MetadataController:
def create_event(self, req, body=None):
con = context.get_admin_context()
[error, event] = rpc.call(con, 'engine',
{'method': 'event_create',
'args': {'event': body}})
[error, event] = self.engine_rpcapi.event_create(con, event=body)
if error:
return json_error(400, error)
return json_response(201, event)
def create_watch_data(self, req, body, watch_name):
con = context.get_admin_context()
[error, watch_data] = rpc.call(con, 'engine',
{'method': 'create_watch_data',
'args': {'watch_name': watch_name,
'stats_data': body}})
[error, watch_data] = self.engine_rpcapi.create_watch_data(con,
watch_name=watch_name,
stats_data=body)
if error:
return json_error(400, error)
return json_response(201, watch_data)
def list_watch_data(self, req, watch_name):
con = context.get_admin_context()
data = rpc.call(con, 'engine',
{'method': 'list_watch_data',
'args': {'watch_name': watch_name}})
data = self.engine_rpcapi.list_watch_data(con,
watch_name=watch_name)
if data:
return data
else:

View File

@ -25,8 +25,10 @@ import httplib
import json
import urlparse
from heat.common import config
from heat.common import context
from heat.engine import auth
from heat.openstack.common import cfg
from heat.openstack.common import rpc
import heat.openstack.common.rpc.common as rpc_common
from heat.common.wsgi import Request
@ -145,9 +147,10 @@ class StackControllerTest(unittest.TestCase):
u'stack_name': u'wordpress',
u'stack_status': u'CREATE_COMPLETE'}]}
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'show_stack',
rpc.call(dummy_req.context, self.topic, {'method': 'show_stack',
'args': {'stack_name': None,
'params': dict(dummy_req.params)}}
'params': dict(dummy_req.params)},
'version': self.api_version}, None
).AndReturn(engine_resp)
# Stub socket.gethostname so it returns "ahostname"
@ -175,9 +178,10 @@ class StackControllerTest(unittest.TestCase):
# Insert an engine RPC error and ensure we map correctly to the
# heat exception type
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'show_stack',
rpc.call(dummy_req.context, self.topic, {'method': 'show_stack',
'args': {'stack_name': None,
'params': dict(dummy_req.params)}}
'params': dict(dummy_req.params)},
'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("AttributeError"))
self.m.ReplayAll()
@ -193,9 +197,10 @@ class StackControllerTest(unittest.TestCase):
# Insert an engine RPC error and ensure we map correctly to the
# heat exception type
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'show_stack',
rpc.call(dummy_req.context, self.topic, {'method': 'show_stack',
'args': {'stack_name': None,
'params': dict(dummy_req.params)}}
'params': dict(dummy_req.params)},
'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("Exception"))
self.m.ReplayAll()
@ -206,7 +211,7 @@ class StackControllerTest(unittest.TestCase):
def test_describe(self):
# Format a dummy GET request to pass into the WSGI handler
stack_name = "wordpress"
stack_name = u"wordpress"
params = {'Action': 'DescribeStacks', 'StackName': stack_name}
dummy_req = self._dummy_GET_request(params)
@ -238,9 +243,10 @@ class StackControllerTest(unittest.TestCase):
u'capabilities':[]}]}
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'show_stack', 'args':
{'stack_name': stack_name,
'params': dict(dummy_req.params)}}).AndReturn(engine_resp)
rpc.call(dummy_req.context, self.topic, {'method': 'show_stack',
'args': {'stack_name': stack_name,
'params': dict(dummy_req.params)},
'version': self.api_version}, None).AndReturn(engine_resp)
# Stub socket.gethostname so it returns "ahostname"
self.m.StubOutWithMock(socket, 'gethostname')
@ -292,9 +298,10 @@ class StackControllerTest(unittest.TestCase):
# Insert an engine RPC error and ensure we map correctly to the
# heat exception type
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'show_stack', 'args':
{'stack_name': stack_name,
'params': dict(dummy_req.params)}}
rpc.call(dummy_req.context, self.topic, {'method': 'show_stack',
'args': {'stack_name': stack_name,
'params': dict(dummy_req.params)},
'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("AttributeError"))
self.m.ReplayAll()
@ -330,12 +337,13 @@ class StackControllerTest(unittest.TestCase):
engine_resp = {u'StackName': u'wordpress', u'StackId': 1}
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'create_stack',
rpc.call(dummy_req.context, self.topic, {'method': 'create_stack',
'args':
{'stack_name': stack_name,
'template': template,
'params': engine_parms,
'args': engine_args}}).AndReturn(engine_resp)
'args': engine_args},
'version': self.api_version}, None).AndReturn(engine_resp)
# Stub socket.gethostname so it returns "ahostname"
self.m.StubOutWithMock(socket, 'gethostname')
@ -389,12 +397,13 @@ class StackControllerTest(unittest.TestCase):
# heat exception type
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'create_stack',
rpc.call(dummy_req.context, self.topic, {'method': 'create_stack',
'args':
{'stack_name': stack_name,
'template': template,
'params': engine_parms,
'args': engine_args}}
'args': engine_args},
'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("AttributeError"))
self.m.ReplayAll()
@ -420,12 +429,13 @@ class StackControllerTest(unittest.TestCase):
engine_resp = {u'StackName': u'wordpress', u'StackId': 1}
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'update_stack',
rpc.call(dummy_req.context, self.topic, {'method': 'update_stack',
'args':
{'stack_name': stack_name,
'template': template,
'params': engine_parms,
'args': engine_args}}).AndReturn(engine_resp)
'args': engine_args},
'version': self.api_version}, None).AndReturn(engine_resp)
# Stub socket.gethostname so it returns "ahostname"
self.m.StubOutWithMock(socket, 'gethostname')
@ -456,10 +466,11 @@ class StackControllerTest(unittest.TestCase):
engine_resp = template
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'get_template',
rpc.call(dummy_req.context, self.topic, {'method': 'get_template',
'args':
{'stack_name': stack_name,
'params': dict(dummy_req.params)}}).AndReturn(engine_resp)
'params': dict(dummy_req.params)},
'version': self.api_version}, None).AndReturn(engine_resp)
self.m.ReplayAll()
@ -479,10 +490,11 @@ class StackControllerTest(unittest.TestCase):
# Insert an engine RPC error and ensure we map correctly to the
# heat exception type
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'get_template',
rpc.call(dummy_req.context, self.topic, {'method': 'get_template',
'args':
{'stack_name': stack_name,
'params': dict(dummy_req.params)}}
'params': dict(dummy_req.params)},
'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("AttributeError"))
self.m.ReplayAll()
@ -502,10 +514,11 @@ class StackControllerTest(unittest.TestCase):
engine_resp = None
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'get_template',
rpc.call(dummy_req.context, self.topic, {'method': 'get_template',
'args':
{'stack_name': stack_name,
'params': dict(dummy_req.params)}}).AndReturn(engine_resp)
'params': dict(dummy_req.params)},
'version': self.api_version}, None).AndReturn(engine_resp)
self.m.ReplayAll()
@ -543,10 +556,11 @@ class StackControllerTest(unittest.TestCase):
engine_resp = None
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'delete_stack',
rpc.call(dummy_req.context, self.topic, {'method': 'delete_stack',
'args':
{'stack_name': stack_name,
'params': dict(dummy_req.params)}}).AndReturn(engine_resp)
'params': dict(dummy_req.params)},
'version': self.api_version}, None).AndReturn(engine_resp)
self.m.ReplayAll()
@ -564,10 +578,11 @@ class StackControllerTest(unittest.TestCase):
# Insert an engine RPC error and ensure we map correctly to the
# heat exception type
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'delete_stack',
rpc.call(dummy_req.context, self.topic, {'method': 'delete_stack',
'args':
{'stack_name': stack_name,
'params': dict(dummy_req.params)}}
'params': dict(dummy_req.params)},
'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("AttributeError"))
self.m.ReplayAll()
@ -596,10 +611,11 @@ class StackControllerTest(unittest.TestCase):
u'resource_type': u'AWS::EC2::Instance'}]}
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'list_events',
rpc.call(dummy_req.context, self.topic, {'method': 'list_events',
'args':
{'stack_name': stack_name,
'params': dict(dummy_req.params)}}).AndReturn(engine_resp)
'params': dict(dummy_req.params)},
'version': self.api_version}, None).AndReturn(engine_resp)
# Stub socket.gethostname so it returns "ahostname"
self.m.StubOutWithMock(socket, 'gethostname')
@ -633,10 +649,11 @@ class StackControllerTest(unittest.TestCase):
# Insert an engine RPC error and ensure we map correctly to the
# heat exception type
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, 'engine', {'method': 'list_events',
rpc.call(dummy_req.context, self.topic, {'method': 'list_events',
'args':
{'stack_name': stack_name,
'params': dict(dummy_req.params)}}
'params': dict(dummy_req.params)},
'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("Exception"))
self.m.ReplayAll()
@ -671,9 +688,10 @@ class StackControllerTest(unittest.TestCase):
'stack_name': dummy_req.params.get('StackName'),
'resource_name': dummy_req.params.get('LogicalResourceId'),
}
rpc.call(dummy_req.context, 'engine',
rpc.call(dummy_req.context, self.topic,
{'method': 'describe_stack_resource',
'args': args}).AndReturn(engine_resp)
'args': args,
'version': self.api_version}, None).AndReturn(engine_resp)
# Stub socket.gethostname so it returns "ahostname"
self.m.StubOutWithMock(socket, 'gethostname')
@ -727,9 +745,10 @@ class StackControllerTest(unittest.TestCase):
'physical_resource_id': None,
'logical_resource_id': dummy_req.params.get('LogicalResourceId'),
}
rpc.call(dummy_req.context, 'engine',
rpc.call(dummy_req.context, self.topic,
{'method': 'describe_stack_resources',
'args': args}).AndReturn(engine_resp)
'args': args,
'version': self.api_version}, None).AndReturn(engine_resp)
# Stub socket.gethostname so it returns "ahostname"
self.m.StubOutWithMock(socket, 'gethostname')
@ -792,9 +811,10 @@ class StackControllerTest(unittest.TestCase):
args = {
'stack_name': dummy_req.params.get('StackName'),
}
rpc.call(dummy_req.context, 'engine',
rpc.call(dummy_req.context, self.topic,
{'method': 'list_stack_resources',
'args': args}).AndReturn(engine_resp)
'args': args,
'version': self.api_version}, None).AndReturn(engine_resp)
self.m.ReplayAll()
@ -816,6 +836,12 @@ class StackControllerTest(unittest.TestCase):
self.maxDiff = None
self.m = mox.Mox()
config.register_engine_opts()
cfg.CONF.set_default('engine_topic', 'engine')
cfg.CONF.set_default('host', 'host')
self.topic = '%s.%s' % (cfg.CONF.engine_topic, cfg.CONF.host)
self.api_version = '1.0'
# Create WSGI controller instance
class DummyConfig():
bind_port = 8000