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.spec.ts b/src/app/extender/services/onboard.service.spec.ts
index f9373c9..375aadb 100644
--- a/src/app/extender/services/onboard.service.spec.ts
+++ b/src/app/extender/services/onboard.service.spec.ts
@@ -5,7 +5,7 @@
import {XosOnboarder, IXosOnboarder} from './onboard.service';
import {IWSEventService} from '../../datasources/websocket/global';
-let service, $ocLazyLoad;
+let service, $ocLazyLoad, $timeout;
const subject = new Subject();
@@ -32,6 +32,16 @@
}
};
+const MockModelStore = {
+ query: () => {
+ return {
+ subscribe: () => {
+ return;
+ }
+ };
+ }
+};
+
describe('The XosOnboarder service', () => {
beforeEach(() => {
@@ -40,6 +50,7 @@
.module('XosOnboarder', [])
.value('WebSocket', MockWs)
.value('$ocLazyLoad', MockLoad)
+ .value('ModelStore', MockModelStore)
.service('XosOnboarder', XosOnboarder);
angular.mock.module('XosOnboarder');
@@ -47,21 +58,28 @@
beforeEach(angular.mock.inject((
XosOnboarder: IXosOnboarder,
- _$ocLazyLoad_: any
+ _$ocLazyLoad_: any,
+ _$timeout_: ng.ITimeoutService
) => {
$ocLazyLoad = _$ocLazyLoad_;
spyOn($ocLazyLoad, 'load').and.callThrough();
service = XosOnboarder;
+ $timeout = _$timeout_;
}));
describe('when receive an event', () => {
it('should use $ocLazyLoad to add modules to the app', () => {
subject.next({
+ model: 'XOSComponent',
msg: {
app: 'sample',
- files: ['vendor.js', 'app.js']
+ object: {
+ extra: '["vendor.js", "app.js"]',
+ name: 'sample app'
+ }
}
});
+ $timeout.flush();
expect($ocLazyLoad.load).toHaveBeenCalledWith('vendor.js');
expect($ocLazyLoad.load).toHaveBeenCalledWith('app.js');
});
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;
}
);
}