brcdBwSensor   B
last analyzed

Complexity

Total Complexity 43

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 123
rs 8.3157
c 0
b 0
f 0
wmc 43

13 Methods

Rating   Name   Duplication   Size   Complexity  
A add_trigger() 0 3 1
C _manage_bandwidth() 0 21 9
A update_trigger() 0 3 1
A poll() 0 10 2
A _monitor_bandwidth() 0 8 3
C _get_configs() 0 18 14
A remove_trigger() 0 3 1
A setup() 0 3 1
A _get_bw_tracker() 0 8 4
A __init__() 0 13 1
A cleanup() 0 4 1
A _issue_update() 0 9 3
A _set_bw_tracker() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like brcdBwSensor often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from st2reactor.sensor.base import PollingSensor
2
from lib.vadc import Bsd
3
4
import json
5
6
7
class brcdBwSensor(PollingSensor):
8
9
    def __init__(self, sensor_service, config=None, poll_interval=5):
10
        super(brcdBwSensor, self).__init__(sensor_service=sensor_service, config=config,
11
            poll_interval=poll_interval)
12
        self._logger = self.sensor_service.get_logger(name=self.__class__.__name__)
13
        self._stop = False
14
        self._bw_tracker = None
15
        self._bsd = None
16
        self._manage = None
17
        self._minimum = 10
18
        self._headroom = 10
19
        self._roundup = 10
20
        self._track = 10
21
        self._warn = 10
22
23
    def setup(self):
24
        self._bsd = Bsd(self._config, self._logger)
25
        self._bw_tracker = None
26
27
    def poll(self):
28
        self._get_configs()
29
        bandwidth = self._bsd.getBandwidth()
30
        bw_tracker = self._get_bw_tracker()
31
        if self._manage is not None:
32
            self._manage_bandwidth(bw_tracker, bandwidth)
33
        else:
34
            bw_tracker = {}
35
        self._monitor_bandwidth(bandwidth)
36
        self._set_bw_tracker(bw_tracker)
37
38
    def _get_configs(self):
39
        self._logger.debug(self._config)
40
        if "brcd_bw_minimum" in self._config and self._config["brcd_bw_minimum"] is not None:
41
            self._minimum = int(self._config["brcd_bw_minimum"])
42
        if "brcd_bw_roundup" in self._config and self._config["brcd_bw_roundup"] is not None:
43
            self._roundup = int(self._config["brcd_bw_roundup"])
44
        if "brcd_bw_headroom" in self._config and self._config["brcd_bw_headroom"] is not None:
45
            self._headroom = int(self._config["brcd_bw_headroom"])
46
        if "brcd_bw_track" in self._config and self._config["brcd_bw_track"] is not None:
47
            self._track = int(self._config["brcd_bw_track"])
48
        if "brcd_bw_warn" in self._config and self._config["brcd_bw_warn"] is not None:
49
            self._warn = int(self._config["brcd_bw_warn"])
50
        if "brcd_bw_manage" in self._config and self._config["brcd_bw_manage"] is not None:
51
            manage = str(self._config["brcd_bw_manage"])
52
            if manage.lower() == "all":
53
                self._manage = ["__ALL__"]
54
            else:
55
                self._manage = manage.split(',')
56
57
    def _manage_bandwidth(self, bw_tracker, bandwidth):
58
        for instance in bandwidth.keys():
59
            instData = bandwidth[instance]
60
            tag = instData["tag"]
61
            if "__ALL__" in self._manage or instance in self._manage or tag in self._manage:
62
                tracked = instData["current"]
63
                tracked += self._roundup - (tracked % self._roundup)
64
                if tracked < self._minimum:
65
                    tracked = self._minimum
66
                if instance not in bw_tracker:
67
                    bw_tracker[instance] = instData
68
                    bw_tracker[instance]["tracking"] = []
69
                while len(bw_tracker[instance]["tracking"]) >= self._track:
70
                    bw_tracker[instance]["tracking"].pop(0)
71
                bw_tracker[instance]["tracking"].append(tracked)
72
                bw_tracker[instance]["current"] = instData["current"]
73
                bw_tracker[instance]["peak"] = instData["peak"]
74
                self._issue_update(instance, tracked, instData, bw_tracker, bandwidth)
75
            else:
76
                if instance in bw_tracker:
77
                    bw_tracker.pop(instance)
78
79
    def _issue_update(self, instance, tracked, instData, bw_tracker, bandwidth):
80
            average = sum(bw_tracker[instance]["tracking"]) / len(bw_tracker[instance]["tracking"])
81
            assign = average if tracked < average else tracked
82
            assign = int(assign + self._headroom)
83
            if assign != instData["assigned"]:
84
                bw_tracker[instance]["assigned"] = assign
85
                payload = {"action": "update", "instance": instance, "tag": instData["tag"],
86
                    "bandwidth": assign, "current": instData["current"], "average": average}
87
                self.sensor_service.dispatch(trigger="vadc.bsd_bandwidth_event", payload=payload)
88
89
    def _monitor_bandwidth(self, bandwidth):
90
        for instance in bandwidth.keys():
91
            instData = bandwidth[instance]
92
            tag = instData["tag"]
93
            if instData["assigned"] - instData["current"] - self._warn <= 0:
94
                payload = {"action": "alert", "instance": instance, "tag": tag,
95
                    "bandwidth": instData["assigned"], "current": instData["current"]}
96
                self.sensor_service.dispatch(trigger="vadc.bsd_bandwidth_event", payload=payload)
97
98
    def _get_bw_tracker(self):
99
        if not self._bw_tracker and hasattr(self._sensor_service, 'get_value'):
100
            bw_tracker = self._sensor_service.get_value(name='bw_tracker')
101
            if bw_tracker is not None:
102
                self._bw_tracker = json.loads(bw_tracker, encoding="utf-8")
103
            else:
104
                self._bw_tracker = {}
105
        return self._bw_tracker
106
107
    def _set_bw_tracker(self, bw_tracker):
108
        self._bw_tracker = bw_tracker
109
110
        if hasattr(self._sensor_service, 'set_value'):
111
            self._sensor_service.set_value(name='bw_tracker', value=json.dumps(bw_tracker,
112
                encoding="utf-8"))
113
114
    def cleanup(self):
115
        # This is called when the st2 system goes down. You can perform cleanup operations like
116
        # closing the connections to external system here.
117
        pass
118
119
    def add_trigger(self, trigger):
120
        # This method is called when trigger is created
121
        pass
122
123
    def update_trigger(self, trigger):
124
        # This method is called when trigger is updated
125
        pass
126
127
    def remove_trigger(self, trigger):
128
        # This method is called when trigger is deleted
129
        pass
130