diff --git a/microservice/language/python/init/_utils.py b/microservice/language/python/init/_utils.py index 30a3216..8f5fca7 100644 --- a/microservice/language/python/init/_utils.py +++ b/microservice/language/python/init/_utils.py @@ -28,6 +28,14 @@ def build_deploy_playbook(path: Path) -> str: def build_docker_compose(path: Path, microservice_name: str) -> str: """Build Docker Compose file content.""" + db_creation_path = path.parent / "external/postgres/10-create-database.sql" + if not db_creation_path.exists(): + raise ValueError("external/postgres/10-create-database.sql script must exist") + + with db_creation_path.open("a") as db_creation_file: + db_creation_file.write(f"\nCREATE DATABASE {microservice_name}_db;") + db_creation_file.write(f"\nCREATE DATABASE {microservice_name}_query_db;") + if not path.exists(): raise ValueError("A base Compose file must exist.") diff --git a/microservice/language/python/init/config.yml.jinja b/microservice/language/python/init/config.yml.jinja index 66b7cdd..208d762 100644 --- a/microservice/language/python/init/config.yml.jinja +++ b/microservice/language/python/init/config.yml.jinja @@ -10,6 +10,7 @@ service: transaction_repository: minos.aggregate.PostgreSqlTransactionRepository event_repository: minos.aggregate.PostgreSqlEventRepository snapshot_repository: minos.aggregate.PostgreSqlSnapshotRepository + {{ name }}_repository: src.{{ aggregate }}QueryServiceRepository saga_manager: minos.saga.SagaManager discovery: minos.networks.DiscoveryConnector services: diff --git a/microservice/language/python/init/src/queries/repository.py.jinja b/microservice/language/python/init/src/queries/repository.py.jinja index 97165db..f3e60f7 100644 --- a/microservice/language/python/init/src/queries/repository.py.jinja +++ b/microservice/language/python/init/src/queries/repository.py.jinja @@ -8,15 +8,11 @@ class {{ aggregate }}QueryServiceRepository(MinosSetup): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.engine = create_engine("postgresql+psycopg2://postgres:@localhost:5432/{{ name }}_query_db".format(**kwargs)) - self.session = sessionmaker(bind=self.engine) + self.session = sessionmaker(bind=self.engine)() async def _setup(self) -> None: Base.metadata.create_all(self.engine) @classmethod - def _from_config(cls, *args, config: MinosConfig, **kwargs) -> {{ aggregate }}QueryRepository: + def _from_config(cls, *args, config: MinosConfig, **kwargs): return cls(*args, **(config.query_repository._asdict()) | kwargs) - - @property - def session(self): - return self.session \ No newline at end of file diff --git a/microservice/language/python/init/src/queries/services.py.jinja b/microservice/language/python/init/src/queries/services.py.jinja index 52af62f..54012a6 100644 --- a/microservice/language/python/init/src/queries/services.py.jinja +++ b/microservice/language/python/init/src/queries/services.py.jinja @@ -15,6 +15,8 @@ from minos.networks import ( class {{ aggregate }}QueryService(QueryService): """{{ aggregate }}QueryService class.""" + repository: {{ aggregate }}QueryServiceRepository = Provide["{{ name }}_repository"] + @enroute.rest.query("/{{ aggregate.lower() }}s", "GET") async def get_{{ aggregate.lower() }}(self, request: Request) -> Response: """Get a {{ aggregate }} instance. diff --git a/microservice/language/python/init/tests/utils.py b/microservice/language/python/init/tests/utils.py index 84a78dd..e173c87 100644 --- a/microservice/language/python/init/tests/utils.py +++ b/microservice/language/python/init/tests/utils.py @@ -5,6 +5,9 @@ from pathlib import ( Path, ) +from uuid import ( + UUID, +) from minos.aggregate import ( InMemoryEventRepository, @@ -13,23 +16,70 @@ ) from minos.common import ( DependencyInjector, + Lock, MinosConfig, + MinosPool, + MinosSetup, ) -from minos.networks import ( - InMemoryBrokerPublisher, - InMemoryBrokerSubscriberBuilder, +from minos.saga import ( + SagaContext, + SagaStatus, ) +class _FakeBroker(MinosSetup): + """For testing purposes.""" + + async def send(self, *args, **kwargs) -> None: + """For testing purposes.""" + + +class _FakeSagaManager(MinosSetup): + """For testing purposes.""" + + async def run(self, *args, **kwargs) -> UUID: + """For testing purposes.""" + + +class _FakeSagaExecution: + def __init__(self, context: SagaContext, status: SagaStatus = SagaStatus.Finished): + self.context = context + self.status = status + + +class FakeLock(Lock): + """For testing purposes.""" + + def __init__(self, key=None, *args, **kwargs): + if key is None: + key = "fake" + super().__init__(key, *args, **kwargs) + + async def __aexit__(self, exc_type, exc_val, exc_tb): + return + + +class FakeLockPool(MinosPool): + """For testing purposes.""" + + async def _create_instance(self): + return FakeLock() + + async def _destroy_instance(self, instance) -> None: + """For testing purposes.""" + + def build_dependency_injector() -> DependencyInjector: """For testing purposes""" return DependencyInjector( build_config(), - broker_publisher=InMemoryBrokerPublisher, + saga_manager=_FakeSagaManager, + broker_publisher=_FakeBroker, + lock_pool=FakeLockPool, transaction_repository=InMemoryTransactionRepository, event_repository=InMemoryEventRepository, - snapshot_snapshot=InMemorySnapshotRepository, + snapshot_repository=InMemorySnapshotRepository, ) diff --git a/microservice/language/python/package-manager/poetry/pyproject.toml.jinja b/microservice/language/python/package-manager/poetry/pyproject.toml.jinja index 09e15bb..00eda87 100644 --- a/microservice/language/python/package-manager/poetry/pyproject.toml.jinja +++ b/microservice/language/python/package-manager/poetry/pyproject.toml.jinja @@ -15,7 +15,7 @@ minos-microservice-cqrs = "^0.5.0" minos-broker-kafka = "^0.5.0" minos-discovery-minos = "^0.5.0" typer = "^0.3.2" -SQLAlchemy = "^1.4.32" +SQLAlchemy = "^1.4.0" [tool.poetry.dev-dependencies] black = "^19.10b" diff --git a/project/database/postgres/deploy/docker-compose/external/postgres/10-create-database.sql b/project/database/postgres/deploy/docker-compose/external/postgres/10-create-database.sql new file mode 100644 index 0000000..7086f43 --- /dev/null +++ b/project/database/postgres/deploy/docker-compose/external/postgres/10-create-database.sql @@ -0,0 +1 @@ +-- Create microservices databases \ No newline at end of file diff --git a/project/database/postgres/deploy/docker-compose/external/postgres/Dockerfile b/project/database/postgres/deploy/docker-compose/external/postgres/Dockerfile index 8f76803..416b3f6 100644 --- a/project/database/postgres/deploy/docker-compose/external/postgres/Dockerfile +++ b/project/database/postgres/deploy/docker-compose/external/postgres/Dockerfile @@ -1,2 +1,2 @@ -FROM postgres -COPY create-multiple-postgresql-databases.sh /docker-entrypoint-initdb.d/ +FROM postgres:14.2 +COPY 10-create-database.sql /docker-entrypoint-initdb.d/10-create-database.sql \ No newline at end of file diff --git a/project/database/postgres/deploy/docker-compose/external/postgres/create-multiple-postgresql-databases.sh b/project/database/postgres/deploy/docker-compose/external/postgres/create-multiple-postgresql-databases.sh deleted file mode 100644 index 711a438..0000000 --- a/project/database/postgres/deploy/docker-compose/external/postgres/create-multiple-postgresql-databases.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -set -e -set -u - -function create_user_and_database() { - local database="$1" - echo " Creating user and database '$database'" - psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL - CREATE USER $database; - CREATE DATABASE $database; - GRANT ALL PRIVILEGES ON DATABASE $database TO $database; -EOSQL -} - -if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then - echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" - for db in "$(echo "$POSTGRES_MULTIPLE_DATABASES" | tr ',' ' ')"; do - create_user_and_database "$db" - done - echo "Multiple databases created" -fi diff --git a/project/database/redis/deploy/docker-compose/_utils.py b/project/database/redis/deploy/docker-compose/_utils.py index 42edad6..13d85d9 100644 --- a/project/database/redis/deploy/docker-compose/_utils.py +++ b/project/database/redis/deploy/docker-compose/_utils.py @@ -19,9 +19,11 @@ def build_docker_compose(path: Path) -> str: data = yaml.safe_load(file) container = { + "image": "docker.io/bitnami/redis:6.2", + "user": "root", "restart": "always", - "image": "redis:latest", - "volumes": ["redis:/data",], + "environment": {"ALLOW_EMPTY_PASSWORD": "yes", "REDIS_DISABLE_COMMANDS": "FLUSHDB,FLUSHALL"}, + "volumes": ["redis:/bitnami/redis/data",], } data["services"]["redis"] = container