blob: dc23024dd3d5cbffd211577b0ed1238d38e50abf [file] [log] [blame]
Matteo Scandoloe3de73d2015-12-04 10:14:40 -08001'use strict';
2
3angular.module('xos.ceilometerDashboard', [
4 'ngResource',
5 'ngCookies',
6 'ngLodash',
7 'ui.router',
8 'xos.helpers',
Matteo Scandoloc2d31102015-12-08 14:35:55 -08009 'ngAnimate',
Matteo Scandolo0f5e1632015-12-09 16:09:59 -080010 'chart.js',
11 'ui.bootstrap.accordion'
Matteo Scandoloe3de73d2015-12-04 10:14:40 -080012])
Matteo Scandoloc2d31102015-12-08 14:35:55 -080013.config(($stateProvider, $urlRouterProvider) => {
Matteo Scandoloe3de73d2015-12-04 10:14:40 -080014 $stateProvider
15 .state('ceilometerDashboard', {
16 url: '/',
17 template: '<ceilometer-dashboard></ceilometer-dashboard>'
Matteo Scandoloec8ad422015-12-04 15:55:20 -080018 })
19 .state('samples', {
20 url: '/:name/:tenant/samples',
21 template: '<ceilometer-samples></ceilometer-samples>'
Matteo Scandoloe3de73d2015-12-04 10:14:40 -080022 });
Matteo Scandoloc2d31102015-12-08 14:35:55 -080023 $urlRouterProvider.otherwise('/');
Matteo Scandoloe3de73d2015-12-04 10:14:40 -080024})
25.config(function($httpProvider){
26 $httpProvider.interceptors.push('NoHyperlinks');
27})
Matteo Scandoloc2d31102015-12-08 14:35:55 -080028.run(function($rootScope){
29 $rootScope.stateName = 'ceilometerDashboard';
30 $rootScope.$on('$stateChangeStart', (event, toState) => {
Matteo Scandoloc2d31102015-12-08 14:35:55 -080031 $rootScope.stateName = toState.name;
32 })
33})
Matteo Scandolo5dd94182015-12-09 17:09:55 -080034.service('Ceilometer', function($http, $q, lodash){
Matteo Scandolod3e696d2015-12-08 15:24:23 -080035
Matteo Scandoloa918ea82015-12-14 14:26:20 -080036 this.resourceMap = {};
Matteo Scandolod3e696d2015-12-08 15:24:23 -080037
Matteo Scandoloe3de73d2015-12-04 10:14:40 -080038 this.getMeters = () => {
39 let deferred = $q.defer();
40
Matteo Scandolo5dd94182015-12-09 17:09:55 -080041 $http.get('/xoslib/meters/', {cache: true})
42 // $http.get('../meters_mock.json', {cache: true})
Matteo Scandoloe3de73d2015-12-04 10:14:40 -080043 .then((res) => {
Matteo Scandoloa918ea82015-12-14 14:26:20 -080044
45 // saving resources name and ids for later user,
46 // {resource_id: resource_name}
47 // NOTE REMOVE IF NOT ANYMORE NEEDED
48 const resourceObj = lodash.groupBy(res.data, 'resource_id');
49 this.resourceMap = lodash.reduce(Object.keys(resourceObj), (map, item) => {
50 map[item] = resourceObj[item][0].resource_name;
51 return map;
52 }, {});
53
Matteo Scandoloec8ad422015-12-04 15:55:20 -080054 deferred.resolve(res.data)
55 })
56 .catch((e) => {
57 deferred.reject(e);
58 });
59
60 return deferred.promise;
61 }
62
63 this.getSamples = (name, tenant) => {
64 let deferred = $q.defer();
65
Matteo Scandolo6c788432015-12-07 17:32:39 -080066 $http.get(`/xoslib/metersamples/`, {params: {meter: name, tenant: tenant}})
Matteo Scandoloec8ad422015-12-04 15:55:20 -080067 .then((res) => {
68 deferred.resolve(res.data)
Matteo Scandoloe3de73d2015-12-04 10:14:40 -080069 })
70 .catch((e) => {
71 deferred.reject(e);
72 });
73
74 return deferred.promise;
75 }
Matteo Scandolo5dd94182015-12-09 17:09:55 -080076
77 this.getStats = (sliceName) => {
78 let deferred = $q.defer();
79
80 $http.get('/xoslib/meterstatistics/', {cache: true})
81 // $http.get('../stats_mock.son', {cache: true})
82 .then((res) => {
83 deferred.resolve(lodash.filter(res.data, {slice: sliceName}))
84 })
85 .catch((e) => {
86 deferred.reject(e);
87 });
88
89 return deferred.promise;
90 };
Matteo Scandoloe3de73d2015-12-04 10:14:40 -080091})
Matteo Scandoloec8ad422015-12-04 15:55:20 -080092.directive('ceilometerDashboard', function(lodash){
Matteo Scandoloe3de73d2015-12-04 10:14:40 -080093 return {
94 restrict: 'E',
95 scope: {},
96 bindToController: true,
97 controllerAs: 'vm',
98 templateUrl: 'templates/ceilometer-dashboard.tpl.html',
99 controller: function(Ceilometer){
100
101 this.loadMeters = () => {
102 this.loader = true;
103
104 Ceilometer.getMeters()
105 .then(meters => {
Matteo Scandolo30c23c72015-12-09 15:23:51 -0800106 //group project by service
107 this.projects = lodash.groupBy(meters, 'service');
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800108 lodash.forEach(Object.keys(this.projects), (project) => {
Matteo Scandolo30c23c72015-12-09 15:23:51 -0800109 // inside each service group by slice
110 this.projects[project] = lodash.groupBy(this.projects[project], 'slice');
111 lodash.forEach(Object.keys(this.projects[project]), (slice) => {
112 // inside each service => slice group by resource
Matteo Scandoloa918ea82015-12-14 14:26:20 -0800113 this.projects[project][slice] = lodash.groupBy(this.projects[project][slice], 'resource_name');
Matteo Scandolo30c23c72015-12-09 15:23:51 -0800114 });
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800115 });
Matteo Scandoloe3de73d2015-12-04 10:14:40 -0800116 })
117 .catch(err => {
Matteo Scandoloa918ea82015-12-14 14:26:20 -0800118 this.error = err.data.detail;
Matteo Scandoloe3de73d2015-12-04 10:14:40 -0800119 })
120 .finally(() => {
121 this.loader = false;
122 });
123 }
124
125 this.loadMeters();
126
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800127 /**
Matteo Scandolo30c23c72015-12-09 15:23:51 -0800128 * Select the current service
129 */
130
131 this.selectService = (service) => {
132 //cleaning
133 this.selectedResources = null;
134 this.selectedResource = null;
135 this.selectedMeters = null;
Matteo Scandolo0f5e1632015-12-09 16:09:59 -0800136
Matteo Scandolo30c23c72015-12-09 15:23:51 -0800137 this.selectedService = service;
138 };
139
140 /**
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800141 * Select Resources for a slice
142 *
143 * @param Array resources The list of selected resources
144 * @returns void
145 */
146 this.selectedResources = null;
147 this.selectResources = (resources, slice) => {
148 //cleaning
149 this.selectedResources = null;
150 this.selectedResource = null;
151 this.selectedMeters = null;
152
153 this.selectedResources = resources;
154 this.selectedSlice = slice;
155 }
156
157 /**
158 * Select Meters for a resource
159 *
160 * @param Array meters The list of selected resources
161 * @returns void
162 */
163 this.selectedMeters = null;
164 this.selectMeters = (meters, resource) => {
165 this.selectedMeters = meters;
166 this.selectedResource = resource;
167 }
168
Matteo Scandoloe3de73d2015-12-04 10:14:40 -0800169 }
170 };
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800171})
172.directive('ceilometerSamples', function(lodash, $stateParams){
173 return {
174 restrict: 'E',
175 scope: {
176 name: '=name',
177 tenant: '=tenant'
178 },
179 bindToController: true,
180 controllerAs: 'vm',
181 templateUrl: 'templates/ceilometer-samples.tpl.html',
182 controller: function(Ceilometer) {
183
Matteo Scandoloc6a78982015-12-08 16:39:57 -0800184 this.chartColors = [
Matteo Scandolod3e696d2015-12-08 15:24:23 -0800185 '#286090',
186 '#F7464A',
187 '#46BFBD',
188 '#FDB45C',
189 '#97BBCD',
190 '#4D5360',
191 '#8c4f9f'
192 ];
Matteo Scandoloc6a78982015-12-08 16:39:57 -0800193
194 this.chart = {
195 series: [],
196 labels: [],
197 data: []
198 }
199
200 Chart.defaults.global.colours = this.chartColors;
Matteo Scandolod3e696d2015-12-08 15:24:23 -0800201
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800202 this.chartType = 'line';
203
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800204 if($stateParams.name && $stateParams.tenant){
205 this.name = $stateParams.name;
206 this.tenant = $stateParams.tenant;
207 }
208
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800209 // Mock
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800210
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800211 /**
Matteo Scandoloc6a78982015-12-08 16:39:57 -0800212 * Goes trough the array and format date to be used as labels
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800213 *
214 * @param Array data
215 * @returns Array a list of labels
216 */
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800217
Matteo Scandolo52193d32015-12-05 18:44:45 -0800218 this.getLabels = (data) => {
219 return data.reduce((list, item) => {
220 let date = new Date(item.timestamp);
221 list.push(`${date.getHours()}:${(date.getMinutes()<10?'0':'') + date.getMinutes()}:${date.getSeconds()}`);
222 return list;
223 }, []);
224 };
225
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800226 /**
Matteo Scandoloc6a78982015-12-08 16:39:57 -0800227 * Goes trough the array and return a flat array of values
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800228 *
229 * @param Array data
230 * @returns Array a list of values
231 */
232
Matteo Scandolo52193d32015-12-05 18:44:45 -0800233 this.getData = (data) => {
234 return data.reduce((list, item) => {
235 list.push(item.volume);
236 return list;
237 }, []);
238 }
239
Matteo Scandoloc6a78982015-12-08 16:39:57 -0800240 /**
241 * Add a samples to the chart
242 *
243 * @param string resource_id
244 */
245 this.chartMeters = [];
246 this.addMeterToChart = (resource_id) => {
Matteo Scandoloa918ea82015-12-14 14:26:20 -0800247 console.log(resource_id, this.samplesList);
Matteo Scandoloc6a78982015-12-08 16:39:57 -0800248 this.chart['labels'] = this.getLabels(lodash.sortBy(this.samplesList[resource_id], 'timestamp'));
249 this.chart['series'].push(resource_id);
250 this.chart['data'].push(this.getData(lodash.sortBy(this.samplesList[resource_id], 'timestamp')));
251 this.chartMeters.push(resource_id);
252 lodash.remove(this.sampleLabels, {id: resource_id});
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800253 }
254
Matteo Scandoloc6a78982015-12-08 16:39:57 -0800255 this.removeFromChart = (resource_id) => {
256 this.chart.data.splice(this.chart.series.indexOf(resource_id), 1);
257 this.chart.series.splice(this.chart.series.indexOf(resource_id), 1);
258 this.chartMeters.splice(this.chartMeters.indexOf(resource_id), 1);
259 this.sampleLabels.push({
260 id: resource_id,
261 // TODO add resource name
262 })
263 };
264
265 /**
266 * Format samples to create a list of labels and ids
267 */
268
269 this.formatSamplesLabels = (samples) => {
270
271 return lodash.uniq(samples.reduce((labels, item) => {
272 labels.push({
273 id: item.resource_id,
Matteo Scandoloa918ea82015-12-14 14:26:20 -0800274 name: Ceilometer.resourceMap[item.resource_id]
Matteo Scandoloc6a78982015-12-08 16:39:57 -0800275 });
276 return labels;
277 }, []), item => item.id);
278 }
279
280
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800281 /**
282 * Load the samples and format data
283 */
284
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800285 this.showSamples = () => {
286 this.loader = true;
Matteo Scandoloc2d31102015-12-08 14:35:55 -0800287 // Ceilometer.getSamples(this.name, this.tenant) //fetch one
288 Ceilometer.getSamples(this.name) //fetch all
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800289 .then(res => {
Matteo Scandoloc6a78982015-12-08 16:39:57 -0800290
291 // setup data for visualization
Matteo Scandolod3e696d2015-12-08 15:24:23 -0800292 this.samplesList = lodash.groupBy(res, 'resource_id');
Matteo Scandoloc6a78982015-12-08 16:39:57 -0800293 this.sampleLabels = this.formatSamplesLabels(res);
294
295 // add current meter to chart
296 this.addMeterToChart(this.tenant);
297
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800298 })
299 .catch(err => {
Matteo Scandolo30c23c72015-12-09 15:23:51 -0800300 this.error = err.data.detail;
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800301 })
302 .finally(() => {
303 this.loader = false;
304 });
305 };
306
307 this.showSamples();
Matteo Scandoloec8ad422015-12-04 15:55:20 -0800308 }
309 }
Matteo Scandolo5dd94182015-12-09 17:09:55 -0800310})
311.directive('ceilometerStats', function(){
312 return {
313 restrict: 'E',
314 scope: {
315 name: '=name',
316 },
317 bindToController: true,
318 controllerAs: 'vm',
319 templateUrl: 'templates/ceilometer-stats.tpl.html',
320 controller: function($scope, Ceilometer) {
321 this.getStats = () => {
322 this.loader = true;
323 Ceilometer.getStats(this.name)
324 .then(res => {
325 this.stats = res;
326 })
327 .catch(err => {
328 this.error = err.data;
329 })
330 .finally(() => {
331 this.loader = false;
332 });
333 };
334
335 this.getStats();
336
337 $scope.$watch(() => this.name, () => {this.getStats();});
338 }
339 }
Matteo Scandolo76b4e982015-12-10 10:15:20 -0800340})
341.filter('orderObjectByKey', function(lodash) {
Matteo Scandoloa918ea82015-12-14 14:26:20 -0800342 return function(items) {
Matteo Scandolo76b4e982015-12-10 10:15:20 -0800343
344 if(!items){
345 return;
346 }
347
348 return lodash.reduce(Object.keys(items).reverse(), (list, key) => {
349 list[key] = items[key];
350 return list;
351 }, {});
352
353 };
354});
355;