[CORD-1250] Rendering new ServiceInstance Models
Change-Id: Ic8fdb4775b119816b4b7aa085e6af699eaa13a67
diff --git a/src/app/service-graph/services/service-graph.store.ts b/src/app/service-graph/services/service-graph.store.ts
new file mode 100644
index 0000000..d784958
--- /dev/null
+++ b/src/app/service-graph/services/service-graph.store.ts
@@ -0,0 +1,209 @@
+import * as _ from 'lodash';
+import {Observable, BehaviorSubject, Subscription} from 'rxjs';
+import {IXosModelStoreService} from '../../datasources/stores/model.store';
+import {
+ IXosServiceGraph, IXosServiceModel, IXosTenantModel, IXosCoarseGraphData,
+ IXosServiceGraphNode, IXosServiceGraphLink, IXosFineGrainedGraphData
+} from '../interfaces';
+import {IXosDebouncer} from '../../core/services/helpers/debounce.helper';
+export interface IXosServiceGraphStore {
+ // TODO remove, moved in a new service
+ get(): Observable<IXosServiceGraph>;
+ // TODO rename in get()
+ getCoarse(): Observable<IXosServiceGraph>;
+}
+
+export class XosServiceGraphStore implements IXosServiceGraphStore {
+ static $inject = [
+ '$log',
+ 'XosModelStore',
+ 'XosDebouncer'
+ ];
+
+ // graph data store
+ private graphData: BehaviorSubject<IXosFineGrainedGraphData> = new BehaviorSubject({
+ services: [],
+ tenants: [],
+ networks: [],
+ subscribers: [],
+ servicedependencies: []
+ });
+
+ private emptyGraph: IXosServiceGraph = {
+ nodes: [],
+ links: []
+ };
+
+ // representation of the graph as D3 requires
+ private d3CoarseGraph = new BehaviorSubject(this.emptyGraph);
+ private d3FineGrainedGraph = new BehaviorSubject(this.emptyGraph);
+
+ // storing locally reference to the data model
+ private services;
+ private tenants;
+ private subscribers;
+ private networks;
+ private servicedependencys;
+
+ // debounced functions
+ private handleData;
+
+ // datastore
+ private ServiceSubscription: Subscription;
+ private TenantSubscription: Subscription;
+ private SubscriberSubscription: Subscription;
+ private NetworkSubscription: Subscription;
+ private ServiceDependencySubscription: Subscription;
+
+ constructor (
+ private $log: ng.ILogService,
+ private XosModelStore: IXosModelStoreService,
+ private XosDebouncer: IXosDebouncer
+ ) {
+
+ this.$log.info(`[XosServiceGraphStore] Setup`);
+
+ // we want to have a quiet period of 500ms from the last event before doing anything
+ this.handleData = this.XosDebouncer.debounce(this._handleData, 500, this, false);
+
+ // observe models and populate graphData
+ this.ServiceSubscription = this.XosModelStore.query('Service', '/core/services')
+ .subscribe(
+ (res) => {
+ this.combineData(res, 'services');
+ },
+ (err) => {
+ this.$log.error(`[XosServiceGraphStore] Service Observable: `, err);
+ }
+ );
+
+ this.ServiceDependencySubscription = this.XosModelStore.query('ServiceDependency', '/core/servicedependencys')
+ .subscribe(
+ (res) => {
+ this.combineData(res, 'servicedependencies');
+ },
+ (err) => {
+ this.$log.error(`[XosServiceGraphStore] Service Observable: `, err);
+ }
+ );
+
+ this.TenantSubscription = this.XosModelStore.query('Tenant', '/core/tenants')
+ .subscribe(
+ (res) => {
+ this.combineData(res, 'tenants');
+ },
+ (err) => {
+ this.$log.error(`[XosServiceGraphStore] Tenant Observable: `, err);
+ }
+ );
+
+ this.SubscriberSubscription = this.XosModelStore.query('Tenantroot', '/core/tenantroots')
+ .subscribe(
+ (res) => {
+ this.combineData(res, 'subscribers');
+ },
+ (err) => {
+ this.$log.error(`[XosServiceGraphStore] Subscriber Observable: `, err);
+ }
+ );
+
+ this.NetworkSubscription = this.XosModelStore.query('Network', '/core/networks')
+ .subscribe(
+ (res) => {
+ this.combineData(res, 'networks');
+ },
+ (err) => {
+ this.$log.error(`[XosServiceGraphStore] graphData Observable: `, err);
+ }
+ );
+
+ // observe graphData and build Coarse and FineGrained graphs
+ this.graphData
+ .subscribe(
+ (res: IXosFineGrainedGraphData) => {
+ this.$log.debug(`[XosServiceGraphStore] New graph data received`, res);
+ this.graphDataToCoarseGraph(res);
+ // this.graphDataToFineGrainedGraph(res);
+ },
+ (err) => {
+ this.$log.error(`[XosServiceGraphStore] graphData Observable: `, err);
+ }
+ );
+ }
+
+ public get() {
+ return this.d3FineGrainedGraph.asObservable();
+ }
+
+ public getCoarse() {
+ return this.d3CoarseGraph.asObservable();
+ }
+
+ private combineData(data: any, type: 'services'|'tenants'|'subscribers'|'networks'|'servicedependencies') {
+ switch (type) {
+ case 'services':
+ this.services = data;
+ break;
+ case 'tenants':
+ this.tenants = data;
+ break;
+ case 'subscribers':
+ this.subscribers = data;
+ break;
+ case 'networks':
+ this.networks = data;
+ break;
+ case 'servicedependencies':
+ this.servicedependencys = data;
+ break;
+ }
+ this.handleData(this.services, this.tenants);
+ }
+
+ private _handleData(services: IXosServiceModel[], tenants: IXosTenantModel[]) {
+ this.graphData.next({
+ services: this.services,
+ tenants: this.tenants,
+ subscribers: this.subscribers,
+ networks: this.networks,
+ servicedependencies: this.servicedependencys
+ });
+ }
+
+ private getNodeIndexById(id: number | string, nodes: IXosServiceModel[]) {
+ return _.findIndex(nodes, {id: id});
+ }
+
+ private graphDataToCoarseGraph(data: IXosCoarseGraphData) {
+
+ try {
+ const links: IXosServiceGraphLink[] = _.chain(data.servicedependencies)
+ .map((t: IXosTenantModel) => {
+ return {
+ id: t.id,
+ source: this.getNodeIndexById(t.provider_service_id, data.services),
+ target: this.getNodeIndexById(t.subscriber_service_id, data.services),
+ model: t
+ };
+ })
+ .value();
+
+ const nodes: IXosServiceGraphNode[] = _.map(data.services, (s: IXosServiceModel) => {
+ return {
+ id: s.id,
+ label: s.name,
+ model: s
+ };
+ });
+
+ let graph: IXosServiceGraph = {
+ nodes,
+ links
+ };
+
+ this.d3CoarseGraph.next(graph);
+ } catch (e) {
+ this.d3CoarseGraph.error(e);
+ }
+ }
+}