Cleanup old dse code in API models (part-2)

This is the follow up patch on Tim's patch to cleanup old dse code.

Change-Id: Id4942d714c35e4eed70e72793fecbc08925e7811
This commit is contained in:
Anusha Ramineni 2016-07-27 14:45:35 +05:30 committed by Eric K
parent 28812457c0
commit 6f06bdfe4b
12 changed files with 65 additions and 132 deletions

View File

@ -23,10 +23,6 @@ from congress.api import webservice
from congress import exception
def d6service(name, keys, inbox, datapath, args):
return ActionsModel(name, keys, inbox=inbox, dataPath=datapath, **args)
class ActionsModel(base.APIModel):
"""Model for handling API requests about Actions."""
@ -44,8 +40,7 @@ class ActionsModel(base.APIModel):
of items in this model.
"""
# Note: blocking call
caller, source_id = api_utils.get_id_from_context(
context, self.datasource_mgr, self.engine)
caller, source_id = api_utils.get_id_from_context(context)
try:
rpc_args = {'source_id': source_id}

View File

@ -18,6 +18,7 @@ from __future__ import absolute_import
from oslo_log import log as logging
from congress.api import base
from congress.api import webservice
from congress.db import datasources as db_datasources
@ -34,15 +35,13 @@ def create_table_dict(tablename, schema):
# Note(thread-safety): blocking function
def get_id_from_context(context, datasource_mgr=None, policy_engine=None):
# Note(thread-safety): blocking call
datasource_mgr = db_datasources.get_datasource_name(
context.get('ds_id'))
def get_id_from_context(context):
if 'ds_id' in context:
return datasource_mgr, context.get('ds_id')
# Note(thread-safety): blocking call
ds_name = db_datasources.get_datasource_name(context.get('ds_id'))
return ds_name, context.get('ds_id')
elif 'policy_id' in context:
return policy_engine, context.get('policy_id')
return base.ENGINE_SERVICE, context.get('policy_id')
else:
msg = "Internal error: context %s should have included " % str(context)
"either ds_id or policy_id"

View File

@ -19,24 +19,20 @@ from __future__ import absolute_import
from oslo_config import cfg
ENGINE_SERVICE = 'engine'
class APIModel(object):
"""Base Class for handling API requests."""
def __init__(self, name, keys='', inbox=None, dataPath=None,
policy_engine=None, datasource_mgr=None, bus=None):
self.dist_arch = True
self.engine = policy_engine
if self.dist_arch:
self.engine = 'engine'
self.datasource_mgr = datasource_mgr
self.bus = bus
def __init__(self, name, bus=None):
self.name = name
self.dse_long_timeout = cfg.CONF.dse_long_timeout
self.bus = bus
# Note(thread-safety): blocking function
def invoke_rpc(self, caller, name, kwargs, timeout=None):
local = (caller is self.engine and
self.bus.node.service_object(self.engine) is not None)
local = (caller is ENGINE_SERVICE and
self.bus.node.service_object(ENGINE_SERVICE) is not None)
return self.bus.rpc(
caller, name, kwargs, timeout=timeout, local=local)

View File

@ -30,22 +30,8 @@ from congress import exception
LOG = logging.getLogger(__name__)
def d6service(name, keys, inbox, datapath, args):
return DatasourceModel(name, keys, inbox=inbox, dataPath=datapath, **args)
class DatasourceModel(base.APIModel):
"""Model for handling API requests about Datasources."""
def __init__(self, name, keys='', inbox=None, dataPath=None,
policy_engine=None, datasource_mgr=None, bus=None,
synchronizer=None):
super(DatasourceModel, self).__init__(name, keys, inbox=inbox,
dataPath=dataPath,
policy_engine=policy_engine,
datasource_mgr=datasource_mgr,
bus=bus)
self.synchronizer = synchronizer
self.dist_arch = True
# Note(thread-safety): blocking function
def get_items(self, params, context=None):
@ -69,10 +55,6 @@ class DatasourceModel(base.APIModel):
# datasources, and the running datasources should match the
# datasources we show the client.
# TODO(ramineni): Need to move this to new architecture
if self.synchronizer:
# Note(thread-safety): blocking call
self.synchronizer.synchronize_datasources()
return {"results": results}
# Note(thread-safety): blocking function
@ -113,40 +95,35 @@ class DatasourceModel(base.APIModel):
def delete_item(self, id_, params, context=None):
ds_id = context.get('ds_id')
try:
if self.dist_arch:
# Note(thread-safety): blocking call
datasource = self.bus.get_datasource(ds_id)
# FIXME(thread-safety):
# by the time greenthread resumes, the
# returned datasource name could refer to a totally different
# datasource, causing the rest of this code to unintentionally
# delete a different datasource
# Fix: check UUID of datasource before operating.
# Abort if mismatch
# Note(thread-safety): blocking call
datasource = self.bus.get_datasource(ds_id)
# FIXME(thread-safety):
# by the time greenthread resumes, the
# returned datasource name could refer to a totally different
# datasource, causing the rest of this code to unintentionally
# delete a different datasource
# Fix: check UUID of datasource before operating.
# Abort if mismatch
# Note(thread-safety): blocking call
# FIXME(thread-safety):
# by the time greenthread resumes, the
# returned datasource name could refer to a totally different
# datasource, causing the rest of this code to unintentionally
# delete a different datasource
# Fix: check UUID of datasource before operating.
# Abort if mismatch
# Note(thread-safety): blocking call
# FIXME(thread-safety):
# by the time greenthread resumes, the
# returned datasource name could refer to a totally different
# datasource, causing the rest of this code to unintentionally
# delete a different datasource
# Fix: check UUID of datasource before operating.
# Abort if mismatch
# Note(thread-safety): blocking call
self.bus.delete_datasource(datasource)
# Let PE synchronizer takes care of deleting policy
else:
# Note(thread-safety): blocking call
self.datasource_mgr.delete_datasource(ds_id)
# Note(thread-safety): blocking call
self.bus.delete_datasource(datasource)
# Let PE synchronizer takes care of deleting policy
except (exception.DatasourceNotFound,
exception.DanglingReference) as e:
raise webservice.DataModelException(e.code, str(e))
# Note(thread-safety): blocking function
def request_refresh_action(self, params, context=None, request=None):
caller, source_id = api_utils.get_id_from_context(context,
self.datasource_mgr)
caller, source_id = api_utils.get_id_from_context(context)
try:
args = {'source_id': source_id}
# Note(thread-safety): blocking call
@ -172,7 +149,7 @@ class DatasourceModel(base.APIModel):
# TODO(ekcs): perhaps keep execution synchronous when explicitly
# called via API
# Note(thread-safety): blocking call
self.invoke_rpc(self.engine, 'execute_action', args)
self.invoke_rpc(base.ENGINE_SERVICE, 'execute_action', args)
except exception.PolicyException as e:
(num, desc) = error_codes.get('execute_error')
raise webservice.DataModelException(num, desc + "::" + str(e))

View File

@ -28,14 +28,9 @@ from congress.api import error_codes
from congress.api import webservice
from congress import exception
LOG = logging.getLogger(__name__)
def d6service(name, keys, inbox, datapath, args):
return PolicyModel(name, keys, inbox=inbox, dataPath=datapath, **args)
class PolicyModel(base.APIModel):
"""Model for handling API requests about Policies."""
@ -54,7 +49,7 @@ class PolicyModel(base.APIModel):
"""
try:
# Note(thread-safety): blocking call
return {"results": self.invoke_rpc(self.engine,
return {"results": self.invoke_rpc(base.ENGINE_SERVICE,
'persistent_get_policies',
{})}
except exception.CongressException as e:
@ -75,7 +70,7 @@ class PolicyModel(base.APIModel):
"""
try:
# Note(thread-safety): blocking call
return self.invoke_rpc(self.engine,
return self.invoke_rpc(base.ENGINE_SERVICE,
'persistent_get_policy',
{'id_': id_})
except exception.CongressException as e:
@ -104,7 +99,7 @@ class PolicyModel(base.APIModel):
try:
# Note(thread-safety): blocking call
policy_metadata = self.invoke_rpc(
self.engine, 'persistent_create_policy',
base.ENGINE_SERVICE, 'persistent_create_policy',
{'name': name,
'abbr': item.get('abbreviation'),
'kind': item.get('kind'),
@ -147,7 +142,7 @@ class PolicyModel(base.APIModel):
KeyError: Item with specified id_ not present.
"""
# Note(thread-safety): blocking call
return self.invoke_rpc(self.engine,
return self.invoke_rpc(base.ENGINE_SERVICE,
'persistent_delete_policy',
{'name_or_id': id_})
@ -184,7 +179,7 @@ class PolicyModel(base.APIModel):
'action_theory': actions, 'delta': delta,
'trace': trace, 'as_list': True}
# Note(thread-safety): blocking call
result = self.invoke_rpc(self.engine, 'simulate', args,
result = self.invoke_rpc(base.ENGINE_SERVICE, 'simulate', args,
timeout=self.dse_long_timeout)
except exception.PolicyException as e:
(num, desc) = error_codes.get('simulate_error')
@ -217,7 +212,7 @@ class PolicyModel(base.APIModel):
'action': action,
'action_args': action_args}
# Note(thread-safety): blocking call
self.invoke_rpc(self.engine, 'execute_action', args)
self.invoke_rpc(base.ENGINE_SERVICE, 'execute_action', args)
except exception.PolicyException as e:
(num, desc) = error_codes.get('execute_error')
raise webservice.DataModelException(num, desc + "::" + str(e))

View File

@ -28,10 +28,6 @@ from congress import exception
LOG = logging.getLogger(__name__)
def d6service(name, keys, inbox, datapath, args):
return RowModel(name, keys, inbox=inbox, dataPath=datapath, **args)
class RowModel(base.APIModel):
"""Model for handling API requests about Rows."""
@ -70,8 +66,7 @@ class RowModel(base.APIModel):
# Get the caller, it should be either policy or datasource
# Note(thread-safety): blocking call
caller, source_id = api_utils.get_id_from_context(
context, self.datasource_mgr, self.engine)
caller, source_id = api_utils.get_id_from_context(context)
# FIXME(threod-safety): in DSE2, the returned caller can be a
# datasource name. But the datasource name may now refer to a new,
# unrelated datasource. Causing the rest of this code to operate on
@ -83,7 +78,7 @@ class RowModel(base.APIModel):
try:
args = {'table_id': table_id, 'source_id': source_id,
'trace': gen_trace}
if caller is self.engine:
if caller is base.ENGINE_SERVICE:
# allow extra time for row policy engine query
# Note(thread-safety): blocking call
result = self.invoke_rpc(
@ -98,7 +93,7 @@ class RowModel(base.APIModel):
LOG.exception(m)
raise webservice.DataModelException.create(e)
if gen_trace and caller is self.engine:
if gen_trace and caller is base.ENGINE_SERVICE:
# DSE2 returns lists instead of tuples, so correct that.
results = [{'data': tuple(x['data'])} for x in result[0]]
return {'results': results,
@ -124,9 +119,7 @@ class RowModel(base.APIModel):
"""
LOG.info("update_items(context=%s)", context)
# Note(thread-safety): blocking call
caller, source_id = api_utils.get_id_from_context(context,
self.datasource_mgr,
self.engine)
caller, source_id = api_utils.get_id_from_context(context)
# FIXME(threod-safety): in DSE2, the returned caller can be a
# datasource name. But the datasource name may now refer to a new,
# unrelated datasource. Causing the rest of this code to operate on

View File

@ -28,10 +28,6 @@ from congress import exception
LOG = logging.getLogger(__name__)
def d6service(name, keys, inbox, datapath, args):
return RuleModel(name, keys, inbox=inbox, dataPath=datapath, **args)
class RuleModel(base.APIModel):
"""Model for handling API requests about policy Rules."""
@ -57,7 +53,8 @@ class RuleModel(base.APIModel):
try:
args = {'id_': id_, 'policy_name': self.policy_name(context)}
# Note(thread-safety): blocking call
return self.invoke_rpc(self.engine, 'persistent_get_rule', args)
return self.invoke_rpc(base.ENGINE_SERVICE,
'persistent_get_rule', args)
except exception.CongressException as e:
raise webservice.DataModelException.create(e)
@ -77,7 +74,8 @@ class RuleModel(base.APIModel):
try:
args = {'policy_name': self.policy_name(context)}
# Note(thread-safety): blocking call
rules = self.invoke_rpc(self.engine, 'persistent_get_rules', args)
rules = self.invoke_rpc(base.ENGINE_SERVICE,
'persistent_get_rules', args)
return {'results': rules}
except exception.CongressException as e:
raise webservice.DataModelException.create(e)
@ -108,7 +106,8 @@ class RuleModel(base.APIModel):
'rule_name': item.get('name'),
'comment': item.get('comment')}
# Note(thread-safety): blocking call
return self.invoke_rpc(self.engine, 'persistent_insert_rule', args,
return self.invoke_rpc(base.ENGINE_SERVICE,
'persistent_insert_rule', args,
timeout=self.dse_long_timeout)
except exception.CongressException as e:
raise webservice.DataModelException.create(e)
@ -132,7 +131,8 @@ class RuleModel(base.APIModel):
try:
args = {'id_': id_, 'policy_name_or_id': self.policy_name(context)}
# Note(thread-safety): blocking call
return self.invoke_rpc(self.engine, 'persistent_delete_rule', args,
return self.invoke_rpc(base.ENGINE_SERVICE,
'persistent_delete_rule', args,
timeout=self.dse_long_timeout)
except exception.CongressException as e:
raise webservice.DataModelException.create(e)

View File

@ -27,10 +27,6 @@ from congress import exception
LOG = logging.getLogger(__name__)
def d6service(name, keys, inbox, datapath, args):
return SchemaModel(name, keys, inbox=inbox, dataPath=datapath, **args)
class SchemaModel(base.APIModel):
"""Model for handling API requests about Schemas."""
@ -48,8 +44,7 @@ class SchemaModel(base.APIModel):
The matching item or None if item with id_ does not exist.
"""
# Note(thread-safety): blocking call
caller, source_id = api_utils.get_id_from_context(context,
self.datasource_mgr)
caller, source_id = api_utils.get_id_from_context(context)
# FIXME(threod-safety): in DSE2, the returned caller can be a
# datasource name. But the datasource name may now refer to a new,
# unrelated datasource. Causing the rest of this code to operate on

View File

@ -28,10 +28,6 @@ from congress import exception
LOG = logging.getLogger(__name__)
def d6service(name, keys, inbox, datapath, args):
return StatusModel(name, keys, inbox=inbox, dataPath=datapath, **args)
class StatusModel(base.APIModel):
"""Model for handling API requests about Statuses."""
@ -49,8 +45,7 @@ class StatusModel(base.APIModel):
The matching item or None if item with id_ does not exist.
"""
# Note(thread-safety): blocking call
caller, source_id = api_utils.get_id_from_context(
context, self.datasource_mgr, self.engine)
caller, source_id = api_utils.get_id_from_context(context)
# FIXME(threod-safety): in DSE2, the returned caller can be a
# datasource name. But the datasource name may now refer to a new,
# unrelated datasource. Causing the rest of this code to operate on

View File

@ -27,10 +27,6 @@ from congress import exception
LOG = logging.getLogger(__name__)
def d6service(name, keys, inbox, datapath, args):
return TableModel(name, keys, inbox=inbox, dataPath=datapath, **args)
class TableModel(base.APIModel):
"""Model for handling API requests about Tables."""
@ -48,10 +44,7 @@ class TableModel(base.APIModel):
The matching item or None if item with id_ does not exist.
"""
# Note(thread-safety): blocking call
caller, source_id = api_utils.get_id_from_context(
context,
self.datasource_mgr,
self.engine)
caller, source_id = api_utils.get_id_from_context(context)
# FIXME(threod-safety): in DSE2, the returned caller can be a
# datasource name. But the datasource name may now refer to a new,
# unrelated datasource. Causing the rest of this code to operate on
@ -88,10 +81,7 @@ class TableModel(base.APIModel):
LOG.info('get_items has context %s', context)
# Note(thread-safety): blocking call
caller, source_id = api_utils.get_id_from_context(
context,
self.datasource_mgr,
self.engine)
caller, source_id = api_utils.get_id_from_context(context)
# FIXME(threod-safety): in DSE2, the returned caller can be a
# datasource name. But the datasource name may now refer to a new,
# unrelated datasource. Causing the rest of this code to operate on

View File

@ -40,22 +40,16 @@ class TestAPIUtils(base.SqlTestCase):
def test_get_id_from_context_ds_id(self):
context = {'ds_id': 'datasource id'}
expected = ('datasource id', 'datasource id')
result = api_utils.get_id_from_context(context,
'datasource-mgr',
'policy-engine')
result = api_utils.get_id_from_context(context)
self.assertEqual(expected, result)
def test_get_id_from_context_policy_id(self):
context = {'policy_id': 'policy id'}
expected = ('policy-engine', 'policy id')
result = api_utils.get_id_from_context(context,
'datasource-mgr',
'policy-engine')
expected = ('engine', 'policy id')
result = api_utils.get_id_from_context(context)
self.assertEqual(expected, result)
def test_get_id_from_context_with_invalid_context(self):
context = {'invalid_id': 'invalid id'}
self.assertRaises(webservice.DataModelException,
api_utils.get_id_from_context,
context, 'datasource-mgr', 'policy-engine')
api_utils.get_id_from_context, context)

View File

@ -38,6 +38,10 @@ class TestTableModel(base.SqlTestCase):
# create test policy
self._create_test_policy()
def tearDown(self):
self.node.stop()
super(TestTableModel, self).tearDown()
def _create_test_policy(self):
# create policy
self.policy_model.add_item({"name": 'test-policy'}, {})