228b240d1ee714670ba8619bc7e87ab926dfbd97
[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     SmoO2Notifications
21 from o2common.adapter import redis_eventpublisher
22 from o2common.service import unit_of_work
23 from o2common.service import messagebus
24 from o2common.config import config
25
26 from o2app.service import handlers
27 from o2app.adapter.unit_of_work import SqlAlchemyUnitOfWork
28
29 from o2ims.adapter import orm as o2ims_orm
30 from o2dms.adapter import orm as o2dms_orm
31
32 from o2ims.adapter.clients import alarm_dict_client
33
34
35 from o2common.helper import o2logging
36 logger = o2logging.get_logger(__name__)
37
38
39 @retry(tries=100, delay=2, backoff=1)
40 def wait_for_db_ready(engine):
41     # wait for db up
42     logger.info("Wait for DB ready ...")
43     engine.connect()
44     logger.info("DB is ready")
45
46
47 def bootstrap(
48     start_orm: bool = True,
49     uow: unit_of_work.AbstractUnitOfWork = SqlAlchemyUnitOfWork(),
50     notifications: AbstractNotifications = None,
51     publish: Callable = redis_eventpublisher.publish,
52 ) -> messagebus.MessageBus:
53
54     if notifications is None:
55         notifications = SmoO2Notifications()
56
57     if start_orm:
58         with uow:
59             # get default engine if uow is by default
60             engine = uow.session.get_bind()
61
62             wait_for_db_ready(engine)
63             o2ims_orm.start_o2ims_mappers(engine)
64             o2dms_orm.start_o2dms_mappers(engine)
65
66     dependencies = {"uow": uow, "notifications": notifications,
67                     "publish": publish}
68     injected_event_handlers = {
69         event_type: [
70             inject_dependencies(handler, dependencies)
71             for handler in event_handlers
72         ]
73         for event_type, event_handlers in handlers.EVENT_HANDLERS.items()
74     }
75     injected_command_handlers = {
76         command_type: inject_dependencies(handler, dependencies)
77         for command_type, handler in handlers.COMMAND_HANDLERS.items()
78     }
79
80     bus = messagebus.MessageBus(
81         uow=uow,
82         event_handlers=injected_event_handlers,
83         command_handlers=injected_command_handlers,
84     )
85     messagebus.MessageBus.set_instance(bus)
86     return bus
87
88
89 def inject_dependencies(handler, dependencies):
90     params = inspect.signature(handler).parameters
91     deps = {
92         name: dependency
93         for name, dependency in dependencies.items()
94         if name in params
95     }
96     return lambda message: handler(message, **deps)