From 70b7b98e61ced0d54dbfe4fd028a060366ed92e6 Mon Sep 17 00:00:00 2001 From: hongyuzhao Date: Fri, 5 Jul 2019 17:09:23 +0800 Subject: [PATCH] vnfres upgrade from python2 to python3 Change-Id: Ide7c76f81f59a1ccd22c6550ee6c7f68e29cb021 Issue-ID: VFC-1429 Signed-off-by: hongyuzhao --- res/docker/Dockerfile | 2 +- res/docker/docker-env-conf.sh | 2 +- res/requirements.txt | 11 ++-- res/res/middleware.py | 9 +++ res/res/pub/redisco/__init__.py | 56 +++++++++++++++++++ res/res/pub/redisco/containers.py | 114 ++++++++++++++++++++++++++++++++++++++ res/res/pub/utils/idutil.py | 2 +- res/res/pub/utils/tests.py | 6 +- res/res/resources/views.py | 22 ++++---- res/res/settings.py | 9 ++- res/tox.ini | 5 +- 11 files changed, 208 insertions(+), 30 deletions(-) create mode 100644 res/res/pub/redisco/__init__.py create mode 100644 res/res/pub/redisco/containers.py diff --git a/res/docker/Dockerfile b/res/docker/Dockerfile index ca5d244..01dd1b2 100644 --- a/res/docker/Dockerfile +++ b/res/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM python:2-alpine +FROM python:3.6-alpine ARG HTTP_PROXY=${HTTP_PROXY} ARG HTTPS_PROXY=${HTTPS_PROXY} diff --git a/res/docker/docker-env-conf.sh b/res/docker/docker-env-conf.sh index 58cf517..5b5d961 100755 --- a/res/docker/docker-env-conf.sh +++ b/res/docker/docker-env-conf.sh @@ -4,7 +4,7 @@ install_sf(){ apk --no-cache update apk --no-cache add bash curl gcc wget mysql-client openssl-dev - apk --no-cache add python-dev libffi-dev musl-dev py2-virtualenv + apk --no-cache add python3-dev libffi-dev musl-dev py3-virtualenv # get binary zip from nexus wget -q -O vfc-gvnfm-vnfres.zip "https://nexus.onap.org/service/local/artifact/maven/redirect?r=snapshots&g=org.onap.vfc.gvnfm.vnfres.res&a=vfc-gvnfm-vnfres-res&v=${pkg_version}-SNAPSHOT&e=zip" && \ diff --git a/res/requirements.txt b/res/requirements.txt index d8553b6..424f7ee 100644 --- a/res/requirements.txt +++ b/res/requirements.txt @@ -1,15 +1,14 @@ # rest framework -Django==1.11.9 -djangorestframework==3.7.7 +Django==2.1.4 +djangorestframework==3.9.4 # for access MySQL -PyMySQL==0.7.11 +PyMySQL==0.9.3 # redis cache redis==2.10.5 # for access redis cache -redisco==0.1.4 django-redis-cache==0.13.1 # for call rest api @@ -17,7 +16,7 @@ httplib2==0.12.3 # for unit test coverage==4.2 -mock==2.0.0 +mock==3.0.5 unittest_xml_reporting==1.12.0 # for auto-swagger @@ -26,7 +25,7 @@ flex>=6.11.1 swagger-spec-validator>=2.1.0 # for onap logging -onappylog>=1.0.6 +onappylog>=1.0.9 # uwsgi for parallel processing uwsgi \ No newline at end of file diff --git a/res/res/middleware.py b/res/res/middleware.py index 386deaf..4df1e8f 100644 --- a/res/res/middleware.py +++ b/res/res/middleware.py @@ -19,6 +19,9 @@ from res.pub.config.config import FORWARDED_FOR_FIELDS, SERVICE_NAME class LogContextMiddleware(object): # the last IP behind multiple proxies, if no exist proxies # get local host ip. + def __init__(self, get_response): + self.get_response = get_response + def _getLastIp(self, request): ip = "" @@ -58,3 +61,9 @@ class LogContextMiddleware(object): def process_response(self, request, response): MDC.clear() return response + + def __call__(self, request): + self.process_request(request) + response = self.get_response(request) + self.process_response(request, response) + return response diff --git a/res/res/pub/redisco/__init__.py b/res/res/pub/redisco/__init__.py new file mode 100644 index 0000000..d488d06 --- /dev/null +++ b/res/res/pub/redisco/__init__.py @@ -0,0 +1,56 @@ +# Copyright (c) 2010 Tim Medina +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# The original code link is https://github.com/iamteem/redisco/tree/master/redisco/__init__.py +import redis + + +class Client(object): + def __init__(self, **kwargs): + self.connection_settings = kwargs or {'host': 'localhost', 'port': 6379, 'db': 0} + + def redis(self): + return redis.Redis(**self.connection_settings) + + def update(self, d): + self.connection_settings.update(d) + + +def connection_setup(**kwargs): + global connection, client + if client: + client.update(kwargs) + else: + client = Client(**kwargs) + connection = client.redis() + + +def get_client(): + global connection + return connection + + +client = Client() +connection = client.redis() + +__all__ = ['connection_setup', 'get_client'] diff --git a/res/res/pub/redisco/containers.py b/res/res/pub/redisco/containers.py new file mode 100644 index 0000000..b4ddc18 --- /dev/null +++ b/res/res/pub/redisco/containers.py @@ -0,0 +1,114 @@ +# Copyright (c) 2010 Tim Medina +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# The original code link is https://github.com/iamteem/redisco/tree/master/redisco/containers.py +""" +This module contains the container classes to create objects +that persist directly in a Redis server. +""" +import collections +from functools import partial + + +class Container(object): + """Create a container object saved in Redis. + + Arguments: + key -- the Redis key this container is stored at + db -- the Redis client object. Default: None + + When ``db`` is not set, the gets the default connection from + ``redisco.connection`` module. + """ + + def __init__(self, key, db=None, pipeline=None): + self._db = db + self.key = key + self.pipeline = pipeline + + def clear(self): + """Remove container from Redis database.""" + del self.db[self.key] + + def __getattribute__(self, att): + if att in object.__getattribute__(self, 'DELEGATEABLE_METHODS'): + return partial(getattr(object.__getattribute__(self, 'db'), att), self.key) + else: + return object.__getattribute__(self, att) + + @property + def db(self): + if self.pipeline: + return self.pipeline + if self._db: + return self._db + if hasattr(self, 'db_cache') and self.db_cache: + return self.db_cache + else: + from res.pub.redisco import connection + self.db_cache = connection + return self.db_cache + + DELEGATEABLE_METHODS = () + + +class Hash(Container, collections.MutableMapping): + + def __getitem__(self, att): + return self.hget(att) + + def __setitem__(self, att, val): + self.hset(att, val) + + def __delitem__(self, att): + self.hdel(att) + + def __len__(self): + return self.hlen() + + def __iter__(self): + return self.hgetall().__iter__() + + def __contains__(self, att): + return self.hexists(att) + + def __repr__(self): + return "<%s '%s' %s>" % (self.__class__.__name__, self.key, self.hgetall()) + + def keys(self): + return self.hkeys() + + def values(self): + return self.hvals() + + def _get_dict(self): + return self.hgetall() + + def _set_dict(self, new_dict): + self.clear() + self.update(new_dict) + + dict = property(_get_dict, _set_dict) + + DELEGATEABLE_METHODS = ('hlen', 'hset', 'hdel', 'hkeys', 'hgetall', 'hvals', + 'hget', 'hexists', 'hincrby', 'hmget', 'hmset') diff --git a/res/res/pub/utils/idutil.py b/res/res/pub/utils/idutil.py index 16b5b76..253259f 100644 --- a/res/res/pub/utils/idutil.py +++ b/res/res/pub/utils/idutil.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from redisco import containers as cont +from res.pub.redisco import containers as cont def get_auto_id(id_type, id_group="auto_id_hash"): diff --git a/res/res/pub/utils/tests.py b/res/res/pub/utils/tests.py index ba67e90..5c925c4 100644 --- a/res/res/pub/utils/tests.py +++ b/res/res/pub/utils/tests.py @@ -13,9 +13,9 @@ # limitations under the License. import unittest -import syscomm -import values -import enumutil +from . import syscomm +from . import values +from . import enumutil class UtilsTest(unittest.TestCase): diff --git a/res/res/resources/views.py b/res/res/resources/views.py index b6b44a9..27ec18e 100644 --- a/res/res/resources/views.py +++ b/res/res/resources/views.py @@ -52,10 +52,10 @@ class getVnf(APIView): raise Exception(vnf_info_serializer.errors) return Response( - data=vnf_info_serializer.data, + data=resp_data, status=status.HTTP_200_OK) except Exception as e: - logger.error(e.message) + logger.error(e.args[0]) logger.error(traceback.format_exc()) return Response( data={ @@ -198,10 +198,10 @@ class getVnfs(APIView): raise Exception(vnfs_info_serializer.errors) return Response( - data=vnfs_info_serializer.data, + data={'resp_data': arr}, status=status.HTTP_200_OK) except Exception as e: - logger.error(e.message) + logger.error(e.args[0]) logger.error(traceback.format_exc()) return Response( data={ @@ -233,10 +233,10 @@ class getVms(APIView): raise Exception(vm_info_serializer.errors) return Response( - data=vm_info_serializer.data, + data={'resp_data': arr}, status=status.HTTP_200_OK) except Exception as e: - logger.error(e.message) + logger.error(e.args[0]) logger.error(traceback.format_exc()) return Response( data={ @@ -293,7 +293,7 @@ class getFlavors(APIView): data=flavor_info_serializer.data, status=status.HTTP_200_OK) except Exception as e: - logger.error(e.message) + logger.error(e.args[0]) logger.error(traceback.format_exc()) return Response( data={ @@ -344,7 +344,7 @@ class getNetworks(APIView): data=network_info_serializer.data, status=status.HTTP_200_OK) except Exception as e: - logger.error(e.message) + logger.error(e.args[0]) logger.error(traceback.format_exc()) return Response( data={ @@ -390,7 +390,7 @@ class getSubnets(APIView): data=subnet_info_serializer.data, status=status.HTTP_200_OK) except Exception as e: - logger.error(e.message) + logger.error(e.args[0]) logger.error(traceback.format_exc()) return Response( data={ @@ -438,7 +438,7 @@ class getCps(APIView): data=cp_info_serializer.data, status=status.HTTP_200_OK) except Exception as e: - logger.error(e.message) + logger.error(e.args[0]) logger.error(traceback.format_exc()) return Response( data={ @@ -485,7 +485,7 @@ class getVolumes(APIView): data=volume_serializer.data, status=status.HTTP_200_OK) except Exception as e: - logger.error(e.message) + logger.error(e.args[0]) logger.error(traceback.format_exc()) return Response( data={ diff --git a/res/res/settings.py b/res/res/settings.py index 8884481..d5e487d 100644 --- a/res/res/settings.py +++ b/res/res/settings.py @@ -16,7 +16,7 @@ import os import sys import platform -import redisco +import res.pub.redisco from res.pub.config.config import REDIS_HOST, REDIS_PORT, REDIS_PASSWD from res.pub.config.config import DB_NAME, DB_IP, DB_USER, DB_PASSWD, DB_PORT @@ -54,16 +54,15 @@ INSTALLED_APPS = [ 'drf_yasg', ] -MIDDLEWARE_CLASSES = [ +MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'res.middleware.LogContextMiddleware', + 'res.middleware.LogContextMiddleware' ] ROOT_URLCONF = 'res.urls' @@ -115,7 +114,7 @@ DATABASES = { }, } -redisco.connection_setup(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWD, db=0) +res.pub.redisco.connection_setup(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWD, db=0) # CACHE_BACKEND = 'redis_cache.cache://%s@%s:%s' % (REDIS_PASSWD, REDIS_HOST, REDIS_PORT) TIME_ZONE = 'UTC' diff --git a/res/tox.ini b/res/tox.ini index f2cdb3c..13e2837 100644 --- a/res/tox.ini +++ b/res/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27,pep8,cov +envlist = py36,pep8,cov skipsdist = true [tox:jenkins] @@ -18,9 +18,10 @@ commands = coverage run --branch manage.py test res deps = flake8 commands = flake8 -[testenv:py27] +[testenv:py36] commands = {[testenv]commands} [testenv:cov] +deps = coverage commands = coverage xml --omit="*test*,*__init__.py,*site-packages*" \ No newline at end of file -- 2.16.6