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:
parent
6ac96952e0
commit
2d92166d3d
54
octavia/common/decorators.py
Normal file
54
octavia/common/decorators.py
Normal 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
|
56
octavia/tests/unit/common/test_decorator.py
Normal file
56
octavia/tests/unit/common/test_decorator.py
Normal 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)
|
Loading…
Reference in New Issue
Block a user