blob: d2f90eaad21790419c8942a32f165ff1467f69f9 [file] [log] [blame]
Matteo Scandolof0577ac2016-03-21 17:27:42 -07001/**
2 * © OpenCORD
3 *
4 * Visit http://guide.xosproject.org/devguide/addview/ for more information
5 *
6 * Created by teone on 3/21/16.
7 */
8
9(function () {
10 'use strict';
11
12 angular.module('xos.ceilometerDashboard')
Matteo Scandolo02f44d62016-09-19 17:17:58 -070013 .directive('ceilometerSamples', function(_, $stateParams, $interval){
Matteo Scandolof0577ac2016-03-21 17:27:42 -070014 return {
15 restrict: 'E',
16 scope: {},
17 bindToController: true,
18 controllerAs: 'vm',
19 templateUrl: 'templates/ceilometer-samples.tpl.html',
20 controller: function(Ceilometer) {
21
Matteo Scandolof0577ac2016-03-21 17:27:42 -070022 this.chartColors = [
23 '#286090',
24 '#F7464A',
25 '#46BFBD',
26 '#FDB45C',
27 '#97BBCD',
28 '#4D5360',
29 '#8c4f9f'
30 ];
31
32 this.chart = {
33 series: [],
34 labels: [],
35 data: []
36 }
37
38 Chart.defaults.global.colours = this.chartColors;
39
40 this.chartType = 'line';
41
Matteo Scandolo02f44d62016-09-19 17:17:58 -070042 // TODO
43 // check for name, if
44 // - broadview.pt.packet-trace-lag-resolution
45 // - broadview.pt.packet-trace-ecmp-resolution
46 // draw a pie
47
48 const pieStats = [
49 'broadview.pt.packet-trace-lag-resolution',
50 'broadview.pt.packet-trace-ecmp-resolution'
51 ];
52 let isApie = false;
53
54 let refreshInterval = 60 * 1000;
55
Matteo Scandolof0577ac2016-03-21 17:27:42 -070056 if($stateParams.name && $stateParams.tenant){
57 this.name = $stateParams.name;
Matteo Scandolo8420f622016-03-24 11:38:50 -070058 // TODO rename tenant in resource_id
Matteo Scandolo02f44d62016-09-19 17:17:58 -070059 this.tenant = $stateParams.tenant;
60
61 if(pieStats.indexOf(this.name) > -1){
62 isApie = true;
63 this.chartType = 'pie';
64 refreshInterval = 10 * 1000;
65 }
Matteo Scandolof0577ac2016-03-21 17:27:42 -070066 }
67 else{
68 throw new Error('Missing Name and Tenant Params!');
69 }
70
71 /**
72 * Goes trough the array and format date to be used as labels
73 *
74 * @param Array data
75 * @returns Array a list of labels
76 */
77
78 this.getLabels = (data) => {
79 return data.reduce((list, item) => {
80 let date = new Date(item.timestamp);
81 list.push(`${date.getHours()}:${(date.getMinutes()<10?'0':'') + date.getMinutes()}:${date.getSeconds()}`);
82 return list;
83 }, []);
84 };
85
86 /**
87 * Goes trough the array and return a flat array of values
88 *
89 * @param Array data
90 * @returns Array a list of values
91 */
92
93 this.getData = (data) => {
94 return data.reduce((list, item) => {
95 list.push(item.volume);
96 return list;
97 }, []);
98 }
99
100 /**
101 * Add a samples to the chart
102 *
103 * @param string resource_id
104 */
105 this.chartMeters = [];
106 this.addMeterToChart = (resource_id) => {
Matteo Scandoloa06d08d2017-01-17 17:33:28 -0800107 const resourcePos = _.findIndex(this.chartMeters, m => m.resource_id === resource_id);
108 // if this meter is not yet rendered
109 if (resourcePos < 0) {
110 this.chart['data'].push(this.getData(_.sortBy(this.samplesList[resource_id], 'timestamp')));
111 this.chart['labels'] = this.getLabels(_.sortBy(this.samplesList[resource_id], 'timestamp'));
112 this.chart['series'].push(resource_id);
113 this.chartMeters.push(this.samplesList[resource_id][0]); //use the 0 as are all samples for the same resource and I need the name
114 _.remove(this.sampleLabels, {id: resource_id});
115 }
116 else {
117 this.chart['data'][resourcePos] = this.getData(_.sortBy(this.samplesList[resource_id], 'timestamp'));
118 this.chart['labels'] = this.getLabels(_.sortBy(this.samplesList[resource_id], 'timestamp'));
119 this.chart['series'][resourcePos] = resource_id;
120 }
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700121 }
122
123 this.removeFromChart = (meter) => {
124 this.chart.data.splice(this.chart.series.indexOf(meter.resource_id), 1);
125 this.chart.series.splice(this.chart.series.indexOf(meter.resource_id), 1);
Matteo Scandolo54bc5f72016-05-18 14:06:45 -0700126 this.chartMeters.splice(_.findIndex(this.chartMeters, {resource_id: meter.resource_id}), 1);
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700127 this.sampleLabels.push({
128 id: meter.resource_id,
129 name: meter.resource_name || meter.resource_id
130 })
131 };
132
133 /**
134 * Format samples to create a list of labels and ids
135 */
136
137 this.formatSamplesLabels = (samples) => {
138
Matteo Scandolo54bc5f72016-05-18 14:06:45 -0700139 return _.uniq(samples, 'resource_id')
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700140 .reduce((labels, item) => {
141 labels.push({
142 id: item.resource_id,
143 name: item.resource_name || item.resource_id
144 });
145
146 return labels;
147 }, []);
148 }
149
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700150 /**
151 * Format data series in pie chart val
152 */
153
154 this.formatPieChartData = (samples) => {
155
156 this.chart['labels'] = samples[0].metadata['lag-members'].replace(/\[|\]|'| /g, '').split(',');
157 this.chart.options = {
158 legend: {
159 display: true
160 }
161 };
162 samples = _.groupBy(samples, i => i.metadata['dst-lag-member']);
163
164 // TODO show percentage in pie
165 Chart.defaults.global.tooltipTemplate = '<%if (label){%><%=label%>: <%}%><%= value %>%';
166
167 let data = _.reduce(this.chart.labels, (data, item) => {
168 let length = samples[item] ? samples[item].length : 0;
169 data.push(length);
170 return data;
171 }, []);
172
173 let total = _.reduce(data, (d, t) => d + t);
174
175 let percent = _.map(data, d => Math.round((d / total) * 100));
176
177 console.log(total);
178
179 this.chart['data'] = percent;
180 };
181
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700182
183 /**
184 * Load the samples and format data
185 */
186
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700187 this.loader = true;
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700188 this.showSamples = () => {
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700189 // Ceilometer.getSamples(this.name, this.tenant) //fetch one
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700190 let p;
191 if (isApie){
192 p = Ceilometer.getSamples(this.name, 30) //fetch all
193 }
194 else{
195 p = Ceilometer.getSamples(this.name) //fetch all
196 }
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700197
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700198 p.then(res => {
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700199
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700200 // rename things in UI
201 res.map(m => {
202 m.resource_name = m.resource_name.replace('mysite_onos_vbng', 'ONOS_FABRIC');
203 m.resource_name = m.resource_name.replace('mysite_onos_volt', 'ONOS_CORD');
204 m.resource_name = m.resource_name.replace('mysite_vbng', 'mysite_vRouter');
205 return m;
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700206 });
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700207 // end rename things in UI
208
209 // if I have to draw a pie skip the rest
210 if(isApie){
211
212 // TODO format data as pie
213 this.formatPieChartData(res);
214 return;
215 }
216
217 // setup data for visualization
218 this.samplesList = _.groupBy(res, 'resource_id');
219 this.sampleLabels = this.formatSamplesLabels(res);
220
221 // add current meter to chart
222 this.addMeterToChart(this.tenant);
223
224 })
225 .catch(err => {
226 this.error = err.data.detail;
227 })
228 .finally(() => {
229 this.loader = false;
230 });
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700231 };
232
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700233 $interval(() => {
234 this.showSamples();
235 }, refreshInterval)
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700236 this.showSamples();
237 }
238 }
239 });
240})();
241