Passed
Pull Request — master (#123)
by Carlos
03:00
created

build.storehouse   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Test Coverage

Coverage 79.69%

Importance

Changes 0
Metric Value
eloc 77
dl 0
loc 116
ccs 51
cts 64
cp 0.7969
rs 10
c 0
b 0
f 0
wmc 20

11 Methods

Rating   Name   Duplication   Size   Complexity  
A StoreHouse.__init__() 0 11 2
A StoreHouse._save_status_callback() 0 6 2
A StoreHouse.get_data() 0 11 4
A StoreHouse.get_stored_box() 0 9 1
A StoreHouse.create_box() 0 7 1
A StoreHouse._get_or_create_a_box_from_list_of_boxes() 0 6 2
A StoreHouse._get_box_callback() 0 6 2
A StoreHouse.list_stored_boxes() 0 8 1
A StoreHouse._create_box_callback() 0 7 2
A StoreHouse.__new__() 0 9 2
A StoreHouse.save_status() 0 11 1
1
"""Module to handle the storehouse."""
2 1
import time
3
4 1
from kytos.core import log
5 1
from kytos.core.events import KytosEvent
6 1
from napps.kytos.topology import settings
7
8 1
DEFAULT_WAIT_PERSISTENCE_BOX_TIMER = 0.1
9 1
ATTEMPT_GET_PERSISTENCE_BOX = 20
10
11
12 1
class StoreHouse:
13
    """Class to handle storehouse."""
14
15 1
    @classmethod
16
    def __new__(cls, *args, **kwargs):
17
        # pylint: disable=unused-argument
18
        """Make this class a Singleton."""
19 1
        instance = cls.__dict__.get("__instance__")
20 1
        if instance is not None:
21 1
            return instance
22 1
        cls.__instance__ = instance = object.__new__(cls)
23 1
        return instance
24
25 1
    def __init__(self, controller):
26
        """Create a storehouse client instance."""
27 1
        self.controller = controller
28 1
        self.namespace = 'kytos.topology.status'
29 1
        self.wait_persistence_box = getattr(settings,
30
                                            'WAIT_PERSISTENCE_BOX_TIMER',
31
                                            DEFAULT_WAIT_PERSISTENCE_BOX_TIMER)
32
33 1
        if 'box' not in self.__dict__:
34 1
            self.box = None
35 1
        self.list_stored_boxes()
36
37 1
    def get_data(self):
38
        """Return the persistence box data."""
39
        # Wait retrieve or create box in storehouse
40 1
        limits = 0
41 1
        while not self.box and limits < ATTEMPT_GET_PERSISTENCE_BOX:
42
            time.sleep(self.wait_persistence_box)
43
            limits += 1
44 1
        if self.box:
45 1
            return self.box.data
46
        error = 'Error retrieving persistence box from storehouse.'
47
        raise FileNotFoundError(error)
48
49 1
    def create_box(self):
50
        """Create a persistence box to store administrative changes."""
51 1
        content = {'namespace': self.namespace,
52
                   'callback': self._create_box_callback,
53
                   'data': {}}
54 1
        event = KytosEvent(name='kytos.storehouse.create', content=content)
55 1
        self.controller.buffers.app.put(event)
56
57 1
    def _create_box_callback(self, _event, data, error):
58
        """Execute the callback to handle create_box."""
59
        if error:
60
            log.error(f'Can\'t create persistence'
61
                      f'box with namespace {self.namespace}')
62
63
        self.box = data
64
65 1
    def list_stored_boxes(self):
66
        """List all persistence box stored in storehouse."""
67 1
        name = 'kytos.storehouse.list'
68 1
        content = {'namespace': self.namespace,
69
                   'callback': self._get_or_create_a_box_from_list_of_boxes}
70
71 1
        event = KytosEvent(name=name, content=content)
72 1
        self.controller.buffers.app.put(event)
73
74 1
    def _get_or_create_a_box_from_list_of_boxes(self, _event, data, _error):
75
        """Create a persistence box or retrieve the stored box."""
76 1
        if data:
77 1
            self.get_stored_box(data[0])
78
        else:
79 1
            self.create_box()
80
81 1
    def get_stored_box(self, box_id):
82
        """Get persistence box from storehouse."""
83 1
        content = {'namespace': self.namespace,
84
                   'callback': self._get_box_callback,
85
                   'box_id': box_id,
86
                   'data': {}}
87 1
        name = 'kytos.storehouse.retrieve'
88 1
        event = KytosEvent(name=name, content=content)
89 1
        self.controller.buffers.app.put(event)
90
91 1
    def _get_box_callback(self, _event, data, error):
92
        """Handle get_box method saving the box or logging with the error."""
93
        if error:
94
            log.error('Persistence box not found.')
95
96
        self.box = data
97
98 1
    def save_status(self, status):
99
        """Save the network administrative status using storehouse."""
100 1
        self.box.data[status.get('id')] = status
101
102 1
        content = {'namespace': self.namespace,
103
                   'box_id': self.box.box_id,
104
                   'data': self.box.data,
105
                   'callback': self._save_status_callback}
106
107 1
        event = KytosEvent(name='kytos.storehouse.update', content=content)
108 1
        self.controller.buffers.app.put(event)
109
110 1
    def _save_status_callback(self, _event, data, error):
111
        """Display the saved network status in the log."""
112
        if error:
113
            log.error(f'Can\'t update persistence box {data.box_id}.')
114
115
        log.info('Network administrative status saved in '
116
                 f'{self.namespace}.{data.box_id}')
117