Merge "OAuth2 support"
[pti/o2.git] / o2app / bootstrap.py
1 # Copyright (C) 2021 Wind River Systems, Inc.
2 #
3 #  Licensed under the Apache License, Version 2.0 (the "License");
4 #  you may not use this file except in compliance with the License.
5 #  You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #  Unless required by applicable law or agreed to in writing, software
10 #  distributed under the License is distributed on an "AS IS" BASIS,
11 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 #  See the License for the specific language governing permissions and
13 #  limitations under the License.
14
15 from retry import retry
16 import inspect
17 from typing import Callable
18
19 from o2common.adapter.notifications import AbstractNotifications,\
20     NoneNotifications
21 from o2common.adapter import redis_eventpublisher
22 from o2common.service import unit_of_work
23 from o2common.service import messagebus
24
25 from o2app.service import handlers
26 from o2app.adapter.unit_of_work import SqlAlchemyUnitOfWork
27
28 from o2ims.adapter import orm as o2ims_orm
29 from o2dms.adapter import orm as o2dms_orm
30
31
32 from o2common.helper import o2logging
33 logger = o2logging.get_logger(__name__)
34
35
36 @retry(tries=100, delay=2, backoff=1)
37 def wait_for_db_ready(engine):
38     # wait for db up
39     logger.info("Wait for DB ready ...")
40     engine.connect()
41     logger.info("DB is ready")
42
43
44 def bootstrap(
45     start_orm: bool = True,
46     uow: unit_of_work.AbstractUnitOfWork = SqlAlchemyUnitOfWork(),
47     notifications: AbstractNotifications = None,
48     publish: Callable = redis_eventpublisher.publish,
49 ) -> messagebus.MessageBus:
50
51     if notifications is None:
52         notifications = NoneNotifications()
53
54     if start_orm:
55         with uow:
56             # get default engine if uow is by default
57             engine = uow.session.get_bind()
58
59             wait_for_db_ready(engine)
60             o2ims_orm.start_o2ims_mappers(engine)
61             o2dms_orm.start_o2dms_mappers(engine)
62
63     dependencies = {"uow": uow, "notifications": notifications,
64                     "publish": publish}
65     injected_event_handlers = {
66         event_type: [
67             inject_dependencies(handler, dependencies)
68             for handler in event_handlers
69         ]
70         for event_type, event_handlers in handlers.EVENT_HANDLERS.items()
71     }
72     injected_command_handlers = {
73         command_type: inject_dependencies(handler, dependencies)
74         for command_type, handler in handlers.COMMAND_HANDLERS.items()
75     }
76
77     bus = messagebus.MessageBus(
78         uow=uow,
79         event_handlers=injected_event_handlers,
80         command_handlers=injected_command_handlers,
81     )
82     messagebus.MessageBus.set_instance(bus)
83     return bus
84
85
86 def inject_dependencies(handler, dependencies):
87     params = inspect.signature(handler).parameters
88     deps = {
89         name: dependency
90         for name, dependency in dependencies.items()
91         if name in params
92     }
93     return lambda message: handler(message, **deps)