diff --git a/datasources/connectors/mongo.py b/datasources/connectors/mongo.py new file mode 100644 index 0000000000000000000000000000000000000000..e1eb9f6050ef1b0b4fb88383d0b17fa2651dad09 --- /dev/null +++ b/datasources/connectors/mongo.py @@ -0,0 +1,35 @@ +import json +import typing + +import pymongo + +from .base import DataSetConnector, DummyRequestsResponse + + +class UnmanagedMongoConnector(DataSetConnector): + """ + This connector handles requests for data from a MongoDB collection managed outside of PEDASI. + """ + def __init__(self, location: str, + api_key: typing.Optional[str] = None, + auth: typing.Optional[typing.Callable] = None, + **kwargs): + super().__init__(location, api_key, auth, **kwargs) + + # TODO validate db url + host, database, collection = location.rsplit('/', 2) + self._client = pymongo.MongoClient(host) + self._database = self._client[database] + self._collection = self._database[collection] + + def get_response(self, + params: typing.Optional[typing.Mapping[str, str]] = None): + """ + Select and return all contents of table. + """ + result = self._collection.find(filter=params) + + return DummyRequestsResponse( + json.dumps([dict(row) for row in result], default=str), + 200, content_type='application/json' + ) diff --git a/datasources/tests/test_connectors.py b/datasources/tests/test_connectors.py index a368a9ed1bab75fc3a64455f0d299f4e917356e2..7f934fcdd842a823585ba1819bc558237a70f608 100644 --- a/datasources/tests/test_connectors.py +++ b/datasources/tests/test_connectors.py @@ -143,3 +143,61 @@ class ConnectorUnmanagedSqlTest(TestCase): for record in result: self.assertEqual('datasources', record['app']) + + +class UnmanagedMongoConnectorTest(TestCase): + # Use Django migrations table as test data + location = 'mongodb://localhost/prov/django_migrations' + + def _get_connection(self) -> BaseDataConnector: + return self.plugin(self.location) + + def setUp(self): + BaseDataConnector.load_plugins('datasources/connectors') + self.plugin = BaseDataConnector.get_plugin('UnmanagedMongoConnector') + + def test_get_plugin(self): + self.assertIsNotNone(self.plugin) + + def test_plugin_init(self): + connection = self._get_connection() + + self.assertEqual(connection.location, self.location) + + def test_plugin_type(self): + connection = self._get_connection() + + self.assertFalse(connection.is_catalogue) + + def test_plugin_get_data(self): + connection = self._get_connection() + + result = connection.get_data() + + self.assertEqual(list, type(result)) + self.assertLessEqual(1, len(result)) + first = result[0] + + self.assertEqual(dict, type(first)) + self.assertIn('id', first) + self.assertIn('app', first) + self.assertIn('name', first) + self.assertIn('applied', first) + + def test_plugin_get_data_query(self): + connection = self._get_connection() + + result = connection.get_data(params={'app': 'datasources'}) + + self.assertEqual(list, type(result)) + self.assertLessEqual(1, len(result)) + first = result[0] + + self.assertEqual(dict, type(first)) + self.assertIn('id', first) + self.assertIn('app', first) + self.assertIn('name', first) + self.assertIn('applied', first) + + for record in result: + self.assertEqual('datasources', record['app'])