From fd3fd66a1db8925e5a9a3d34acdd213f49378877 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 30 Apr 2018 17:24:27 +0300 Subject: Add: notification service --- notification_service.py | 125 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 notification_service.py (limited to 'notification_service.py') diff --git a/notification_service.py b/notification_service.py new file mode 100644 index 0000000..002650d --- /dev/null +++ b/notification_service.py @@ -0,0 +1,125 @@ +#!/usr/bin/python3 +# Copyright (C) 2018 Lars Wirzenius +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + + +import logging +import logging.handlers +import os +import sys + + +import apifw +import slog +import yaml + + +import ick2 + + +transactions = slog.Counter() + + +def counter(): + return 'HTTP transaction {}'.format(transactions.increment()) + + +def dict_logger(log, stack_info=None): + ick2.log.log(exc_info=stack_info, **log) + + +default_config = { + 'token-public-key': None, + 'token-audience': None, + 'token-issuer': None, + 'log': [], + 'from_addr': None, + 'smtp_server': None, + 'smtp_port': None, + 'smtp_user': None, + 'smtp_password': None +} + + +def load_config(filename, defconf): + conf = yaml.safe_load(open(filename, 'r')) + actual_config = dict(defconf) + actual_config.update(conf) + return actual_config + + +def check_config(config, musthave): + for key in config: + if key not in musthave: + raise Exception('Config %s is not known' % key) + for key in musthave: + if config.get(key) is None: + raise Exception('Config %s must not be None' % key) + + +def main(): + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + handler = logging.StreamHandler(sys.stderr) + logger.addHandler(handler) + logging.info('Starting notification service') + + try: + + name = 'NOTIFICATION_SERVICE_CONFIG' + config_filename = os.environ.get(name) + logging.info('config filename %r', config_filename) + if not config_filename: + msg = 'No %s defined in environment' % name + logging.error(msg) + raise Exception(msg) + + logging.info('reading config from %r', config_filename) + config = load_config(config_filename, default_config) + + logging.info('config is %r', config) + ick2.setup_logging(config) + check_config(config, default_config) + + ick2.log.log( + 'info', msg_text='Notification service starts', config=config) + + api = ick2.NotificationAPI(config) + ick2.log.log('info', msg_text='created NotificationAPI') + + application = apifw.create_bottle_application( + api, counter, dict_logger, config) + ick2.log.log('info', msg_text='called apifw.create_bottle_application') + + return application + except SystemExit: + raise + except BaseException as e: + logging.error(str(e)) + ick2.log.log( + 'error', msg_text='Uncaught exception', exception=str(e), + exc_info=True) + sys.exit(1) + + +app = main() + +# If we are running this program directly with Python, and not via +# gunicorn, we can use the Bottle built-in debug server, which can +# make some things easier to debug. + +if __name__ == '__main__': + print('running in debug mode') + app.run(host='127.0.0.1', port=12767) -- cgit v1.2.1