build.storehouse.StoreHouse.__init__()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 8
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 7
nop 2
dl 0
loc 8
ccs 7
cts 7
cp 1
crap 2
rs 10
c 0
b 0
f 0
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
        self._lock = threading.Lock()
26 1
        if 'box' not in self.__dict__:
27 1
            self.box = None
28 1
        self.list_stored_boxes()
29
30 1
    def get_data(self):
31
        """Return the box data."""
32 1
        if not self.box:
33 1
            return {}
34 1
        self.get_stored_box(self.box.box_id)
35 1
        return self.box.data
36
37 1
    def create_box(self):
38
        """Create a new box."""
39 1
        content = {'namespace': self.namespace,
40
                   'callback': self._create_box_callback,
41
                   'data': {}}
42 1
        event = KytosEvent(name='kytos.storehouse.create', content=content)
43 1
        self.controller.buffers.app.put(event)
44 1
        log.info('Create box from storehouse.')
45
46 1
    def _create_box_callback(self, _event, data, error):
47
        """Execute the callback to handle create_box."""
48
        if error:
49
            log.error(f'Can\'t create box with namespace {self.namespace}')
50
51
        self.box = data
52
        log.info(f'Box {self.box.box_id} was created in {self.namespace}.')
53
54 1
    def list_stored_boxes(self):
55
        """List all boxes using the current namespace."""
56 1
        name = 'kytos.storehouse.list'
57 1
        content = {'namespace': self.namespace,
58
                   'callback': self._get_or_create_a_box_from_list_of_boxes}
59
60 1
        event = KytosEvent(name=name, content=content)
61 1
        self.controller.buffers.app.put(event)
62 1
        log.debug(f'Bootstraping storehouse box for {self.namespace}.')
63
64 1
    def _get_or_create_a_box_from_list_of_boxes(self, _event, data, _error):
65
        """Create a new box or retrieve the stored box."""
66
        if data:
67
            self.get_stored_box(data[0])
68
        else:
69
            self.create_box()
70
71 1
    def get_stored_box(self, box_id):
72
        """Get box from storehouse."""
73 1
        content = {'namespace': self.namespace,
74
                   'callback': self._get_box_callback,
75
                   'box_id': box_id,
76
                   'data': {}}
77 1
        name = 'kytos.storehouse.retrieve'
78 1
        event = KytosEvent(name=name, content=content)
79 1
        self.controller.buffers.app.put(event)
80 1
        log.debug(f'Retrieve box with {box_id} from {self.namespace}.')
81
82 1
    def _get_box_callback(self, _event, data, error):
83
        """Handle get_box method saving the box or logging with the error."""
84
        if error:
85
            log.error(f'Box {data.box_id} not found in {self.namespace}.')
86
87
        self.box = data
88
        log.debug(f'Box {self.box.box_id} was loaded from storehouse.')
89
90 1
    def save_evc(self, evc):
91
        """Save a EVC using the storehouse."""
92 1
        self._lock.acquire()  # Lock to avoid race condition
93 1
        log.debug(f'Lock {self._lock} acquired.')
94 1
        self.box.data[evc.id] = evc.as_dict()
95
96 1
        content = {'namespace': self.namespace,
97
                   'box_id': self.box.box_id,
98
                   'data': self.box.data,
99
                   'callback': self._save_evc_callback}
100
101 1
        event = KytosEvent(name='kytos.storehouse.update', content=content)
102 1
        self.controller.buffers.app.put(event)
103
104 1
    def _save_evc_callback(self, _event, data, error):
105
        """Display the save EVC result in the log."""
106 1
        self._lock.release()
107 1
        log.debug(f'Lock {self._lock} released.')
108 1
        if error:
109 1
            log.error(f'Can\'t update the {self.box.box_id}')
110
111
        log.info(f'Box {data.box_id} was updated.')
112