Skip to content

Commit 9933c03

Browse files
author
Sergio García Prado
committed
ISSUE #98
* Add support for multiple databases.
1 parent 47a0aae commit 9933c03

File tree

11 files changed

+74
-21
lines changed

11 files changed

+74
-21
lines changed

packages/core/minos-microservice-aggregate/minos/aggregate/events/repositories/database/impl.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
from minos.common import (
1111
NULL_UUID,
12-
Config,
1312
DatabaseMixin,
1413
DatabaseOperation,
1514
IntegrityException,
@@ -32,9 +31,10 @@
3231
class DatabaseEventRepository(DatabaseMixin[EventDatabaseOperationFactory], EventRepository):
3332
"""Database-based implementation of the event repository class."""
3433

35-
@classmethod
36-
def _from_config(cls, config: Config, **kwargs) -> Optional[EventRepository]:
37-
return super()._from_config(config, database_key=None, **kwargs)
34+
def __init__(self, *args, database_key: Optional[tuple[str]] = None, **kwargs):
35+
if database_key is None:
36+
database_key = ("aggregate", "event")
37+
super().__init__(*args, database_key=database_key, **kwargs)
3838

3939
async def _setup(self):
4040
"""Setup miscellaneous repository things.

packages/core/minos-microservice-aggregate/minos/aggregate/snapshots/repositories/database/impl.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
from minos.common import (
1717
NULL_UUID,
18-
Config,
1918
DatabaseMixin,
2019
Inject,
2120
NotProvidedException,
@@ -71,9 +70,12 @@ def __init__(
7170
*args,
7271
event_repository: EventRepository,
7372
transaction_repository: TransactionRepository,
73+
database_key: Optional[tuple[str]] = None,
7474
**kwargs,
7575
):
76-
super().__init__(*args, **kwargs)
76+
if database_key is None:
77+
database_key = ("aggregate", "snapshot")
78+
super().__init__(*args, database_key=database_key, **kwargs)
7779

7880
if event_repository is None:
7981
raise NotProvidedException("An event repository instance is required.")
@@ -84,10 +86,6 @@ def __init__(
8486
self._event_repository = event_repository
8587
self._transaction_repository = transaction_repository
8688

87-
@classmethod
88-
def _from_config(cls, config: Config, **kwargs) -> DatabaseSnapshotRepository:
89-
return cls(database_key=None, **kwargs)
90-
9189
async def _setup(self) -> None:
9290
operation = self.operation_factory.build_create()
9391
await self.submit_query(operation)

packages/core/minos-microservice-aggregate/minos/aggregate/transactions/repositories/database/impl.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
)
99

1010
from minos.common import (
11-
Config,
1211
DatabaseMixin,
1312
ProgrammingException,
1413
)
@@ -30,9 +29,10 @@
3029
class DatabaseTransactionRepository(DatabaseMixin[TransactionDatabaseOperationFactory], TransactionRepository):
3130
"""Database Transaction Repository class."""
3231

33-
@classmethod
34-
def _from_config(cls, config: Config, **kwargs) -> DatabaseTransactionRepository:
35-
return super()._from_config(config, database_key=None, **kwargs)
32+
def __init__(self, *args, database_key: Optional[tuple[str]] = None, **kwargs):
33+
if database_key is None:
34+
database_key = ("aggregate", "transaction")
35+
super().__init__(*args, database_key=database_key, **kwargs)
3636

3737
async def _setup(self):
3838
operation = self.operation_factory.build_create()

packages/core/minos-microservice-common/minos/common/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
from .pools import (
114114
MinosPool,
115115
Pool,
116+
PoolException,
116117
PoolFactory,
117118
)
118119
from .ports import (

packages/core/minos-microservice-common/minos/common/database/mixins.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from contextlib import (
2+
suppress,
3+
)
14
from typing import (
25
AsyncIterator,
36
Generic,
@@ -14,6 +17,7 @@
1417
Inject,
1518
)
1619
from ..pools import (
20+
PoolException,
1721
PoolFactory,
1822
)
1923
from ..setup import (
@@ -39,15 +43,16 @@ def __init__(
3943
self,
4044
database_pool: Optional[DatabaseClientPool] = None,
4145
pool_factory: Optional[PoolFactory] = None,
42-
database_key: Optional[str] = None,
46+
database_key: Optional[tuple[str]] = None,
4347
operation_factory: Optional[GenericDatabaseOperationFactory] = None,
4448
operation_factory_cls: Optional[type[GenericDatabaseOperationFactory]] = None,
4549
*args,
4650
**kwargs,
4751
):
4852
super().__init__(*args, **kwargs, pool_factory=pool_factory)
53+
4954
if database_pool is None and pool_factory is not None:
50-
database_pool = pool_factory.get_pool(type_="database", identifier=database_key)
55+
database_pool = self._get_pool_from_factory(pool_factory, database_key)
5156

5257
if not isinstance(database_pool, DatabaseClientPool):
5358
raise NotProvidedException(f"A {DatabaseClientPool!r} instance is required. Obtained: {database_pool}")
@@ -62,6 +67,17 @@ def __init__(
6267

6368
self._operation_factory = operation_factory
6469

70+
@staticmethod
71+
def _get_pool_from_factory(pool_factory: PoolFactory, database_key: Optional[tuple[str]]):
72+
if database_key is None:
73+
database_key = tuple()
74+
75+
for identifier in database_key:
76+
with suppress(PoolException):
77+
return pool_factory.get_pool(type_="database", identifier=identifier)
78+
79+
return pool_factory.get_pool(type_="database")
80+
6581
@property
6682
def operation_factory(self) -> Optional[GenericDatabaseOperationFactory]:
6783
"""Get the operation factory if any.

packages/core/minos-microservice-common/minos/common/pools.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
from .config import (
3030
Config,
3131
)
32+
from .exceptions import (
33+
MinosConfigException,
34+
MinosException,
35+
)
3236
from .injections import (
3337
Injectable,
3438
)
@@ -87,7 +91,10 @@ def get_pool(self, type_: str, identifier: Optional[str] = None, **kwargs) -> Po
8791
def _create_pool(self, type_: str, **kwargs) -> Pool:
8892
# noinspection PyTypeChecker
8993
pool_cls = self._get_pool_cls(type_)
90-
pool = pool_cls.from_config(self._config, **kwargs)
94+
try:
95+
pool = pool_cls.from_config(self._config, **kwargs)
96+
except MinosConfigException:
97+
raise PoolException("The pool could not be built.")
9198
return pool
9299

93100
def _get_pool_cls(self, type_: str) -> type[Pool]:
@@ -97,7 +104,7 @@ def _get_pool_cls(self, type_: str) -> type[Pool]:
97104
pool_cls = self._config.get_pools().get("types", dict()).get(type_)
98105

99106
if pool_cls is None:
100-
raise ValueError(
107+
raise PoolException(
101108
f"There is not any provided {type!r} to build pools that matches the given type: {type_!r}"
102109
)
103110

@@ -175,3 +182,7 @@ class MinosPool(Pool, Generic[P], ABC):
175182
def __init__(self, *args, **kwargs):
176183
warnings.warn(f"{MinosPool!r} has been deprecated. Use {Pool} instead.", DeprecationWarning)
177184
super().__init__(*args, **kwargs)
185+
186+
187+
class PoolException(MinosException):
188+
"""Exception to be raised when some problem related with a pool happens."""

packages/core/minos-microservice-common/tests/config/v2.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ databases:
1515
saga:
1616
path: "./order.lmdb"
1717
query:
18+
client: minos.common.testing.MockedDatabaseClient
1819
database: order_query_db
1920
user: minos
2021
password: min0s

packages/core/minos-microservice-common/tests/test_common/test_database/test_mixins.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ async def test_constructor_with_pool_factory(self):
3333
# noinspection PyUnresolvedReferences
3434
self.assertEqual(pool_factory.get_pool("database"), database.database_pool)
3535

36+
async def test_constructor_with_pool_factory_and_database_key(self):
37+
pool_factory = PoolFactory(self.config, {"database": DatabaseClientPool})
38+
# noinspection PyTypeChecker
39+
database = DatabaseMixin(pool_factory=pool_factory, database_key=("query", "unknown"))
40+
# noinspection PyUnresolvedReferences
41+
self.assertEqual(pool_factory.get_pool("database", "query"), database.database_pool)
42+
3643
async def test_constructor_raises(self):
3744
with self.assertRaises(NotProvidedException):
3845
# noinspection PyArgumentEqualDefault

packages/core/minos-microservice-common/tests/test_common/test_pools.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@
1010
)
1111
from unittest.mock import (
1212
MagicMock,
13+
patch,
1314
)
1415

1516
from aiomisc import (
1617
PoolBase,
1718
)
1819

1920
from minos.common import (
21+
MinosConfigException,
2022
MinosPool,
2123
Pool,
24+
PoolException,
2225
PoolFactory,
2326
SetupMixin,
2427
)
@@ -55,10 +58,15 @@ def test_get_pool_with_key(self):
5558
self.assertEqual(lock_a, self.factory.get_pool("lock", "a"))
5659
self.assertEqual(lock_b, self.factory.get_pool("lock", "b"))
5760

58-
def test_get_pool_raises(self):
59-
with self.assertRaises(ValueError):
61+
def test_get_pool_cls_raises(self):
62+
with self.assertRaises(PoolException):
6063
self.factory.get_pool("something")
6164

65+
def test_get_pool_identifier_raises(self):
66+
with patch.object(SetupMixin, "from_config", side_effect=MinosConfigException("")):
67+
with self.assertRaises(PoolException):
68+
self.factory.get_pool("database")
69+
6270

6371
class TestPool(unittest.IsolatedAsyncioTestCase):
6472
def test_abstract(self):

packages/core/minos-microservice-networks/minos/networks/brokers/collections/queues/database/impl.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,12 @@ def __init__(
6565
*args,
6666
retry: Optional[int] = None,
6767
records: Optional[int] = None,
68+
database_key: Optional[tuple[str]] = None,
6869
**kwargs,
6970
):
70-
super().__init__(*args, **kwargs)
71+
if database_key is None:
72+
database_key = ("broker",)
73+
super().__init__(*args, database_key=database_key, **kwargs)
7174

7275
if retry is None:
7376
retry = 2

0 commit comments

Comments
 (0)