blob: b3ac3b09f3ed5f0c4b994803a8fd32366690896a [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){
15 return $resource('/xos/instances', {id: '@id'});
16 })
Matteo Scandoloff7df762016-01-22 16:36:34 -080017 .service('Subscribers', function($resource){
18 return $resource('/xos/subscribers', {id: '@id'});
19 })
Matteo Scandolo071ef462016-01-25 12:00:42 -080020 .service('ServiceRelation', function($q, lodash, Services, Tenant, Slice, Instances){
Matteo Scandolof16b3792016-01-21 14:23:28 -080021
Matteo Scandolof2c99012016-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 Scandolof16b3792016-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
43 // find all the service defined by a given array of relations
44 const findLevelServices = (relations, services) => {
45 const levelServices = [];
46 lodash.forEach(relations, (tenant) => {
47 var service = lodash.find(services, {id: tenant.provider_service});
48 levelServices.push(service);
49 });
50 return levelServices;
51 };
52
53 const buildLevel = (tenants, services, rootService, parentName = null) => {
54
55 const tree = {
56 name: rootService.humanReadableName,
57 parent: parentName,
Matteo Scandolof2c99012016-01-25 10:10:38 -080058 type: 'service',
Matteo Scandoloe89935b2016-01-22 13:17:33 -080059 service: rootService,
Matteo Scandolof16b3792016-01-21 14:23:28 -080060 children: []
61 };
62
63 // build an array of unlinked services
64 // these are the services that should still placed in the tree
65 var unlinkedServices = lodash.difference(services, [rootService]);
66
67 // find all relations relative to this rootElement
68 const levelRelation = findLevelRelation(tenants, rootService.id);
69
70 // find all items related to rootElement
71 const levelServices = findLevelServices(levelRelation, services);
72
73 // remove this item from the list (performance
74 unlinkedServices = lodash.difference(unlinkedServices, levelServices);
75
76 lodash.forEach(levelServices, (service) => {
77 tree.children.push(buildLevel(tenants, unlinkedServices, service, rootService.humanReadableName));
78 });
79
Matteo Scandolof2c99012016-01-25 10:10:38 -080080 // if it is the last element append internet
81 if(tree.children.length === 0){
82 tree.children.push({
83 name: 'Internet',
84 type: 'internet',
85 children: []
86 });
87 }
88
Matteo Scandolof16b3792016-01-21 14:23:28 -080089 return tree;
90 };
91
Matteo Scandolocb12a1a2016-01-25 14:11:10 -080092 const buildServiceTree = (services, tenants, subscriber = {id: 1, name: 'fakeSubs'}) => {
Matteo Scandolof16b3792016-01-21 14:23:28 -080093
94 // find the root service
95 // it is the one attached to subsriber_root
96 // as now we have only one root so this can work
Matteo Scandoloff7df762016-01-22 16:36:34 -080097 const rootServiceId = lodash.find(tenants, {subscriber_root: subscriber.id}).provider_service;
Matteo Scandolof16b3792016-01-21 14:23:28 -080098 const rootService = lodash.find(services, {id: rootServiceId});
99
100 const serviceTree = buildLevel(tenants, services, rootService);
101
Matteo Scandoloff7df762016-01-22 16:36:34 -0800102 return {
103 name: subscriber.name,
104 parent: null,
Matteo Scandolof2c99012016-01-25 10:10:38 -0800105 type: 'subscriber',
Matteo Scandoloff7df762016-01-22 16:36:34 -0800106 children: [serviceTree]
107 };
108
Matteo Scandolof16b3792016-01-21 14:23:28 -0800109 };
110
Matteo Scandoloff7df762016-01-22 16:36:34 -0800111 const get = (subscriber) => {
Matteo Scandolof16b3792016-01-21 14:23:28 -0800112 var deferred = $q.defer();
113 var services, tenants;
114 Services.query().$promise
115 .then((res) => {
116 services = res;
117 return Tenant.query().$promise;
118 })
119 .then((res) => {
120 tenants = res;
Matteo Scandoloff7df762016-01-22 16:36:34 -0800121 deferred.resolve(buildServiceTree(services, tenants, subscriber));
Matteo Scandolof16b3792016-01-21 14:23:28 -0800122 })
123 .catch((e) => {
124 throw new Error(e);
125 });
126
127 return deferred.promise;
Matteo Scandolof2c99012016-01-25 10:10:38 -0800128 };
Matteo Scandoloff7df762016-01-22 16:36:34 -0800129
Matteo Scandolo5bf04572016-01-25 17:36:08 -0800130 const buildServiceInterfacesTree = (slices, instances) => {
131 var interfaceTree = [];
132 lodash.forEach(slices, (slice, i) => {
133 let current = {
134 name: slice.name,
135 slice: slice,
136 type: 'slice',
137 children: instances[i].map((instance) => {
138 return {
139 name: instance.humanReadableName,
140 children: [],
141 type: 'instance',
142 instance: instance
143 };
144
145 })
146 };
147 interfaceTree.push(current);
148 });
149 return interfaceTree;
150 };
151
Matteo Scandolo071ef462016-01-25 12:00:42 -0800152 const getServiceInterfaces = (serviceId) => {
153 var deferred = $q.defer();
154
155 var _slices;
156
157 Slice.query({service: serviceId}).$promise
158 .then((slices) => {
159 _slices = slices;
160 const promisesArr = slices.reduce((promises, slice) => {
161 promises.push(Instances.query({slice: slice.id}).$promise);
162 return promises;
163 }, []);
164
Matteo Scandolo9ef3c842016-01-25 13:55:09 -0800165 // TODO add networks
166 // decide how, they should be manually drawn
167 // as they connect more instances without parent dependencies
168
Matteo Scandolo071ef462016-01-25 12:00:42 -0800169 return $q.all(promisesArr);
170 })
171 .then((instances) => {
Matteo Scandolo5bf04572016-01-25 17:36:08 -0800172 deferred.resolve(buildServiceInterfacesTree(_slices, instances));
Matteo Scandolo071ef462016-01-25 12:00:42 -0800173 });
174
175 return deferred.promise;
176 };
177
Matteo Scandolof2c99012016-01-25 10:10:38 -0800178 // export APIs
Matteo Scandolo5bf04572016-01-25 17:36:08 -0800179 return {
180 get: get,
181 buildLevel: buildLevel,
182 buildServiceTree: buildServiceTree,
183 findLevelRelation: findLevelRelation,
184 findLevelServices: findLevelServices,
185 depthOf: depthOf,
186 getServiceInterfaces: getServiceInterfaces,
187 buildServiceInterfacesTree: buildServiceInterfacesTree
188 }
Matteo Scandolo8a64fa42016-01-21 11:21:03 -0800189 });
190
191}());