Passed
Pull Request — master (#248)
by Antonio
02:33
created

build.storehouse   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Test Coverage

Coverage 83.58%

Importance

Changes 0
Metric Value
eloc 78
dl 0
loc 113
ccs 56
cts 67
cp 0.8358
rs 10
c 0
b 0
f 0
wmc 19

11 Methods

Rating   Name   Duplication   Size   Complexity  
A StoreHouse.__new__() 0 9 2
A StoreHouse.__init__() 0 9 3
A StoreHouse.get_data() 0 6 2
A StoreHouse.get_stored_box() 0 10 1
A StoreHouse.create_box() 0 8 1
A StoreHouse._get_or_create_a_box_from_list_of_boxes() 0 6 2
A StoreHouse._get_box_callback() 0 7 2
A StoreHouse._save_evc_callback() 0 8 2
A StoreHouse.list_stored_boxes() 0 9 1
A StoreHouse._create_box_callback() 0 7 2
A StoreHouse.save_evc() 0 13 1
1
"""Module to handle the storehouse."""
2 1
import threading
3
4 1
from kytos.core import log
5 1
from kytos.core.events import KytosEvent
6
7
8 1
class StoreHouse:
9
    """Class to handle storehouse."""
10
11 1
    @classmethod
12
    def __new__(cls, *args, **kwargs):
13
        # pylint: disable=unused-argument
14
        """Make this class a Singleton."""
15 1
        instance = cls.__dict__.get("__instance__")
16 1
        if instance is not None:
17 1
            return instance
18 1
        cls.__instance__ = instance = object.__new__(cls)
19 1
        return instance
20
21 1
    def __init__(self, controller):
22
        """Create a storehouse instance."""
23 1
        self.controller = controller
24 1
        self.namespace = 'kytos.mef_eline.circuits'
25 1
        if '_lock' not in self.__dict__:
26 1
            self._lock = threading.Lock()
27 1
        if 'box' not in self.__dict__:
28 1
            self.box = None
29 1
        self.list_stored_boxes()
30
31 1
    def get_data(self):
32
        """Return the box data."""
33 1
        if not self.box:
34 1
            return {}
35 1
        self.get_stored_box(self.box.box_id)
36 1
        return self.box.data
37
38 1
    def create_box(self):
39
        """Create a new box."""
40 1
        content = {'namespace': self.namespace,
41
                   'callback': self._create_box_callback,
42
                   'data': {}}
43 1
        event = KytosEvent(name='kytos.storehouse.create', content=content)
44 1
        self.controller.buffers.app.put(event)
45 1
        log.info('Create box from storehouse.')
46
47 1
    def _create_box_callback(self, _event, data, error):
48
        """Execute the callback to handle create_box."""
49
        if error:
50
            log.error(f'Can\'t create box with namespace {self.namespace}')
51
52
        self.box = data
53
        log.info(f'Box {self.box.box_id} was created in {self.namespace}.')
54
55 1
    def list_stored_boxes(self):
56
        """List all boxes using the current namespace."""
57 1
        name = 'kytos.storehouse.list'
58 1
        content = {'namespace': self.namespace,
59
                   'callback': self._get_or_create_a_box_from_list_of_boxes}
60
61 1
        event = KytosEvent(name=name, content=content)
62 1
        self.controller.buffers.app.put(event)
63 1
        log.debug(f'Bootstraping storehouse box for {self.namespace}.')
64
65 1
    def _get_or_create_a_box_from_list_of_boxes(self, _event, data, _error):
66
        """Create a new box or retrieve the stored box."""
67
        if data:
68
            self.get_stored_box(data[0])
69
        else:
70
            self.create_box()
71
72 1
    def get_stored_box(self, box_id):
73
        """Get box from storehouse."""
74 1
        content = {'namespace': self.namespace,
75
                   'callback': self._get_box_callback,
76
                   'box_id': box_id,
77
                   'data': {}}
78 1
        name = 'kytos.storehouse.retrieve'
79 1
        event = KytosEvent(name=name, content=content)
80 1
        self.controller.buffers.app.put(event)
81 1
        log.debug(f'Retrieve box with {box_id} from {self.namespace}.')
82
83 1
    def _get_box_callback(self, _event, data, error):
84
        """Handle get_box method saving the box or logging with the error."""
85
        if error:
86
            log.error(f'Box {data.box_id} not found in {self.namespace}.')
87
88
        self.box = data
89
        log.debug(f'Box {self.box.box_id} was loaded from storehouse.')
90
91 1
    def save_evc(self, evc):
92
        """Save a EVC using the storehouse."""
93 1
        self._lock.acquire()  # Lock to avoid race condition
94 1
        log.debug(f'Lock {self._lock} acquired.')
95 1
        self.box.data[evc.id] = evc.as_dict()
96
97 1
        content = {'namespace': self.namespace,
98
                   'box_id': self.box.box_id,
99
                   'data': self.box.data,
100
                   'callback': self._save_evc_callback}
101
102 1
        event = KytosEvent(name='kytos.storehouse.update', content=content)
103 1
        self.controller.buffers.app.put(event)
104
105 1
    def _save_evc_callback(self, _event, data, error):
106
        """Display the save EVC result in the log."""
107 1
        self._lock.release()
108 1
        log.debug(f'Lock {self._lock} released.')
109 1
        if error:
110 1
            log.error(f'Can\'t update the {self.box.box_id}')
111
112
        log.info(f'Box {data.box_id} was updated.')
113