From 98452ba62ec0be7ffafeee31daade696f7772c68 Mon Sep 17 00:00:00 2001 From: Evgeniy L Date: Thu, 17 Mar 2016 17:16:38 +0300 Subject: [PATCH] Common initialisation logic into Base Object --- bareon_dynamic_allocator/errors.py | 4 ++ bareon_dynamic_allocator/objects/base.py | 47 +++++++++++++++++++++++ bareon_dynamic_allocator/objects/disk.py | 11 ++++-- bareon_dynamic_allocator/objects/space.py | 26 ++++++------- 4 files changed, 69 insertions(+), 19 deletions(-) diff --git a/bareon_dynamic_allocator/errors.py b/bareon_dynamic_allocator/errors.py index 600e938..2d959ed 100644 --- a/bareon_dynamic_allocator/errors.py +++ b/bareon_dynamic_allocator/errors.py @@ -19,3 +19,7 @@ class BareonDynamicAllocator(Exception): class NoSolutionFound(BareonDynamicAllocator): pass + + +class InvalidData(BareonDynamicAllocator): + pass diff --git a/bareon_dynamic_allocator/objects/base.py b/bareon_dynamic_allocator/objects/base.py index 2a2d50e..eef17ae 100644 --- a/bareon_dynamic_allocator/objects/base.py +++ b/bareon_dynamic_allocator/objects/base.py @@ -16,9 +16,56 @@ import abc +from copy import deepcopy + +from bareon_dynamic_allocator import errors + import six @six.add_metaclass(abc.ABCMeta) class BaseObject(object): """Base class for Bareon Allocator Objects.""" + + def __init__(self, **kwargs): + self.init_data = deepcopy(kwargs) + self.additional_parameters = {} + + # Fail if required property is not specified + if not set(self.required) <= set(kwargs.keys()): + required_properties = set(self.required) - set(kwargs.keys()) + raise errors.InvalidData( + 'Cannot create object with parameters "{0}", because ' + 'required parameters are not provided {1}'.format( + self.init_data, + required_properties)) + + # Set default properties for the object + for k, v in six.iteritems(self.properties): + setattr(self, k, v) + + # Override properties with data from parameters + for k, v in six.iteritems(self.init_data): + if k in self.properties.keys(): + setattr(self, k, v) + else: + self.additional_parameters[k] = v + + def __repr__(self): + return str(self.init_data) + + @abc.abstractproperty + def properties(self): + """Set object properties. + + Should be dictionary, example + + { + 'property': default_value + } + """ + + @property + def required(self): + """A list of required properties.""" + return [] diff --git a/bareon_dynamic_allocator/objects/disk.py b/bareon_dynamic_allocator/objects/disk.py index e6dd842..760083d 100644 --- a/bareon_dynamic_allocator/objects/disk.py +++ b/bareon_dynamic_allocator/objects/disk.py @@ -16,11 +16,14 @@ from bareon_dynamic_allocator.objects import BaseObject -import six - class Disk(BaseObject): + properties = { + 'id': None, + 'size': 0, + } + required_properties = ['id'] + def __init__(self, **kwargs): - for k, v in six.iteritems(kwargs): - setattr(self, k, v) + super(Disk, self).__init__(**kwargs) diff --git a/bareon_dynamic_allocator/objects/space.py b/bareon_dynamic_allocator/objects/space.py index 014255a..62d1254 100644 --- a/bareon_dynamic_allocator/objects/space.py +++ b/bareon_dynamic_allocator/objects/space.py @@ -16,26 +16,22 @@ from bareon_dynamic_allocator.objects import BaseObject -import six - class Space(BaseObject): + properties = { + 'id': None, + 'min_size': 0, + 'max_size': None, + 'best_with_disks': set([]), + 'weight': 1 + } + required = ['id'] + def __init__(self, **kwargs): - for k, v in six.iteritems(kwargs): - setattr(self, k, v) + super(Space, self).__init__(**kwargs) - # If no min_size specified set it to 0 - if not kwargs.get('min_size'): - self.min_size = 0 - - # Exact size can be repreneted as min_size and max_size + # Exact size should be repreneted as min_size and max_size if kwargs.get('size'): self.min_size = kwargs.get('size') self.max_size = kwargs.get('size') - - if not kwargs.get('best_with_disks'): - self.best_with_disks = set([]) - - def __repr__(self): - return str(self.__dict__)