blob: 2673bfcdb0e68be0ebc875d4158803c80c3af8ed [file] [log] [blame]
Matteo Scandolobe9b13d2016-01-21 11:21:03 -08001(function () {
2 'use strict';
3
4 angular.module('xos.serviceTopology')
5 .service('Services', function($resource){
Matteo Scandolo85aad312016-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 Scandolo68236262016-01-21 15:38:06 -080011 .service('Slice', function($resource){
12 return $resource('/xos/slices', {id: '@id'});
13 })
14 .service('Instances', function($resource){
15 return $resource('/xos/instances', {id: '@id'});
16 })
Matteo Scandolo735606c2016-02-09 09:13:30 -080017 .service('Subscribers', function($resource, $q, SubscriberDevice){
18 return $resource('/xos/subscribers', {id: '@id'}, {
19 queryWithDevices: {
20 method: 'GET',
21 isArray: true,
22 interceptor: {
23 response: function(res){
Matteo Scandoloeeb9c082016-02-09 11:19:22 -080024
25 /**
26 * For each subscriber retrieve devices and append them
27 */
28
Matteo Scandolo735606c2016-02-09 09:13:30 -080029 const deferred = $q.defer();
30
31 let requests = [];
32
33 angular.forEach(res.data, (subscriber) => {
Matteo Scandoloeeb9c082016-02-09 11:19:22 -080034 requests.push(SubscriberDevice.query({id: subscriber.id}).$promise);
Matteo Scandolo735606c2016-02-09 09:13:30 -080035 })
36
37 $q.all(requests)
38 .then((list) => {
Matteo Scandolo735606c2016-02-09 09:13:30 -080039 res.data.map((subscriber, i) => {
40 subscriber.devices = list[i];
Matteo Scandolo38ba3312016-02-09 16:01:49 -080041 subscriber.type = 'subscriber';
42
43 subscriber.devices.map(d => d.type = 'device')
44
Matteo Scandolo735606c2016-02-09 09:13:30 -080045 return subscriber;
46 });
Matteo Scandoloeeb9c082016-02-09 11:19:22 -080047
Matteo Scandolo38ba3312016-02-09 16:01:49 -080048 // faking to have 2 subscriber
49 res.data.push(angular.copy(res.data[0]));
50
Matteo Scandolo735606c2016-02-09 09:13:30 -080051 deferred.resolve(res.data);
52 })
53
54 return deferred.promise;
55 }
56 }
57 }
58 });
59 })
60 .service('SubscriberDevice', function($resource){
61 return $resource('/xoslib/rs/subscriber/:id/users/', {id: '@id'});
Matteo Scandolo89276392016-01-22 16:36:34 -080062 })
Matteo Scandolo4889f5a2016-01-25 12:00:42 -080063 .service('ServiceRelation', function($q, lodash, Services, Tenant, Slice, Instances){
Matteo Scandolo85aad312016-01-21 14:23:28 -080064
Matteo Scandolofb46f5b2016-01-25 10:10:38 -080065 // count the mas depth of an object
66 const depthOf = (obj) => {
67 var depth = 0;
68 if (obj.children) {
69 obj.children.forEach(function (d) {
70 var tmpDepth = depthOf(d);
71 if (tmpDepth > depth) {
72 depth = tmpDepth
73 }
74 })
75 }
76 return 1 + depth
77 };
78
Matteo Scandolo85aad312016-01-21 14:23:28 -080079 // find all the relation defined for a given root
80 const findLevelRelation = (tenants, rootId) => {
81 return lodash.filter(tenants, service => {
82 return service.subscriber_service === rootId;
83 });
84 };
85
Matteo Scandolo998e4652016-01-28 12:02:57 -080086 const findSpecificInformation = (tenants, rootId) => {
87 var tenants = lodash.filter(tenants, service => {
88 return service.provider_service === rootId && service.subscriber_tenant;
89 });
90
91 var info;
92
93 tenants.forEach((tenant) => {
94 if(tenant.service_specific_attribute){
95 info = JSON.parse(tenant.service_specific_attribute);
96 }
97 });
98
99 return info;
100 };
101
Matteo Scandolo85aad312016-01-21 14:23:28 -0800102 // find all the service defined by a given array of relations
103 const findLevelServices = (relations, services) => {
104 const levelServices = [];
105 lodash.forEach(relations, (tenant) => {
106 var service = lodash.find(services, {id: tenant.provider_service});
107 levelServices.push(service);
108 });
109 return levelServices;
110 };
111
112 const buildLevel = (tenants, services, rootService, parentName = null) => {
113
Matteo Scandolo85aad312016-01-21 14:23:28 -0800114 // build an array of unlinked services
115 // these are the services that should still placed in the tree
116 var unlinkedServices = lodash.difference(services, [rootService]);
117
118 // find all relations relative to this rootElement
119 const levelRelation = findLevelRelation(tenants, rootService.id);
120
121 // find all items related to rootElement
122 const levelServices = findLevelServices(levelRelation, services);
123
124 // remove this item from the list (performance
125 unlinkedServices = lodash.difference(unlinkedServices, levelServices);
126
Matteo Scandolo998e4652016-01-28 12:02:57 -0800127 rootService.service_specific_attribute = findSpecificInformation(tenants, rootService.id);
128
129 const tree = {
130 name: rootService.humanReadableName,
131 parent: parentName,
132 type: 'service',
133 service: rootService,
134 children: []
135 };
136
Matteo Scandolo85aad312016-01-21 14:23:28 -0800137 lodash.forEach(levelServices, (service) => {
138 tree.children.push(buildLevel(tenants, unlinkedServices, service, rootService.humanReadableName));
139 });
140
Matteo Scandolofb46f5b2016-01-25 10:10:38 -0800141 // if it is the last element append internet
142 if(tree.children.length === 0){
143 tree.children.push({
Matteo Scandolo38ba3312016-02-09 16:01:49 -0800144 name: 'Router',
145 type: 'router',
Matteo Scandolofb46f5b2016-01-25 10:10:38 -0800146 children: []
147 });
148 }
149
Matteo Scandolo85aad312016-01-21 14:23:28 -0800150 return tree;
151 };
152
Matteo Scandolo7dbb1912016-01-25 14:11:10 -0800153 const buildServiceTree = (services, tenants, subscriber = {id: 1, name: 'fakeSubs'}) => {
Matteo Scandolo85aad312016-01-21 14:23:28 -0800154
155 // find the root service
156 // it is the one attached to subsriber_root
157 // as now we have only one root so this can work
Matteo Scandolo89276392016-01-22 16:36:34 -0800158 const rootServiceId = lodash.find(tenants, {subscriber_root: subscriber.id}).provider_service;
Matteo Scandolo85aad312016-01-21 14:23:28 -0800159 const rootService = lodash.find(services, {id: rootServiceId});
160
161 const serviceTree = buildLevel(tenants, services, rootService);
162
Matteo Scandolo89276392016-01-22 16:36:34 -0800163 return {
164 name: subscriber.name,
165 parent: null,
Matteo Scandolofb46f5b2016-01-25 10:10:38 -0800166 type: 'subscriber',
Matteo Scandolo89276392016-01-22 16:36:34 -0800167 children: [serviceTree]
168 };
169
Matteo Scandolo85aad312016-01-21 14:23:28 -0800170 };
171
Matteo Scandolo89276392016-01-22 16:36:34 -0800172 const get = (subscriber) => {
Matteo Scandolo85aad312016-01-21 14:23:28 -0800173 var deferred = $q.defer();
174 var services, tenants;
175 Services.query().$promise
176 .then((res) => {
177 services = res;
178 return Tenant.query().$promise;
179 })
180 .then((res) => {
181 tenants = res;
Matteo Scandolo89276392016-01-22 16:36:34 -0800182 deferred.resolve(buildServiceTree(services, tenants, subscriber));
Matteo Scandolo85aad312016-01-21 14:23:28 -0800183 })
184 .catch((e) => {
185 throw new Error(e);
186 });
187
188 return deferred.promise;
Matteo Scandolofb46f5b2016-01-25 10:10:38 -0800189 };
Matteo Scandolo89276392016-01-22 16:36:34 -0800190
Matteo Scandolofb46f5b2016-01-25 10:10:38 -0800191 // export APIs
Matteo Scandoloc86b4c12016-01-25 17:36:08 -0800192 return {
193 get: get,
194 buildLevel: buildLevel,
195 buildServiceTree: buildServiceTree,
196 findLevelRelation: findLevelRelation,
197 findLevelServices: findLevelServices,
198 depthOf: depthOf,
Matteo Scandolo998e4652016-01-28 12:02:57 -0800199 findSpecificInformation: findSpecificInformation
Matteo Scandoloc86b4c12016-01-25 17:36:08 -0800200 }
Matteo Scandolobe9b13d2016-01-21 11:21:03 -0800201 });
202
203}());