blob: 470667d8616655ca8b7981fd326c0a401cca4708 [file] [log] [blame]
Matteo Scandolod2044a42017-08-07 16:08:28 -07001
2/*
3 * Copyright 2017-present Open Networking Foundation
4
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8
9 * http://www.apache.org/licenses/LICENSE-2.0
10
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
Matteo Scandolof0577ac2016-03-21 17:27:42 -070019/**
20 * © OpenCORD
21 *
22 * Visit http://guide.xosproject.org/devguide/addview/ for more information
23 *
24 * Created by teone on 3/21/16.
25 */
26
27(function () {
28 'use strict';
29
30 angular.module('xos.ceilometerDashboard')
Matteo Scandolo02f44d62016-09-19 17:17:58 -070031 .directive('ceilometerSamples', function(_, $stateParams, $interval){
Matteo Scandolof0577ac2016-03-21 17:27:42 -070032 return {
33 restrict: 'E',
34 scope: {},
35 bindToController: true,
36 controllerAs: 'vm',
37 templateUrl: 'templates/ceilometer-samples.tpl.html',
38 controller: function(Ceilometer) {
39
Matteo Scandolof0577ac2016-03-21 17:27:42 -070040 this.chartColors = [
41 '#286090',
42 '#F7464A',
43 '#46BFBD',
44 '#FDB45C',
45 '#97BBCD',
46 '#4D5360',
47 '#8c4f9f'
48 ];
49
50 this.chart = {
51 series: [],
52 labels: [],
53 data: []
54 }
55
56 Chart.defaults.global.colours = this.chartColors;
57
58 this.chartType = 'line';
59
Matteo Scandolo02f44d62016-09-19 17:17:58 -070060 // TODO
61 // check for name, if
62 // - broadview.pt.packet-trace-lag-resolution
63 // - broadview.pt.packet-trace-ecmp-resolution
64 // draw a pie
65
66 const pieStats = [
67 'broadview.pt.packet-trace-lag-resolution',
68 'broadview.pt.packet-trace-ecmp-resolution'
69 ];
70 let isApie = false;
71
72 let refreshInterval = 60 * 1000;
73
Matteo Scandolof0577ac2016-03-21 17:27:42 -070074 if($stateParams.name && $stateParams.tenant){
75 this.name = $stateParams.name;
Matteo Scandolo8420f622016-03-24 11:38:50 -070076 // TODO rename tenant in resource_id
Matteo Scandolo02f44d62016-09-19 17:17:58 -070077 this.tenant = $stateParams.tenant;
78
79 if(pieStats.indexOf(this.name) > -1){
80 isApie = true;
81 this.chartType = 'pie';
82 refreshInterval = 10 * 1000;
83 }
Matteo Scandolof0577ac2016-03-21 17:27:42 -070084 }
85 else{
86 throw new Error('Missing Name and Tenant Params!');
87 }
88
89 /**
90 * Goes trough the array and format date to be used as labels
91 *
92 * @param Array data
93 * @returns Array a list of labels
94 */
95
96 this.getLabels = (data) => {
97 return data.reduce((list, item) => {
98 let date = new Date(item.timestamp);
99 list.push(`${date.getHours()}:${(date.getMinutes()<10?'0':'') + date.getMinutes()}:${date.getSeconds()}`);
100 return list;
101 }, []);
102 };
103
104 /**
105 * Goes trough the array and return a flat array of values
106 *
107 * @param Array data
108 * @returns Array a list of values
109 */
110
111 this.getData = (data) => {
112 return data.reduce((list, item) => {
113 list.push(item.volume);
114 return list;
115 }, []);
116 }
117
118 /**
119 * Add a samples to the chart
120 *
121 * @param string resource_id
122 */
123 this.chartMeters = [];
124 this.addMeterToChart = (resource_id) => {
Matteo Scandoloa06d08d2017-01-17 17:33:28 -0800125 const resourcePos = _.findIndex(this.chartMeters, m => m.resource_id === resource_id);
126 // if this meter is not yet rendered
127 if (resourcePos < 0) {
128 this.chart['data'].push(this.getData(_.sortBy(this.samplesList[resource_id], 'timestamp')));
129 this.chart['labels'] = this.getLabels(_.sortBy(this.samplesList[resource_id], 'timestamp'));
130 this.chart['series'].push(resource_id);
131 this.chartMeters.push(this.samplesList[resource_id][0]); //use the 0 as are all samples for the same resource and I need the name
132 _.remove(this.sampleLabels, {id: resource_id});
133 }
134 else {
135 this.chart['data'][resourcePos] = this.getData(_.sortBy(this.samplesList[resource_id], 'timestamp'));
136 this.chart['labels'] = this.getLabels(_.sortBy(this.samplesList[resource_id], 'timestamp'));
137 this.chart['series'][resourcePos] = resource_id;
138 }
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700139 }
140
141 this.removeFromChart = (meter) => {
142 this.chart.data.splice(this.chart.series.indexOf(meter.resource_id), 1);
143 this.chart.series.splice(this.chart.series.indexOf(meter.resource_id), 1);
Matteo Scandolo54bc5f72016-05-18 14:06:45 -0700144 this.chartMeters.splice(_.findIndex(this.chartMeters, {resource_id: meter.resource_id}), 1);
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700145 this.sampleLabels.push({
146 id: meter.resource_id,
147 name: meter.resource_name || meter.resource_id
148 })
149 };
150
151 /**
152 * Format samples to create a list of labels and ids
153 */
154
155 this.formatSamplesLabels = (samples) => {
156
Matteo Scandolo54bc5f72016-05-18 14:06:45 -0700157 return _.uniq(samples, 'resource_id')
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700158 .reduce((labels, item) => {
159 labels.push({
160 id: item.resource_id,
161 name: item.resource_name || item.resource_id
162 });
163
164 return labels;
165 }, []);
166 }
167
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700168 /**
169 * Format data series in pie chart val
170 */
171
172 this.formatPieChartData = (samples) => {
173
174 this.chart['labels'] = samples[0].metadata['lag-members'].replace(/\[|\]|'| /g, '').split(',');
175 this.chart.options = {
176 legend: {
177 display: true
178 }
179 };
180 samples = _.groupBy(samples, i => i.metadata['dst-lag-member']);
181
182 // TODO show percentage in pie
183 Chart.defaults.global.tooltipTemplate = '<%if (label){%><%=label%>: <%}%><%= value %>%';
184
185 let data = _.reduce(this.chart.labels, (data, item) => {
186 let length = samples[item] ? samples[item].length : 0;
187 data.push(length);
188 return data;
189 }, []);
190
191 let total = _.reduce(data, (d, t) => d + t);
192
193 let percent = _.map(data, d => Math.round((d / total) * 100));
194
195 console.log(total);
196
197 this.chart['data'] = percent;
198 };
199
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700200
201 /**
202 * Load the samples and format data
203 */
204
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700205 this.loader = true;
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700206 this.showSamples = () => {
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700207 // Ceilometer.getSamples(this.name, this.tenant) //fetch one
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700208 let p;
209 if (isApie){
210 p = Ceilometer.getSamples(this.name, 30) //fetch all
211 }
212 else{
213 p = Ceilometer.getSamples(this.name) //fetch all
214 }
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700215
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700216 p.then(res => {
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700217
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700218 // rename things in UI
219 res.map(m => {
220 m.resource_name = m.resource_name.replace('mysite_onos_vbng', 'ONOS_FABRIC');
221 m.resource_name = m.resource_name.replace('mysite_onos_volt', 'ONOS_CORD');
222 m.resource_name = m.resource_name.replace('mysite_vbng', 'mysite_vRouter');
223 return m;
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700224 });
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700225 // end rename things in UI
226
227 // if I have to draw a pie skip the rest
228 if(isApie){
229
230 // TODO format data as pie
231 this.formatPieChartData(res);
232 return;
233 }
234
235 // setup data for visualization
236 this.samplesList = _.groupBy(res, 'resource_id');
237 this.sampleLabels = this.formatSamplesLabels(res);
238
239 // add current meter to chart
240 this.addMeterToChart(this.tenant);
241
242 })
243 .catch(err => {
244 this.error = err.data.detail;
245 })
246 .finally(() => {
247 this.loader = false;
248 });
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700249 };
250
Matteo Scandolo02f44d62016-09-19 17:17:58 -0700251 $interval(() => {
252 this.showSamples();
253 }, refreshInterval)
Matteo Scandolof0577ac2016-03-21 17:27:42 -0700254 this.showSamples();
255 }
256 }
257 });
258})();
259