From f0c991c665f57b2344a6b8ed23ff62d44612fc19 Mon Sep 17 00:00:00 2001 From: Guy Rodrigue Koffi Date: Sat, 5 Sep 2015 06:54:21 +0200 Subject: [PATCH 1/1] Add external config support to result_collection_api JIRA : RELENG-7 Change-Id: I2b68aac3e903b237f500bad91e3625aaf57bfdaf Signed-off-by: Guy Rodrigue Koffi --- utils/test/result_collection_api/common/config.py | 82 +++++++++++++++++++--- .../test/result_collection_api/common/constants.py | 4 -- utils/test/result_collection_api/config.ini | 10 +++ .../result_collection_api/result_collection_api.py | 28 +++++--- 4 files changed, 104 insertions(+), 20 deletions(-) create mode 100644 utils/test/result_collection_api/config.ini diff --git a/utils/test/result_collection_api/common/config.py b/utils/test/result_collection_api/common/config.py index 9f7272be8..a0d0757a5 100644 --- a/utils/test/result_collection_api/common/config.py +++ b/utils/test/result_collection_api/common/config.py @@ -7,15 +7,8 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -""" -from ConfigParser import SafeConfigParser -parser = SafeConfigParser() -parser.read('config.ini') - - -mongo_url = parser.get('default', 'mongo_url') -""" +from ConfigParser import SafeConfigParser, NoOptionError def prepare_put_request(edit_request, key, new_value, old_value): @@ -31,3 +24,76 @@ def prepare_put_request(edit_request, key, new_value, old_value): edit_request[key] = new_value return edit_request + + +class ParseError(Exception): + """ + Custom exception class for config file + """ + + def __init__(self, message): + self.msg = message + + def __str__(self): + return 'error parsing config file : %s' % self.msg + + +class APIConfig: + """ + The purpose of this class is to load values correctly from the config file. + Each key is declared as an attribute in __init__() and linked in parse() + """ + + def __init__(self): + self._default_config_location = "config.ini" + self.mongo_url = None + self.api_port = None + self.api_debug_on = None + self._parser = None + + def _get_parameter(self, section, param): + try: + return self._parser.get(section, param) + except NoOptionError: + raise ParseError("[%s.%s] parameter not found" % (section, param)) + + def _get_int_parameter(self, section, param): + try: + return int(self._get_parameter(section, param)) + except ValueError: + raise ParseError("[%s.%s] not an int" % (section, param)) + + def _get_bool_parameter(self, section, param): + result = self._get_parameter(section, param) + if str(result).lower() == 'true': + return True + if str(result).lower() == 'false': + return False + + raise ParseError( + "[%s.%s : %s] not a boolean" % (section, param, result)) + + @staticmethod + def parse(config_location=None): + obj = APIConfig() + + if config_location is None: + config_location = obj._default_config_location + + obj._parser = SafeConfigParser() + obj._parser.read(config_location) + if not obj._parser: + raise ParseError("%s not found" % config_location) + + # Linking attributes to keys from file with their sections + obj.mongo_url = obj._get_parameter("mongo", "url") + obj.api_port = obj._get_int_parameter("api", "port") + obj.api_debug_on = obj._get_bool_parameter("api", "debug") + return obj + + def __str__(self): + return "mongo_url = %s \n" \ + "api_port = %s \n" \ + "api_debug_on = %s \n" % (self.mongo_url, + self.api_port, + self.api_debug_on) diff --git a/utils/test/result_collection_api/common/constants.py b/utils/test/result_collection_api/common/constants.py index 21769564c..2c825c109 100644 --- a/utils/test/result_collection_api/common/constants.py +++ b/utils/test/result_collection_api/common/constants.py @@ -8,10 +8,6 @@ ############################################################################## -API_LISTENING_PORT = 80 - -MONGO_URL = "mongodb://127.0.0.1:27017/" - DEFAULT_REPRESENTATION = "application/json" HTTP_BAD_REQUEST = 400 HTTP_FORBIDDEN = 403 diff --git a/utils/test/result_collection_api/config.ini b/utils/test/result_collection_api/config.ini new file mode 100644 index 000000000..e00b56c5f --- /dev/null +++ b/utils/test/result_collection_api/config.ini @@ -0,0 +1,10 @@ +[mongo] +# URL of the mongo DB +# Mongo auth url => mongodb://user1:pwd1@host1/?authSource=db1 +url = mongodb://127.0.0.1:27017/test_results_collection + +[api] +# Listening port +port = 80 +# With debug_on set to true, error traces will be shown in HTTP responses +debug = True \ No newline at end of file diff --git a/utils/test/result_collection_api/result_collection_api.py b/utils/test/result_collection_api/result_collection_api.py index bb26bb25e..c04e0343b 100644 --- a/utils/test/result_collection_api/result_collection_api.py +++ b/utils/test/result_collection_api/result_collection_api.py @@ -15,29 +15,40 @@ Pre-requisites: We can launch the API with this file TODOs : + - use POD name instead of id + - logging - json args validation with schemes + - POST/PUT/DELETE for PODs + - POST/PUT/GET/DELETE for installers, platforms (enrich results info) - count cases for GET on test_projects - count results for GET on cases - provide filtering on requests - include objects - - logging - - external configuration file + - swagger documentation - setup file - results pagination - - POST/PUT/DELETE for PODs - - POST/PUT/GET/DELETE for installers, platforms (enrich results info) + - unit tests """ import tornado.ioloop import motor +import argparse from resources.handlers import VersionHandler, PodHandler, \ TestProjectHandler, TestCasesHandler, TestResultsHandler -from common.constants import API_LISTENING_PORT, MONGO_URL +from common.config import APIConfig + + +# optionally get config file from command line +parser = argparse.ArgumentParser() +parser.add_argument("-c", "--config-file", dest='config_file', + help="Config file location") +args = parser.parse_args() +CONF = APIConfig().parse(args.config_file) # connecting to MongoDB server, and choosing database -db = motor.MotorClient(MONGO_URL).test_results_collection +db = motor.MotorClient(CONF.mongo_url) def make_app(): @@ -76,14 +87,15 @@ def make_app(): (r"/results/([^/]*)", TestResultsHandler), ], db=db, - debug=True, + debug=CONF.api_debug_on, ) def main(): application = make_app() - application.listen(API_LISTENING_PORT) + application.listen(CONF.api_port) tornado.ioloop.IOLoop.current().start() + if __name__ == "__main__": main() -- 2.16.6