CORD-772 Loading external app when a new XosComponent of that kind is created and injecting loaded components at boot

Change-Id: I4f70d3b1e48b63eab3b8f8d2ca3f5b049b468f4c
diff --git a/src/app/extender/services/onboard.service.ts b/src/app/extender/services/onboard.service.ts
index 70d830c..402557c 100644
--- a/src/app/extender/services/onboard.service.ts
+++ b/src/app/extender/services/onboard.service.ts
@@ -1,32 +1,75 @@
-import {IWSEventService} from '../../datasources/websocket/global';
+import {IWSEventService, IWSEvent} from '../../datasources/websocket/global';
+import {IXosModelStoreService} from '../../datasources/stores/model.store';
+import * as _ from 'lodash';
+import {Observable} from 'rxjs';
 
 export interface IXosOnboarder {
 
 }
 
 export class XosOnboarder implements IXosOnboarder {
-  static $inject = ['$timeout', '$log', '$q', 'WebSocket', '$ocLazyLoad'];
+  static $inject = ['$timeout', '$log', '$q', 'WebSocket', '$ocLazyLoad', 'ModelStore'];
 
   constructor(
     private $timeout: ng.ITimeoutService,
     private $log: ng.ILogService,
     private $q: ng.IQService,
     private webSocket: IWSEventService,
-    private $ocLazyLoad: any // TODO add definition
+    private $ocLazyLoad: any, // TODO add definition
+    private ModelStore: IXosModelStoreService
   ) {
     this.$log.info('[XosOnboarder] Setup');
+
+    // Listen for new app (we need a pause to allow the container to boot)
     this.webSocket.list()
-      .filter((e) => {
-        this.$log.log(e);
-        // TODO define event format
-        return e.msg['files'].length > 0;
+      .filter((e: IWSEvent) => {
+        if (e.model === 'XOSComponent' && e.msg.object.extra) {
+          e.msg.object.extra = JSON.parse(e.msg.object.extra);
+          return true;
+        }
+        return false;
       })
       .subscribe(
         (event) => {
-          this.loadFile(event.msg['files'])
-            .then((res) => {
-              this.$log.info(`[XosOnboarder] All files loaded for app: ${event.msg['app']}`);
-            });
+          this.$timeout(() => {
+            this.$log.info(`[XosOnboarder] Loading files for app: ${event.msg.object.name}`);
+            // NOTE we need the timeout because the event is triggered when the model is created,
+            // XOS take around 15s to boot it
+            this.loadFile(event.msg.object.extra)
+              .then((res) => {
+                this.$log.info(`[XosOnboarder] All files loaded for app: ${event.msg.object.name}`);
+              });
+          }, 20 * 1000);
+        }
+      );
+
+    // Load previously onboarded app (containers are already running, so we don't need to wait)
+    let componentsLoaded = false;
+    const ComponentObservable: Observable<any> = this.ModelStore.query('XOSComponent');
+    ComponentObservable.subscribe(
+        (component) => {
+          if (componentsLoaded) {
+            // if we have already loaded the component present when we loaded the page
+            // do nothing, we are intercepting WS to give the container time to boot
+            return;
+          }
+
+          _.forEach(component, (c) => {
+            if (c.extra) {
+              this.$log.info(`[XosOnboarder] Loading files for app: ${c.name}`);
+              let extra;
+              try {
+                extra = JSON.parse(c.extra);
+              } catch (e) {
+                extra = c.extra;
+              }
+              this.loadFile(extra)
+                .then((res) => {
+                  this.$log.info(`[XosOnboarder] All files loaded for app: ${c.name}`);
+                });
+            }
+          });
+          componentsLoaded = true;
         }
       );
   }