Passed
Pull Request — master (#166)
by Antonio
03:24
created

build.storehouse.StoreHouse.save_evc()   A

Complexity

Conditions 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.6296

Importance

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