blob: 2f850288c16b7efa5e9dba5c73b7ff5958c24681 [file] [log] [blame]
Matteo Scandolo47860fe2017-02-02 12:05:55 -08001import {IWSEventService, IWSEvent} from '../../datasources/websocket/global';
2import {IXosModelStoreService} from '../../datasources/stores/model.store';
3import * as _ from 'lodash';
4import {Observable} from 'rxjs';
Matteo Scandolo4e870232017-01-30 13:43:05 -08005
6export interface IXosOnboarder {
7
8}
9
10export class XosOnboarder implements IXosOnboarder {
Matteo Scandolo1aee1982017-02-17 08:33:23 -080011 static $inject = ['$timeout', '$log', '$q', 'WebSocket', '$ocLazyLoad', 'XosModelStore'];
Matteo Scandolo4e870232017-01-30 13:43:05 -080012
13 constructor(
14 private $timeout: ng.ITimeoutService,
15 private $log: ng.ILogService,
16 private $q: ng.IQService,
17 private webSocket: IWSEventService,
Matteo Scandolo47860fe2017-02-02 12:05:55 -080018 private $ocLazyLoad: any, // TODO add definition
Matteo Scandolo1aee1982017-02-17 08:33:23 -080019 private XosModelStore: IXosModelStoreService
Matteo Scandolo4e870232017-01-30 13:43:05 -080020 ) {
21 this.$log.info('[XosOnboarder] Setup');
Matteo Scandolo47860fe2017-02-02 12:05:55 -080022
23 // Listen for new app (we need a pause to allow the container to boot)
Matteo Scandolo4e870232017-01-30 13:43:05 -080024 this.webSocket.list()
Matteo Scandolo47860fe2017-02-02 12:05:55 -080025 .filter((e: IWSEvent) => {
26 if (e.model === 'XOSComponent' && e.msg.object.extra) {
27 e.msg.object.extra = JSON.parse(e.msg.object.extra);
28 return true;
29 }
30 return false;
Matteo Scandolo4e870232017-01-30 13:43:05 -080031 })
32 .subscribe(
33 (event) => {
Matteo Scandolo47860fe2017-02-02 12:05:55 -080034 this.$timeout(() => {
35 this.$log.info(`[XosOnboarder] Loading files for app: ${event.msg.object.name}`);
36 // NOTE we need the timeout because the event is triggered when the model is created,
37 // XOS take around 15s to boot it
38 this.loadFile(event.msg.object.extra)
39 .then((res) => {
40 this.$log.info(`[XosOnboarder] All files loaded for app: ${event.msg.object.name}`);
41 });
42 }, 20 * 1000);
43 }
44 );
45
46 // Load previously onboarded app (containers are already running, so we don't need to wait)
47 let componentsLoaded = false;
Matteo Scandolo1aee1982017-02-17 08:33:23 -080048 const ComponentObservable: Observable<any> = this.XosModelStore.query('XOSComponent');
Matteo Scandolo47860fe2017-02-02 12:05:55 -080049 ComponentObservable.subscribe(
50 (component) => {
51 if (componentsLoaded) {
52 // if we have already loaded the component present when we loaded the page
53 // do nothing, we are intercepting WS to give the container time to boot
54 return;
55 }
56
57 _.forEach(component, (c) => {
58 if (c.extra) {
59 this.$log.info(`[XosOnboarder] Loading files for app: ${c.name}`);
60 let extra;
61 try {
62 extra = JSON.parse(c.extra);
63 } catch (e) {
64 extra = c.extra;
65 }
66 this.loadFile(extra)
67 .then((res) => {
68 this.$log.info(`[XosOnboarder] All files loaded for app: ${c.name}`);
69 });
70 }
71 });
72 componentsLoaded = true;
Matteo Scandolo4e870232017-01-30 13:43:05 -080073 }
74 );
75 }
76
77 // NOTE files needs to be loaded in order, so async loop!
78 private loadFile(files: string[], d?: ng.IDeferred<any>): ng.IPromise<string[]> {
79 if (!angular.isDefined(d)) {
80 d = this.$q.defer();
81 }
82 const file = files.shift();
83 this.$log.info(`[XosOnboarder] Loading file: ${file}`);
84 this.$ocLazyLoad.load(file)
85 .then((res) => {
86 this.$log.info(`[XosOnboarder] Loaded file: `, file);
87 if (files.length > 0) {
88 return this.loadFile(files, d);
89 }
90 return d.resolve(file);
91 })
92 .catch((err) => {
93 this.$log.error(`[XosOnboarder] Failed to load file: `, err);
94 d.reject(err);
95 });
96
97 return d.promise;
98 }
99}