blob: 12dedafb6ade4bfab71825f6c28c3c200a05c427 [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 Scandolo89276392016-01-22 16:36:34 -080017 .service('Subscribers', function($resource){
18 return $resource('/xos/subscribers', {id: '@id'});
19 })
Matteo Scandolo4889f5a2016-01-25 12:00:42 -080020 .service('ServiceRelation', function($q, lodash, Services, Tenant, Slice, Instances){
Matteo Scandolo85aad312016-01-21 14:23:28 -080021
Matteo Scandolofb46f5b2016-01-25 10:10:38 -080022 // count the mas depth of an object
23 const depthOf = (obj) => {
24 var depth = 0;
25 if (obj.children) {
26 obj.children.forEach(function (d) {
27 var tmpDepth = depthOf(d);
28 if (tmpDepth > depth) {
29 depth = tmpDepth
30 }
31 })
32 }
33 return 1 + depth
34 };
35
Matteo Scandolo85aad312016-01-21 14:23:28 -080036 // find all the relation defined for a given root
37 const findLevelRelation = (tenants, rootId) => {
38 return lodash.filter(tenants, service => {
39 return service.subscriber_service === rootId;
40 });
41 };
42
Matteo Scandolo998e4652016-01-28 12:02:57 -080043 const findSpecificInformation = (tenants, rootId) => {
44 var tenants = lodash.filter(tenants, service => {
45 return service.provider_service === rootId && service.subscriber_tenant;
46 });
47
48 var info;
49
50 tenants.forEach((tenant) => {
51 if(tenant.service_specific_attribute){
52 info = JSON.parse(tenant.service_specific_attribute);
53 }
54 });
55
56 return info;
57 };
58
Matteo Scandolo85aad312016-01-21 14:23:28 -080059 // find all the service defined by a given array of relations
60 const findLevelServices = (relations, services) => {
61 const levelServices = [];
62 lodash.forEach(relations, (tenant) => {
63 var service = lodash.find(services, {id: tenant.provider_service});
64 levelServices.push(service);
65 });
66 return levelServices;
67 };
68
69 const buildLevel = (tenants, services, rootService, parentName = null) => {
70
Matteo Scandolo85aad312016-01-21 14:23:28 -080071 // build an array of unlinked services
72 // these are the services that should still placed in the tree
73 var unlinkedServices = lodash.difference(services, [rootService]);
74
75 // find all relations relative to this rootElement
76 const levelRelation = findLevelRelation(tenants, rootService.id);
77
78 // find all items related to rootElement
79 const levelServices = findLevelServices(levelRelation, services);
80
81 // remove this item from the list (performance
82 unlinkedServices = lodash.difference(unlinkedServices, levelServices);
83
Matteo Scandolo998e4652016-01-28 12:02:57 -080084 rootService.service_specific_attribute = findSpecificInformation(tenants, rootService.id);
85
86 const tree = {
87 name: rootService.humanReadableName,
88 parent: parentName,
89 type: 'service',
90 service: rootService,
91 children: []
92 };
93
Matteo Scandolo85aad312016-01-21 14:23:28 -080094 lodash.forEach(levelServices, (service) => {
95 tree.children.push(buildLevel(tenants, unlinkedServices, service, rootService.humanReadableName));
96 });
97
Matteo Scandolofb46f5b2016-01-25 10:10:38 -080098 // if it is the last element append internet
99 if(tree.children.length === 0){
100 tree.children.push({
101 name: 'Internet',
102 type: 'internet',
103 children: []
104 });
105 }
106
Matteo Scandolo85aad312016-01-21 14:23:28 -0800107 return tree;
108 };
109
Matteo Scandolo7dbb1912016-01-25 14:11:10 -0800110 const buildServiceTree = (services, tenants, subscriber = {id: 1, name: 'fakeSubs'}) => {
Matteo Scandolo85aad312016-01-21 14:23:28 -0800111
112 // find the root service
113 // it is the one attached to subsriber_root
114 // as now we have only one root so this can work
Matteo Scandolo89276392016-01-22 16:36:34 -0800115 const rootServiceId = lodash.find(tenants, {subscriber_root: subscriber.id}).provider_service;
Matteo Scandolo85aad312016-01-21 14:23:28 -0800116 const rootService = lodash.find(services, {id: rootServiceId});
117
118 const serviceTree = buildLevel(tenants, services, rootService);
119
Matteo Scandolo89276392016-01-22 16:36:34 -0800120 return {
121 name: subscriber.name,
122 parent: null,
Matteo Scandolofb46f5b2016-01-25 10:10:38 -0800123 type: 'subscriber',
Matteo Scandolo89276392016-01-22 16:36:34 -0800124 children: [serviceTree]
125 };
126
Matteo Scandolo85aad312016-01-21 14:23:28 -0800127 };
128
Matteo Scandolo89276392016-01-22 16:36:34 -0800129 const get = (subscriber) => {
Matteo Scandolo85aad312016-01-21 14:23:28 -0800130 var deferred = $q.defer();
131 var services, tenants;
132 Services.query().$promise
133 .then((res) => {
134 services = res;
135 return Tenant.query().$promise;
136 })
137 .then((res) => {
138 tenants = res;
Matteo Scandolo89276392016-01-22 16:36:34 -0800139 deferred.resolve(buildServiceTree(services, tenants, subscriber));
Matteo Scandolo85aad312016-01-21 14:23:28 -0800140 })
141 .catch((e) => {
142 throw new Error(e);
143 });
144
145 return deferred.promise;
Matteo Scandolofb46f5b2016-01-25 10:10:38 -0800146 };
Matteo Scandolo89276392016-01-22 16:36:34 -0800147
Matteo Scandolo998e4652016-01-28 12:02:57 -0800148 const buildServiceInterfacesTree = (service, slices, instances) => {
149
150 const isActive = (service, instance) => {
151 if(service.service_specific_attribute){
152 return service.service_specific_attribute.instance_id === instance.id;
153 }
154 return false;
155 }
156
Matteo Scandoloc86b4c12016-01-25 17:36:08 -0800157 var interfaceTree = [];
158 lodash.forEach(slices, (slice, i) => {
159 let current = {
160 name: slice.name,
161 slice: slice,
162 type: 'slice',
163 children: instances[i].map((instance) => {
Matteo Scandolo998e4652016-01-28 12:02:57 -0800164
Matteo Scandoloc86b4c12016-01-25 17:36:08 -0800165 return {
166 name: instance.humanReadableName,
167 children: [],
168 type: 'instance',
Matteo Scandolo998e4652016-01-28 12:02:57 -0800169 instance: instance,
170 active: isActive(service, instance)
Matteo Scandoloc86b4c12016-01-25 17:36:08 -0800171 };
172
173 })
174 };
175 interfaceTree.push(current);
176 });
177 return interfaceTree;
178 };
179
Matteo Scandolo998e4652016-01-28 12:02:57 -0800180 const getServiceInterfaces = (service) => {
Matteo Scandolo4889f5a2016-01-25 12:00:42 -0800181 var deferred = $q.defer();
182
183 var _slices;
184
Matteo Scandolo998e4652016-01-28 12:02:57 -0800185 Slice.query({service: service.id}).$promise
Matteo Scandolo4889f5a2016-01-25 12:00:42 -0800186 .then((slices) => {
187 _slices = slices;
188 const promisesArr = slices.reduce((promises, slice) => {
189 promises.push(Instances.query({slice: slice.id}).$promise);
190 return promises;
191 }, []);
192
Matteo Scandolo39f49472016-01-25 13:55:09 -0800193 // TODO add networks
194 // decide how, they should be manually drawn
195 // as they connect more instances without parent dependencies
196
Matteo Scandolo4889f5a2016-01-25 12:00:42 -0800197 return $q.all(promisesArr);
198 })
199 .then((instances) => {
Matteo Scandolo998e4652016-01-28 12:02:57 -0800200 deferred.resolve(buildServiceInterfacesTree(service, _slices, instances));
Matteo Scandolo4889f5a2016-01-25 12:00:42 -0800201 });
202
203 return deferred.promise;
204 };
205
Matteo Scandolofb46f5b2016-01-25 10:10:38 -0800206 // export APIs
Matteo Scandoloc86b4c12016-01-25 17:36:08 -0800207 return {
208 get: get,
209 buildLevel: buildLevel,
210 buildServiceTree: buildServiceTree,
211 findLevelRelation: findLevelRelation,
212 findLevelServices: findLevelServices,
213 depthOf: depthOf,
214 getServiceInterfaces: getServiceInterfaces,
Matteo Scandolo998e4652016-01-28 12:02:57 -0800215 buildServiceInterfacesTree: buildServiceInterfacesTree,
216 findSpecificInformation: findSpecificInformation
Matteo Scandoloc86b4c12016-01-25 17:36:08 -0800217 }
Matteo Scandolobe9b13d2016-01-21 11:21:03 -0800218 });
219
220}());