blob: 93a9b90ed133e59f296a7cda0e67ae20cbcc0834 [file] [log] [blame]
Matteo Scandolo8a64fa42016-01-21 11:21:03 -08001(function () {
2 'use strict';
3
4 angular.module('xos.serviceTopology')
5 .service('Services', function($resource){
Matteo Scandolof16b3792016-01-21 14:23:28 -08006 return $resource('/xos/services/:id', {id: '@id'});
7 })
8 .service('Tenant', function($resource){
9 return $resource('/xos/tenants');
10 })
Matteo Scandolo06f45d62016-01-21 15:38:06 -080011 .service('Slice', function($resource){
12 return $resource('/xos/slices', {id: '@id'});
13 })
14 .service('Instances', function($resource){
Matteo Scandolo170d3be2016-02-11 08:58:04 -080015 return $resource('/xos/instances', {id: '@id'}, {});
16 })
17 .service('Node', function($resource, $q, Instances){
18 return $resource('/xos/nodes', {id: '@id'}, {
19 queryWithInstances: {
20 method: 'GET',
21 isArray: true,
22 interceptor: {
23 response: function(res){
24
25 // TODO update the API to include instances in nodes
26 // http://stackoverflow.com/questions/14573102/how-do-i-include-related-model-fields-using-django-rest-framework
27
28 const deferred = $q.defer();
29
30 let requests = [];
31
32 angular.forEach(res.data, (node) => {
33 requests.push(Instances.query({node: node.id}).$promise);
34 })
35
36 $q.all(requests)
37 .then((list) => {
38 res.data.map((node, i) => {
39 node.instances = list[i];
40 return node;
41 });
Matteo Scandolo170d3be2016-02-11 08:58:04 -080042 deferred.resolve(res.data);
43 })
44
45 return deferred.promise;
46 }
47 }
48 }
49 });
Matteo Scandolo06f45d62016-01-21 15:38:06 -080050 })
Matteo Scandolo7547f042016-02-09 09:13:30 -080051 .service('Subscribers', function($resource, $q, SubscriberDevice){
52 return $resource('/xos/subscribers', {id: '@id'}, {
53 queryWithDevices: {
54 method: 'GET',
55 isArray: true,
56 interceptor: {
57 response: function(res){
Matteo Scandolo219b1a72016-02-09 11:19:22 -080058
59 /**
60 * For each subscriber retrieve devices and append them
61 */
62
Matteo Scandolo7547f042016-02-09 09:13:30 -080063 const deferred = $q.defer();
64
65 let requests = [];
66
67 angular.forEach(res.data, (subscriber) => {
Matteo Scandolo219b1a72016-02-09 11:19:22 -080068 requests.push(SubscriberDevice.query({id: subscriber.id}).$promise);
Matteo Scandolo7547f042016-02-09 09:13:30 -080069 })
70
71 $q.all(requests)
72 .then((list) => {
Matteo Scandolo7547f042016-02-09 09:13:30 -080073 res.data.map((subscriber, i) => {
74 subscriber.devices = list[i];
Matteo Scandolo9fe01af2016-02-09 16:01:49 -080075 subscriber.type = 'subscriber';
76
77 subscriber.devices.map(d => d.type = 'device')
78
Matteo Scandolo7547f042016-02-09 09:13:30 -080079 return subscriber;
80 });
Matteo Scandolo219b1a72016-02-09 11:19:22 -080081
Matteo Scandolo9fe01af2016-02-09 16:01:49 -080082 // faking to have 2 subscriber
Matteo Scandolofd468582016-02-16 16:03:43 -080083 // res.data.push(angular.copy(res.data[0]));
Matteo Scandolo9fe01af2016-02-09 16:01:49 -080084
Matteo Scandolo7547f042016-02-09 09:13:30 -080085 deferred.resolve(res.data);
86 })
87
88 return deferred.promise;
89 }
90 }
91 }
92 });
93 })
94 .service('SubscriberDevice', function($resource){
95 return $resource('/xoslib/rs/subscriber/:id/users/', {id: '@id'});
Matteo Scandoloff7df762016-01-22 16:36:34 -080096 })
Matteo Scandolo071ef462016-01-25 12:00:42 -080097 .service('ServiceRelation', function($q, lodash, Services, Tenant, Slice, Instances){
Matteo Scandolof16b3792016-01-21 14:23:28 -080098
Matteo Scandolof2c99012016-01-25 10:10:38 -080099 // count the mas depth of an object
100 const depthOf = (obj) => {
101 var depth = 0;
102 if (obj.children) {
103 obj.children.forEach(function (d) {
104 var tmpDepth = depthOf(d);
105 if (tmpDepth > depth) {
106 depth = tmpDepth
107 }
108 })
109 }
110 return 1 + depth
111 };
112
Matteo Scandolof16b3792016-01-21 14:23:28 -0800113 // find all the relation defined for a given root
114 const findLevelRelation = (tenants, rootId) => {
115 return lodash.filter(tenants, service => {
116 return service.subscriber_service === rootId;
117 });
118 };
119
Matteo Scandoloc9ebd922016-01-28 12:02:57 -0800120 const findSpecificInformation = (tenants, rootId) => {
121 var tenants = lodash.filter(tenants, service => {
122 return service.provider_service === rootId && service.subscriber_tenant;
123 });
124
125 var info;
126
127 tenants.forEach((tenant) => {
128 if(tenant.service_specific_attribute){
129 info = JSON.parse(tenant.service_specific_attribute);
130 }
131 });
132
133 return info;
134 };
135
Matteo Scandolof16b3792016-01-21 14:23:28 -0800136 // find all the service defined by a given array of relations
137 const findLevelServices = (relations, services) => {
138 const levelServices = [];
139 lodash.forEach(relations, (tenant) => {
140 var service = lodash.find(services, {id: tenant.provider_service});
141 levelServices.push(service);
142 });
143 return levelServices;
144 };
145
146 const buildLevel = (tenants, services, rootService, parentName = null) => {
147
Matteo Scandolof16b3792016-01-21 14:23:28 -0800148 // build an array of unlinked services
149 // these are the services that should still placed in the tree
150 var unlinkedServices = lodash.difference(services, [rootService]);
151
152 // find all relations relative to this rootElement
153 const levelRelation = findLevelRelation(tenants, rootService.id);
154
155 // find all items related to rootElement
156 const levelServices = findLevelServices(levelRelation, services);
157
158 // remove this item from the list (performance
159 unlinkedServices = lodash.difference(unlinkedServices, levelServices);
160
Matteo Scandoloc9ebd922016-01-28 12:02:57 -0800161 rootService.service_specific_attribute = findSpecificInformation(tenants, rootService.id);
162
163 const tree = {
164 name: rootService.humanReadableName,
165 parent: parentName,
166 type: 'service',
167 service: rootService,
168 children: []
169 };
170
Matteo Scandolof16b3792016-01-21 14:23:28 -0800171 lodash.forEach(levelServices, (service) => {
172 tree.children.push(buildLevel(tenants, unlinkedServices, service, rootService.humanReadableName));
173 });
174
Matteo Scandolof2c99012016-01-25 10:10:38 -0800175 // if it is the last element append internet
176 if(tree.children.length === 0){
177 tree.children.push({
Matteo Scandolo9fe01af2016-02-09 16:01:49 -0800178 name: 'Router',
179 type: 'router',
Matteo Scandolof2c99012016-01-25 10:10:38 -0800180 children: []
181 });
182 }
183
Matteo Scandolof16b3792016-01-21 14:23:28 -0800184 return tree;
185 };
186
Matteo Scandolocb12a1a2016-01-25 14:11:10 -0800187 const buildServiceTree = (services, tenants, subscriber = {id: 1, name: 'fakeSubs'}) => {
Matteo Scandolof16b3792016-01-21 14:23:28 -0800188
189 // find the root service
190 // it is the one attached to subsriber_root
191 // as now we have only one root so this can work
Matteo Scandoloff7df762016-01-22 16:36:34 -0800192 const rootServiceId = lodash.find(tenants, {subscriber_root: subscriber.id}).provider_service;
Matteo Scandolof16b3792016-01-21 14:23:28 -0800193 const rootService = lodash.find(services, {id: rootServiceId});
194
195 const serviceTree = buildLevel(tenants, services, rootService);
196
Matteo Scandoloff7df762016-01-22 16:36:34 -0800197 return {
198 name: subscriber.name,
199 parent: null,
Matteo Scandolof2c99012016-01-25 10:10:38 -0800200 type: 'subscriber',
Matteo Scandoloff7df762016-01-22 16:36:34 -0800201 children: [serviceTree]
202 };
203
Matteo Scandolof16b3792016-01-21 14:23:28 -0800204 };
205
Matteo Scandoloff7df762016-01-22 16:36:34 -0800206 const get = (subscriber) => {
Matteo Scandolof16b3792016-01-21 14:23:28 -0800207 var deferred = $q.defer();
208 var services, tenants;
209 Services.query().$promise
210 .then((res) => {
211 services = res;
212 return Tenant.query().$promise;
213 })
214 .then((res) => {
215 tenants = res;
Matteo Scandoloff7df762016-01-22 16:36:34 -0800216 deferred.resolve(buildServiceTree(services, tenants, subscriber));
Matteo Scandolof16b3792016-01-21 14:23:28 -0800217 })
218 .catch((e) => {
219 throw new Error(e);
220 });
221
222 return deferred.promise;
Matteo Scandolof2c99012016-01-25 10:10:38 -0800223 };
Matteo Scandoloff7df762016-01-22 16:36:34 -0800224
Matteo Scandolof2c99012016-01-25 10:10:38 -0800225 // export APIs
Matteo Scandolo5bf04572016-01-25 17:36:08 -0800226 return {
227 get: get,
228 buildLevel: buildLevel,
229 buildServiceTree: buildServiceTree,
230 findLevelRelation: findLevelRelation,
231 findLevelServices: findLevelServices,
232 depthOf: depthOf,
Matteo Scandoloc9ebd922016-01-28 12:02:57 -0800233 findSpecificInformation: findSpecificInformation
Matteo Scandolo5bf04572016-01-25 17:36:08 -0800234 }
Matteo Scandolo8a64fa42016-01-21 11:21:03 -0800235 });
236
237}());