From 430fd5db2b49b2955dfc7558ce9ff607c0c45fc5 Mon Sep 17 00:00:00 2001 From: Anusha Ramineni Date: Tue, 9 Feb 2016 09:51:50 +0530 Subject: [PATCH] Migrate Schema Model API to new architecture Change-Id: I166e4de18585ffbbcb086bb542e13baf729a8dc1 Closes-bug:#1541001 --- congress/api/schema_model.py | 22 +++---- congress/datasources/datasource_driver.py | 3 + congress/managers/datasource.py | 6 +- congress/tests2/api/base.py | 5 ++ congress/tests2/api/test_schema_model.py | 76 +++++++++++++++++++++++ 5 files changed, 96 insertions(+), 16 deletions(-) create mode 100644 congress/tests2/api/test_schema_model.py diff --git a/congress/api/schema_model.py b/congress/api/schema_model.py index ee0bcb683..842f7521a 100644 --- a/congress/api/schema_model.py +++ b/congress/api/schema_model.py @@ -20,8 +20,8 @@ from __future__ import absolute_import from oslo_log import log as logging from congress.api import api_utils +from congress.api import base from congress.api import webservice -from congress.dse import deepsix from congress.managers import datasource as datasource_manager LOG = logging.getLogger(__name__) @@ -31,18 +31,13 @@ def d6service(name, keys, inbox, datapath, args): return SchemaModel(name, keys, inbox=inbox, dataPath=datapath, **args) -class SchemaModel(deepsix.deepSix): +class SchemaModel(base.APIModel): """Model for handling API requests about Schemas.""" def __init__(self, name, keys, inbox=None, dataPath=None, datasource_mgr=None): super(SchemaModel, self).__init__(name, keys, inbox=inbox, - dataPath=dataPath) - - self.datasource_mgr = datasource_mgr - - def rpc(self, caller, name, *args, **kwargs): - f = getattr(caller, name) - return f(*args, **kwargs) + dataPath=dataPath, + datasource_mgr=datasource_mgr) def get_item(self, id_, params, context=None): """Retrieve item with id id_ from model. @@ -56,11 +51,12 @@ class SchemaModel(deepsix.deepSix): Returns: The matching item or None if item with id_ does not exist. """ - datasource = context.get('ds_id') + caller, source_id = api_utils.get_id_from_context(context, + self.datasource_mgr) table = context.get('table_id') + args = {'source_id': source_id} try: - schema = self.rpc(self.datasource_mgr, 'get_datasource_schema', - datasource) + schema = self.invoke_rpc(caller, 'get_datasource_schema', args) except (datasource_manager.DatasourceNotFound, datasource_manager.DriverNotFound) as e: raise webservice.DataModelException(e.code, str(e), @@ -71,7 +67,7 @@ class SchemaModel(deepsix.deepSix): if table not in schema: raise webservice.DataModelException( 404, ("Table '{}' for datasource '{}' has no " - "schema ".format(id_, datasource)), + "schema ".format(id_, source_id)), http_status_code=404) return api_utils.create_table_dict(table, schema) diff --git a/congress/datasources/datasource_driver.py b/congress/datasources/datasource_driver.py index 7f6d990af..a8c2a0b69 100644 --- a/congress/datasources/datasource_driver.py +++ b/congress/datasources/datasource_driver.py @@ -1142,6 +1142,9 @@ class DataSourceDriverEndpoints(object): def get_tablenames(self, context, source_id): return self.ds.get_tablenames() + def get_datasource_schema(self, context, source_id): + return self.ds.get_schema() + class PollingDataSourceDriver(DataSourceDriver): def __init__(self, name, keys, inbox, datapath, args): diff --git a/congress/managers/datasource.py b/congress/managers/datasource.py index d64309f94..165a7e36a 100644 --- a/congress/managers/datasource.py +++ b/congress/managers/datasource.py @@ -175,10 +175,10 @@ class DataSourceManager(object): return obj.get_schema() @classmethod - def get_datasource_schema(cls, datasource_id): - datasource = datasources_db.get_datasource(datasource_id) + def get_datasource_schema(cls, source_id): + datasource = datasources_db.get_datasource(source_id) if not datasource: - raise DatasourceNotFound(id=datasource_id) + raise DatasourceNotFound(id=source_id) driver = cls.get_driver_info(datasource.driver) if driver: # NOTE(arosen): raises if not found diff --git a/congress/tests2/api/base.py b/congress/tests2/api/base.py index ab18df7d0..491580d4b 100644 --- a/congress/tests2/api/base.py +++ b/congress/tests2/api/base.py @@ -23,6 +23,11 @@ from congress.tests import helper def setup_config(services=[]): cfg.CONF.set_override('distributed_architecture', True) + # Load the fake driver. + cfg.CONF.set_override( + 'drivers', + ['congress.tests.fake_datasource.FakeDataSource']) + messaging_config = helper.generate_messaging_config() node = DseNode(messaging_config, "testnode", []) engine = Dse2Runtime('engine') diff --git a/congress/tests2/api/test_schema_model.py b/congress/tests2/api/test_schema_model.py new file mode 100644 index 000000000..29340867d --- /dev/null +++ b/congress/tests2/api/test_schema_model.py @@ -0,0 +1,76 @@ +# Copyright (c) 2015 OpenStack Foundation +# +# 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. + +from __future__ import print_function +from __future__ import division +from __future__ import absolute_import + +from oslo_config import cfg +cfg.CONF.distributed_architecture = True + +from congress.api import api_utils +from congress.api import schema_model +from congress.api import webservice +from congress.tests import base +from congress.tests2.api import base as api_base + + +class TestSchemaModel(base.TestCase): + def setUp(self): + super(TestSchemaModel, self).setUp() + self.schema_model = schema_model.SchemaModel("test_schema", {}) + self.config = api_base.setup_config([self.schema_model]) + self.data = self.config['data'] + + def test_get_item_all_table(self): + context = {'ds_id': self.data.service_id} + schema = self.data.get_schema() + fake_tables = {'tables': + [api_utils.create_table_dict( + table_, schema) for table_ in schema]} + tables = self.schema_model.get_item(None, {}, context=context) + self.assertEqual(fake_tables, tables) + + def test_get_item_table(self): + context = {'ds_id': self.data.service_id, 'table_id': 'fake_table'} + fake_schema = self.data.get_schema() + fake_table = api_utils.create_table_dict( + "fake_table", fake_schema) + table = self.schema_model.get_item(None, {}, context=context) + self.assertEqual(fake_table, table) + + def test_get_invalid_datasource_table(self): + context = {'ds_id': self.data.service_id, 'table_id': 'invalid_table'} + try: + self.schema_model.get_item(None, {}, context=context) + except webservice.DataModelException as e: + self.assertEqual(404, e.error_code) + else: + raise Exception("Should not get here") + + # TODO(ramineni): Enable once exceptions patch is merged. + # def test_get_invalid_datasource(self): + # context = {'ds_id': 'invalid'} + # with mock.patch.object( + # self.schema_model.datasource_mgr, + # "get_datasource_schema", + # side_effect=datasource_manager.DatasourceNotFound('invalid') + # ): + # try: + # self.schema_model.get_item(None, {}, context=context) + # except webservice.DataModelException as e: + # self.assertEqual(404, e.error_code) + # else: + # raise Exception("Should not get here") """