diff --git a/.gitignore b/.gitignore index ac2b656d..8d6c8ffc 100755 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,18 @@ -*.cache -*.classpath -*.project -*.target/ -*.settings/ -.idea -target/ -test-output/ -test-config.yml -*.swp -*.iml -bin/ +*.cache +*.classpath +*.project +*.target/ +*.settings/ +.idea +target/ +test-output/ +test-config.yml +*.swp +*.iml +bin/ +*.pyc +.tox +build +dist +*.egg-info +*.egg diff --git a/HACKING.rst b/HACKING.rst new file mode 100755 index 00000000..a760af1f --- /dev/null +++ b/HACKING.rst @@ -0,0 +1,4 @@ +monasca_common Style Commandments +================================== + +Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/ diff --git a/README.md b/README.md index 53184af6..1d7c3d84 100644 --- a/README.md +++ b/README.md @@ -30,3 +30,12 @@ A change has been submitted to StackForge to switch to bare-trusty for this buil * [monasca-common-streaming](https://github.com/stackforge/monasca-common/tree/master/java/monasca-common-streaming) - Streaming related utilities. * [monasca-common-testing](https://github.com/stackforge/monasca-common/tree/master/java/monasca-common-testing) - A set of testing related dependencies. * [monasca-common-util](https://github.com/stackforge/monasca-common/tree/master/java/monasca-common-util) - Various utilities such as for serialization, dependency injection, date and time, invocation retries, concurrency, etc. + + +python monasca-common +====================== + +To install the python monasca-common modules, git clone the source and run the +following command:: + + sudo python setup.py install diff --git a/monasca_common/__init__.py b/monasca_common/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/monasca_common/logging/__init__.py b/monasca_common/logging/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/monasca_common/logging/dict_config.py b/monasca_common/logging/dict_config.py new file mode 100644 index 00000000..e20515eb --- /dev/null +++ b/monasca_common/logging/dict_config.py @@ -0,0 +1,50 @@ +# (C) Copyright 2015 HP Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +LOG_FORMAT = '%(process)d %(asctime)s %(levelname)s %(name)s %(message)s' + + +def get_config(conf): + log_config = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'default': { + 'format': LOG_FORMAT + } + }, + 'handlers': { + 'console': { + 'class': "logging.StreamHandler", + 'formatter': "default" + }, + 'file': { + 'class': "logging.handlers.RotatingFileHandler", + 'filename': conf.logging.file, + 'formatter': "default", + 'maxBytes': conf.logging.size, + 'backupCount': conf.logging.backup + }, + }, + 'loggers': { + 'kazoo': {'level': conf.logging.kazoo}, + 'kafka': {'level': conf.logging.kafka}, + 'statsd': {'level': conf.logging.statsd}, + 'iso8601': {'level': conf.logging.iso8601} + }, + 'root': { + 'handlers': ['console'], + 'level': conf.logging.level + } + } + return log_config diff --git a/monasca_common/repositories/__init__.py b/monasca_common/repositories/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/monasca_common/repositories/constants.py b/monasca_common/repositories/constants.py new file mode 100755 index 00000000..b165e8c0 --- /dev/null +++ b/monasca_common/repositories/constants.py @@ -0,0 +1,14 @@ +# (C) Copyright 2015 HP Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +PAGE_LIMIT = 50 diff --git a/monasca_common/repositories/exceptions.py b/monasca_common/repositories/exceptions.py new file mode 100755 index 00000000..7f2f4729 --- /dev/null +++ b/monasca_common/repositories/exceptions.py @@ -0,0 +1,29 @@ +# (C) Copyright 2015 HP Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +class RepositoryException(Exception): + pass + + +class DoesNotExistException(RepositoryException): + pass + + +class AlreadyExistsException(RepositoryException): + pass + + +class InvalidUpdateException(RepositoryException): + pass diff --git a/monasca_common/repositories/mysql/__init__.py b/monasca_common/repositories/mysql/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/monasca_common/repositories/mysql/mysql_repository.py b/monasca_common/repositories/mysql/mysql_repository.py new file mode 100755 index 00000000..28d8922e --- /dev/null +++ b/monasca_common/repositories/mysql/mysql_repository.py @@ -0,0 +1,80 @@ +# (C) Copyright 2015 HP Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import logging + +import MySQLdb as mdb +from oslo_config import cfg + +from monasca_common.repositories import exceptions + +LOG = logging.getLogger(__name__) + + +class MySQLRepository(object): + + def __init__(self): + + try: + + super(MySQLRepository, self).__init__() + + self.conf = cfg.CONF + self.database_name = self.conf.mysql.database_name + self.database_server = self.conf.mysql.hostname + self.database_uid = self.conf.mysql.username + self.database_pwd = self.conf.mysql.password + + except Exception as ex: + LOG.exception(ex) + raise exceptions.RepositoryException(ex) + + def _get_cnxn_cursor_tuple(self): + + cnxn = mdb.connect(self.database_server, self.database_uid, + self.database_pwd, self.database_name, + use_unicode=True, charset='utf8') + + cursor = cnxn.cursor(mdb.cursors.DictCursor) + + return cnxn, cursor + + def _execute_query(self, query, parms): + + cnxn, cursor = self._get_cnxn_cursor_tuple() + + with cnxn: + + cursor.execute(query, parms) + return cursor.fetchall() + + +def mysql_try_catch_block(fun): + + def try_it(*args, **kwargs): + + try: + + return fun(*args, **kwargs) + + except exceptions.DoesNotExistException: + raise + except exceptions.InvalidUpdateException: + raise + except exceptions.AlreadyExistsException: + raise + except Exception as ex: + LOG.exception(ex) + raise exceptions.RepositoryException(ex) + + return try_it diff --git a/monasca_common/tests/__init__.py b/monasca_common/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/monasca_common/tests/common_test.py b/monasca_common/tests/common_test.py new file mode 100644 index 00000000..0d41e1fc --- /dev/null +++ b/monasca_common/tests/common_test.py @@ -0,0 +1,52 @@ +# (C) Copyright 2015 HP Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os +import tempfile +import unittest + +from oslo_config import cfg + +from monasca_common.logging import dict_config + + +class CommonTests(unittest.TestCase): + + def test_logging_config(self): + logging_opts = [ + cfg.StrOpt('level', default='INFO'), + cfg.StrOpt('file', default='/var/log/monasca/monasca.log'), + cfg.StrOpt('size', default=10485760), + cfg.StrOpt('backup', default=5), + cfg.StrOpt('kazoo', default="WARN"), + cfg.StrOpt('kafka', default="WARN"), + cfg.StrOpt('iso8601', default="WARN"), + cfg.StrOpt('statsd', default="WARN")] + logging_group = cfg.OptGroup(name='logging', title='logging') + cfg.CONF.register_group(logging_group) + cfg.CONF.register_opts(logging_opts, logging_group) + + tempfile_path = tempfile.mkstemp()[1] + try: + outfile = open(tempfile_path, 'w') + outfile.writelines( + ['[logging]\n', 'level = DEBUG\n', 'backup = 3\n']) + outfile.close() + + cfg.CONF(args=[], project='test', + default_config_files=[tempfile_path]) + log_config = dict_config.get_config(cfg.CONF) + finally: + os.remove(tempfile_path) + self.assertEqual(log_config['handlers']['file']['backupCount'], str(3)) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..36f8602e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +iso8601 +kafka-python>=0.9.1,<0.9.3 +PyYAML +MySQL-python>=1.2.3 +oslo.config>=1.2.1 +oslo.utils +pbr>=0.11,<2.0 +six>=1.7.0 diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..f64393c4 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,22 @@ +[metadata] +name = monasca-common +summary = Monasca common python modules +author = Hewlett-Packard +home-page = https://github.com/stackforge/monasca-common +classifier = + Intended Audience :: Information Technology + Intended Audience :: System Administrators + License :: OSI Approved :: Apache Software License + Operating System :: POSIX :: Linux + Programming Language :: Python + Programming Language :: Python :: 2.7 + +[files] +packages = + monasca_common + +[pbr] +autodoc_index_modules = True + +[wheel] +universal = 1 diff --git a/setup.py b/setup.py new file mode 100755 index 00000000..fe5eb674 --- /dev/null +++ b/setup.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# Copyright (c) 2015 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT + +import setuptools + +setuptools.setup( + setup_requires=['pbr'], + pbr=True) diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 00000000..0217a596 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,23 @@ +# Hacking already pins down pep8, pyflakes and flake8 +hacking>=0.9.2,<0.10 +Babel>=1.3 +coverage>=3.6 +discover +fixtures>=0.3.14 +flake8==2.1.0 +pep8<=1.5.6 +httplib2>=0.7.5 +mock>=1.0 +mox>=0.5.3 +nose +# Docs Requirements +oslosphinx +oslotest +python-subunit>=0.0.18 +sphinx>=1.1.2,!=1.2.0,<1.3 +sphinxcontrib-docbookrestapi +sphinxcontrib-httpdomain +sphinxcontrib-pecanwsme>=0.8 +testrepository>=0.0.18 +testscenarios>=0.4 +testtools>=0.9.34 \ No newline at end of file diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..77cd7323 --- /dev/null +++ b/tox.ini @@ -0,0 +1,26 @@ +[tox] +minversion = 1.6 +skipsdist = True +envlist = py27,pep8 + +[testenv] +setenv = VIRTUAL_ENV={envdir} +usedevelop = True +install_command = pip install -U {opts} {packages} +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt +commands = nosetests monasca_common/tests + +[testenv:pep8] +commands = flake8 monasca_common + +[testenv:venv] +commands = {posargs} + +[flake8] +max-complexity = 50 +max-line-length = 120 +builtins = _ +ignore = F821,H201,H302,H305,H307,H405,H904 +exclude=.venv,.git,.tox,dist,*openstack/common*,*egg,build +show-source = True