blob: f9d4d152ee1e95c173652f3956f10b5aa57f78c6 [file] [log] [blame]
Matteo Scandolo968e7f22017-03-03 11:49:18 -08001import * as _ from 'lodash';
Matteo Scandoloa62adbc2017-03-02 15:37:34 -08002import {Observable, BehaviorSubject} from 'rxjs';
3import {IXosModelStoreService} from '../../datasources/stores/model.store';
Matteo Scandolo968e7f22017-03-03 11:49:18 -08004import {
5 IXosServiceGraph, IXosServiceModel, IXosTenantModel, IXosCoarseGraphData,
6 IXosServiceGraphNode, IXosServiceGraphLink
7} from '../interfaces';
Matteo Scandoloa62adbc2017-03-02 15:37:34 -08008import {IXosDebouncer} from '../../core/services/helpers/debounce.helper';
9export interface IXosServiceGraphStore {
10 get(): Observable<IXosServiceGraph>;
Matteo Scandolo968e7f22017-03-03 11:49:18 -080011 getCoarse(): Observable<IXosServiceGraph>;
Matteo Scandoloa62adbc2017-03-02 15:37:34 -080012}
13
14export class XosServiceGraphStore implements IXosServiceGraphStore {
15 static $inject = [
16 '$log',
17 'XosModelStore',
18 'XosDebouncer'
19 ];
Matteo Scandolo968e7f22017-03-03 11:49:18 -080020
21 // graph data store
22 private graphData: BehaviorSubject<IXosCoarseGraphData> = new BehaviorSubject({
23 services: [],
24 tenants: []
25 });
26
27 // reprentations of the graph as D3 requires
28 private d3CoarseGraph = new BehaviorSubject({});
29 private d3FineGrainedGraph = new BehaviorSubject({});
Matteo Scandoloa62adbc2017-03-02 15:37:34 -080030
31 // storing locally reference to the data model
32 private services;
33 private tenants;
34
35 // debounced functions
36 private handleData;
37
38 // datastore
39 private ServiceObservable: Observable<any>;
40 private TenantObservable: Observable<any>;
41
42 constructor (
43 private $log: ng.ILogService,
44 private XosModelStore: IXosModelStoreService,
45 private XosDebouncer: IXosDebouncer
46 ) {
47
Matteo Scandolo968e7f22017-03-03 11:49:18 -080048 this.$log.info(`[XosServiceGraphStore] Setup`);
49
Matteo Scandoloa62adbc2017-03-02 15:37:34 -080050 // we want to have a quiet period of 500ms from the last event before doing anything
Matteo Scandolo968e7f22017-03-03 11:49:18 -080051 this.handleData = this.XosDebouncer.debounce(this._handleData, 500, this, false);
Matteo Scandoloa62adbc2017-03-02 15:37:34 -080052
53 this.ServiceObservable = this.XosModelStore.query('Service', '/core/services');
Matteo Scandolo968e7f22017-03-03 11:49:18 -080054 this.TenantObservable = this.XosModelStore.query('Tenant', '/core/tenants');
Matteo Scandoloa62adbc2017-03-02 15:37:34 -080055
Matteo Scandolo968e7f22017-03-03 11:49:18 -080056 // observe models and populate graphData
Matteo Scandoloa62adbc2017-03-02 15:37:34 -080057 this.ServiceObservable
58 .subscribe(
59 (res) => {
60 this.combineData(res, 'services');
61 },
62 (err) => {
63 this.$log.error(err);
64 }
65 );
66
Matteo Scandolo968e7f22017-03-03 11:49:18 -080067 this.TenantObservable
Matteo Scandoloa62adbc2017-03-02 15:37:34 -080068 .subscribe(
69 (res) => {
70 this.combineData(res, 'tenants');
71 },
72 (err) => {
73 this.$log.error(err);
74 }
75 );
Matteo Scandolo968e7f22017-03-03 11:49:18 -080076
77 // observe graphData and build Coarse or FineGrained graphs (based on who's subscribed)
78 this.graphData
79 .subscribe(
80 (res: IXosCoarseGraphData) => {
81 if (this.d3CoarseGraph.observers.length > 0) {
82 this.graphDataToCoarseGraph(res);
83 }
84 if (this.d3FineGrainedGraph.observers.length > 0) {
85 // TODO graphDataToFineGrainedGraph
86 }
87 },
88 (err) => {
89 this.$log.error(`[XosServiceGraphStore] graphData Observable: `, err);
90 }
91 );
Matteo Scandoloa62adbc2017-03-02 15:37:34 -080092 }
93
94 public get() {
Matteo Scandolo968e7f22017-03-03 11:49:18 -080095 return this.d3FineGrainedGraph.asObservable();
96 }
97
98 public getCoarse() {
99 return this.d3CoarseGraph.asObservable();
Matteo Scandoloa62adbc2017-03-02 15:37:34 -0800100 }
101
102 private combineData(data: any, type: 'services'|'tenants') {
103 switch (type) {
104 case 'services':
105 this.services = data;
106 break;
107 case 'tenants':
108 this.tenants = data;
109 break;
110 }
111 this.handleData(this.services, this.tenants);
112 }
113
114 private _handleData(services: IXosServiceModel[], tenants: IXosTenantModel[]) {
Matteo Scandolo968e7f22017-03-03 11:49:18 -0800115 this.graphData.next({
116 services: this.services,
117 tenants: this.tenants
118 });
119 }
120
121 private graphDataToCoarseGraph(data: IXosCoarseGraphData) {
122
123 const links: IXosServiceGraphLink[] = _.chain(data.tenants)
124 .filter((t: IXosTenantModel) => t.kind === 'coarse')
125 .map((t: IXosTenantModel) => {
126 return {
127 id: t.id,
128 source: t.provider_service_id,
129 target: t.subscriber_service_id,
130 model: t
131 };
132 })
133 .value();
134
135 // NOTE show all services anyway or find only the node that have links pointing to it
136 const nodes: IXosServiceGraphNode[] = _.map(data.services, (s: IXosServiceModel) => {
137 return {
138 id: s.id,
139 label: s.name,
140 model: s
141 };
142 });
143
144 // TODO call next on this.d3CoarseGraph
145 this.d3CoarseGraph.next({
146 nodes: nodes,
147 links: links
148 });
Matteo Scandoloa62adbc2017-03-02 15:37:34 -0800149 }
150
151}