Introduce API Decorators

Decorators will be used for backwards compatibility with
API v1. Will be needed when doing translations for alignment
of V2 API with LBaaSv2

Change-Id: If98e4dd2b667149b7404a6378e798537684d405d
Co-Authored-By: Brandon Logan <brandon.logan@rackspace.com>
Co-Authored-By: Sindhu Devale <sindhu.devale@intel.com>
This commit is contained in:
Ankur Gupta 2016-12-01 14:29:40 -06:00 committed by Ankur
parent 6ac96952e0
commit 2d92166d3d
2 changed files with 110 additions and 0 deletions

View File

@ -0,0 +1,54 @@
# Copyright 2016
# All Rights Reserved.
#
# 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.
"""Decorators to provide backwards compatibility for V1 API."""
def rename_kwargs(**renamed_kwargs):
"""Renames a class's variables and maintains backwards compatibility.
:param renamed_kwargs: mapping of old kwargs to new kwargs. For example,
to say a class has renamed variable foo to bar the decorator would
be used like: rename_kwargs(foo='bar')
"""
def wrap(cls):
def __getattr__(instance, name):
if name in renamed_kwargs:
return getattr(instance, renamed_kwargs[name])
return getattr(instance, name)
def __setattr__(instance, name, value):
if name in renamed_kwargs:
instance.__dict__[renamed_kwargs[name]] = value
else:
instance.__dict__[name] = value
def wrapped_cls(*args, **kwargs):
# Handle cases of inner classes being called with self
# For example: self.TestClass(1, a=1)
if (args and hasattr(args[0], '__class__') and
hasattr(args[0].__class__, cls.__name__)):
args = args[1:] if args else tuple()
for old_kwarg, new_kwarg in renamed_kwargs.items():
if old_kwarg in kwargs:
kwargs[new_kwarg] = kwargs[old_kwarg]
del kwargs[old_kwarg]
cls.__getattr__ = __getattr__
cls.__setattr__ = __setattr__
return cls(*args, **kwargs)
return wrapped_cls
return wrap

View File

@ -0,0 +1,56 @@
# Copyright 2016
# All Rights Reserved.
#
# 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.
"""Test for the decorator which provides backward compatibility for V1 API."""
import octavia.common.decorators as dec
import octavia.tests.unit.base as base
class TestDecorator(base.TestCase):
@dec.rename_kwargs(a='z')
class TestClass(object):
def __init__(self, x, z=None):
self.x = x
self.z = z
@dec.rename_kwargs(a='z')
class TestClassDupe(object):
def __init__(self, x, z=None):
self.x = x
self.z = z
def test_get(self):
obj = self.TestClass(1, a=3)
self.assertEqual(1, obj.x)
self.assertEqual(3, obj.z)
self.assertEqual(obj.z, obj.a)
def test_set(self):
obj = self.TestClass(1, a=3)
obj.a = 5
self.assertEqual(1, obj.x)
self.assertEqual(5, obj.z)
self.assertEqual(obj.z, obj.a)
def test_similar_classes(self):
obj = self.TestClass(1, z=5)
obj2 = self.TestClassDupe(2, z=10)
self.assertEqual(5, obj.z)
self.assertEqual(10, obj2.z)
self.assertEqual(obj.z, obj.a)
self.assertEqual(obj2.z, obj2.a)