New observable notify design in pubsub
Implemented the new subscription mechanism for the pub sub notify function
Change-Id: I5e6484adf1a0413d48b54b55048cda1a59b387ee
Issue-ID: SDC-1178
Signed-off-by: Idan Amit <ia096e@intl.att.com>
diff --git a/catalog-ui/src/app/models/base-pubsub.ts b/catalog-ui/src/app/models/base-pubsub.ts
index ca313b1..b9ff788 100644
--- a/catalog-ui/src/app/models/base-pubsub.ts
+++ b/catalog-ui/src/app/models/base-pubsub.ts
@@ -5,10 +5,12 @@
subscribers: Map<string, ISubscriber>;
eventsCallbacks: Array<Function>;
clientId: string;
+ eventsToWait: Map<string, Array<string>>;
constructor(pluginId: string) {
this.subscribers = new Map<string, ISubscriber>();
- this.eventsCallbacks = new Array<Function>();
+ this.eventsCallbacks = [];
+ this.eventsToWait = new Map<string, Array<string>>();
this.clientId = pluginId;
this.onMessage = this.onMessage.bind(this);
@@ -29,7 +31,13 @@
}
public on(callback: Function) {
- this.eventsCallbacks.push(callback);
+ let functionExists = this.eventsCallbacks.find((func: Function) => {
+ return callback.toString() == func.toString()
+ });
+
+ if (!functionExists) {
+ this.eventsCallbacks.push(callback);
+ }
}
public off(callback: Function) {
@@ -44,9 +52,49 @@
originId: this.clientId
} as IPubSubEvent;
- this.subscribers.forEach( (subscriber: ISubscriber, id: string) => {
- subscriber.window.postMessage(eventObj, subscriber.locationUrl)
+ this.subscribers.forEach( (subscriber: ISubscriber, subscriberId: string) => {
+ subscriber.window.postMessage(eventObj, subscriber.locationUrl);
+
});
+
+ return {
+ subscribe: function(callbackFn) {
+
+ if(this.subscribers.size !== 0) {
+ let subscribersToNotify = Array.from(this.subscribers.keys());
+
+ const checkNotifyComplete = (subscriberId: string) => {
+
+ let index = subscribersToNotify.indexOf(subscriberId);
+ subscribersToNotify.splice(index, 1);
+
+ if (subscribersToNotify.length === 0) {
+ callbackFn();
+ }
+ };
+
+ this.subscribers.forEach((subscriber: ISubscriber, subscriberId: string) => {
+ if (this.eventsToWait.has(subscriberId) && this.eventsToWait.get(subscriberId).indexOf(eventType) !== -1) {
+
+ const actionCompletedFunction = (eventData, subId = subscriberId) => {
+ if (eventData.type == "ACTION_COMPLETED") {
+ checkNotifyComplete(subId);
+ }
+ this.off(actionCompletedFunction);
+
+ };
+ this.on(actionCompletedFunction);
+ }
+ else {
+ checkNotifyComplete(subscriberId);
+ }
+ });
+ }
+ else {
+ callbackFn();
+ }
+ }.bind(this)
+ }
}
protected onMessage(event: any) {
@@ -58,31 +106,6 @@
}
}
-export class PluginPubSub extends BasePubSub {
-
- constructor(pluginId: string, parentUrl: string) {
- super(pluginId);
- this.register('sdc-hub', window.parent, parentUrl);
- this.subscribe();
- }
-
- public subscribe() {
- const registerData = {
- pluginId: this.clientId
- };
-
- this.notify('PLUGIN_REGISTER', registerData);
- }
-
- public unsubscribe() {
- const unregisterData = {
- pluginId: this.clientId
- };
-
- this.notify('PLUGIN_UNREGISTER', unregisterData);
- }
-}
-
export interface IPubSubEvent {
type: string;
originId: string;
diff --git a/catalog-ui/src/app/models/plugin-pubsub.ts b/catalog-ui/src/app/models/plugin-pubsub.ts
new file mode 100644
index 0000000..3a34de9
--- /dev/null
+++ b/catalog-ui/src/app/models/plugin-pubsub.ts
@@ -0,0 +1,29 @@
+import {BasePubSub} from "./base-pubsub";
+
+declare const window: Window;
+
+export class PluginPubSub extends BasePubSub {
+
+ constructor(pluginId: string, parentUrl: string, eventsToWait?: Array<string>) {
+ super(pluginId);
+ this.register('sdc-hub', window.parent, parentUrl);
+ this.subscribe(eventsToWait);
+ }
+
+ public subscribe(eventsToWait?: Array<string>) {
+ const registerData = {
+ pluginId: this.clientId,
+ eventsToWait: eventsToWait || []
+ };
+
+ this.notify('PLUGIN_REGISTER', registerData);
+ }
+
+ public unsubscribe() {
+ const unregisterData = {
+ pluginId: this.clientId
+ };
+
+ this.notify('PLUGIN_UNREGISTER', unregisterData);
+ }
+}
diff --git a/catalog-ui/src/app/ng2/components/ui/plugin/plugin-frame.component.ts b/catalog-ui/src/app/ng2/components/ui/plugin/plugin-frame.component.ts
index 2ba7847..4759721 100644
--- a/catalog-ui/src/app/ng2/components/ui/plugin/plugin-frame.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/plugin/plugin-frame.component.ts
@@ -43,13 +43,16 @@
this.pluginUrl += this.urlSearchParams.toString();
}
- this.eventBusService.on((eventData) => {
+ let readyEvent = (eventData) => {
if (eventData.originId === this.plugin.pluginId) {
if (eventData.type == "READY") {
this.onLoadingDone.emit();
+ this.eventBusService.off(readyEvent)
}
}
- });
+ };
+
+ this.eventBusService.on(readyEvent);
// Listening to the stateChangeStart event in order to notify the plugin about it being closed
// before moving to a new state
@@ -58,11 +61,11 @@
if (!this.isClosed) {
event.preventDefault();
- this.eventBusService.notify("WINDOW_OUT");
+ this.eventBusService.notify("WINDOW_OUT").subscribe(() => {
+ this.isClosed = true;
- this.isClosed = true;
+ this.eventBusService.unregister(this.plugin.pluginId);
- setTimeout(() => {
this.$state.go(toState.name, toParams);
});
}
diff --git a/catalog-ui/src/app/ng2/services/event-bus.service.ts b/catalog-ui/src/app/ng2/services/event-bus.service.ts
index 7730a77..438437d 100644
--- a/catalog-ui/src/app/ng2/services/event-bus.service.ts
+++ b/catalog-ui/src/app/ng2/services/event-bus.service.ts
@@ -11,6 +11,18 @@
protected handlePluginRegistration(eventData: IPubSubEvent, event: any) {
if (eventData.type === 'PLUGIN_REGISTER') {
this.register(eventData.data.pluginId, event.source, event.origin);
+
+ let newEventsList = [];
+
+ if (this.eventsToWait.has(eventData.data.pluginId)) {
+ newEventsList = _.union(this.eventsToWait.get(eventData.data.pluginId), eventData.data.eventsToWait);
+ }
+ else {
+ newEventsList = eventData.data.eventsToWait;
+ }
+
+ this.eventsToWait.set(eventData.data.pluginId, newEventsList);
+
} else if (eventData.type === 'PLUGIN_UNREGISTER') {
this.unregister(eventData.data.pluginId);
}
@@ -21,8 +33,9 @@
pluginId: pluginId
};
- this.notify('PLUGIN_CLOSE', unregisterData);
- super.unregister(pluginId);
+ this.notify('PLUGIN_CLOSE', unregisterData).subscribe(() => {
+ super.unregister(pluginId);
+ });
}
protected onMessage(event: any) {
diff --git a/catalog-ui/src/app/services/components/component-service.ts b/catalog-ui/src/app/services/components/component-service.ts
index 8331bdb..0b68c8b 100644
--- a/catalog-ui/src/app/services/components/component-service.ts
+++ b/catalog-ui/src/app/services/components/component-service.ts
@@ -24,7 +24,6 @@
import {ComponentInstanceFactory, CommonUtils} from "app/utils";
import {SharingService} from "../sharing-service";
import {ComponentMetadata} from "../../models/component-metadata";
-import {EventBusService} from "../../ng2/services/event-bus.service";
export interface IComponentService {
@@ -82,16 +81,14 @@
'sdcConfig',
'Sdc.Services.SharingService',
'$q',
- '$base64',
- 'EventBusService'
+ '$base64'
];
constructor(protected restangular:restangular.IElement,
protected sdcConfig:IAppConfigurtaion,
protected sharingService:SharingService,
protected $q:ng.IQService,
- protected $base64:any,
- protected eventBusService:EventBusService
+ protected $base64:any
) {
this.restangular.setBaseUrl(sdcConfig.api.root + sdcConfig.api.component_api_root);
@@ -230,16 +227,6 @@
deferred.reject(err);
});
- // Notifying about events before executing the actual actions
- switch (state) {
- case "lifecycleState/CHECKIN":
- this.eventBusService.notify("CHECK_IN");
- break;
- case "lifecycleState/certificationRequest":
- this.eventBusService.notify("SUBMIT_FOR_TESTING");
- break;
- }
-
return deferred.promise;
};
diff --git a/catalog-ui/src/app/services/components/resource-service.ts b/catalog-ui/src/app/services/components/resource-service.ts
index aabc14f..15ef51e 100644
--- a/catalog-ui/src/app/services/components/resource-service.ts
+++ b/catalog-ui/src/app/services/components/resource-service.ts
@@ -26,7 +26,6 @@
import {IComponentService, ComponentService} from "./component-service";
import {PropertyModel, IAppConfigurtaion, Resource, Component} from "../../models";
import {SharingService} from "../sharing-service";
-import {EventBusService} from "../../ng2/services/event-bus.service";
export interface IResourceService extends IComponentService {
updateResourceGroupProperties(uniqueId:string, groupId:string, properties:Array<PropertyModel>):ng.IPromise<Array<PropertyModel>>
@@ -39,18 +38,16 @@
'sdcConfig',
'Sdc.Services.SharingService',
'$q',
- '$base64',
- 'EventBusService'
+ '$base64'
];
constructor(protected restangular:restangular.IElement,
protected sdcConfig:IAppConfigurtaion,
protected sharingService:SharingService,
protected $q:ng.IQService,
- protected $base64:any,
- protected eventBusService:EventBusService
+ protected $base64:any
) {
- super(restangular, sdcConfig, sharingService, $q, $base64, eventBusService);
+ super(restangular, sdcConfig, sharingService, $q, $base64);
this.restangular = restangular.one("resources");
}
diff --git a/catalog-ui/src/app/services/components/service-service.ts b/catalog-ui/src/app/services/components/service-service.ts
index ee3a023..cce0759 100644
--- a/catalog-ui/src/app/services/components/service-service.ts
+++ b/catalog-ui/src/app/services/components/service-service.ts
@@ -26,7 +26,6 @@
import {IComponentService, ComponentService} from "./component-service";
import {Distribution, DistributionComponent, Service, PropertyModel, Component, IAppConfigurtaion} from "app/models";
import {SharingService} from "../sharing-service";
-import {EventBusService} from "../../ng2/services/event-bus.service";
export interface IServiceService extends IComponentService {
getDistributionsList(uuid:string):ng.IPromise<Array<Distribution>>;
@@ -42,8 +41,7 @@
'sdcConfig',
'Sdc.Services.SharingService',
'$q',
- '$base64',
- 'EventBusService'
+ '$base64'
];
public distribution:string = "distribution";
@@ -52,9 +50,8 @@
protected sdcConfig:IAppConfigurtaion,
protected sharingService:SharingService,
protected $q:ng.IQService,
- protected $base64:any,
- protected eventBusService:EventBusService) {
- super(restangular, sdcConfig, sharingService, $q, $base64, eventBusService);
+ protected $base64:any) {
+ super(restangular, sdcConfig, sharingService, $q, $base64);
this.restangular = restangular.one("services");
}
diff --git a/catalog-ui/src/app/utils/change-lifecycle-state-handler.ts b/catalog-ui/src/app/utils/change-lifecycle-state-handler.ts
index d32730d..f1c6544 100644
--- a/catalog-ui/src/app/utils/change-lifecycle-state-handler.ts
+++ b/catalog-ui/src/app/utils/change-lifecycle-state-handler.ts
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,6 +24,7 @@
import {AsdcComment} from "../models/comments";
import {ModalsHandler} from "./modals-handler";
import {ServiceServiceNg2} from "../ng2/services/component-services/service.service";
+import {EventBusService} from "../ng2/services/event-bus.service";
/**
* Created by obarda on 2/11/2016.
@@ -37,7 +38,8 @@
'ComponentFactory',
'$filter',
'ModalsHandler',
- 'ServiceServiceNg2'
+ 'ServiceServiceNg2',
+ 'EventBusService'
];
constructor(private sdcConfig:IAppConfigurtaion,
@@ -45,7 +47,8 @@
private ComponentFactory:ComponentFactory,
private $filter:ng.IFilterService,
private ModalsHandler:ModalsHandler,
- private ServiceServiceNg2:ServiceServiceNg2) {
+ private ServiceServiceNg2:ServiceServiceNg2,
+ private eventBusService:EventBusService) {
}
@@ -101,7 +104,12 @@
let onOk = (confirmationText):void => {
comment.userRemarks = confirmationText;
scope.isLoading = true;
- component.changeLifecycleState(data.url, comment).then(onSuccess, onError);
+
+ if (data.url === "lifecycleState/CHECKIN") {
+ this.eventBusService.notify("CHECK_IN").subscribe(() => {
+ component.changeLifecycleState(data.url, comment).then(onSuccess, onError);
+ });
+ }
};
let onCancel = ():void => {
@@ -118,10 +126,14 @@
// Show email dialog if defined in menu.json
//-------------------------------------------------
let onOk = (resource):void => {
- if (resource) {
- onSuccess(resource);
- } else {
- onError("Error changing life cycle state");
+ if (data.url === "lifecycleState/certificationRequest") {
+ this.eventBusService.notify("SUBMIT_FOR_TESTING").subscribe(() => {
+ if (resource) {
+ onSuccess(resource);
+ } else {
+ onError("Error changing life cycle state");
+ }
+ });
}
};
diff --git a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts
index 5d83c34..7fa2517 100644
--- a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts
@@ -283,15 +283,14 @@
version: this.$scope.changeVersion.selectedVersion.versionNumber
};
- this.eventBusService.notify("VERSION_CHANGED", eventData);
-
- this.$state.go(this.$state.current.name, {
- id: selectedId,
- type: this.$scope.componentType.toLowerCase(),
- mode: WorkspaceMode.VIEW,
- components: this.$state.params['components']
- }, {reload: true});
-
+ this.eventBusService.notify("VERSION_CHANGED", eventData).subscribe(() => {
+ this.$state.go(this.$state.current.name, {
+ id: selectedId,
+ type: this.$scope.componentType.toLowerCase(),
+ mode: WorkspaceMode.VIEW,
+ components: this.$state.params['components']
+ }, {reload: true});
+ });
};
this.$scope.getLatestVersion = ():void => {
@@ -472,36 +471,38 @@
switch (url) {
case 'lifecycleState/CHECKOUT':
- // only checkOut get the full component from server
- // this.$scope.component = component;
- // Work around to change the csar version
- if (this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
- (<Resource>this.$scope.component).csarVersion = this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
- }
+ this.eventBusService.notify("CHECK_OUT", eventData).subscribe(() => {
+ // only checkOut get the full component from server
+ // this.$scope.component = component;
+ // Work around to change the csar version
+ if (this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
+ (<Resource>this.$scope.component).csarVersion = this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
+ }
- //when checking out a minor version uuid remains
- const bcIdx = _.findIndex(this.components, (item) => {
- return item.uuid === component.uuid;
- });
- if (bcIdx !== -1) {
- this.components[bcIdx] = component;
- } else {
- //when checking out a major(certified) version
- this.components.unshift(component);
- }
- // this.$state.go(this.$state.current.name, {
- // id: component.uniqueId,
- // type: component.componentType.toLowerCase(),
- // components: this.components
- // });
- this.$scope.mode = this.initViewMode();
- this.initChangeLifecycleStateButtons();
- this.initVersionObject();
- this.$scope.isLoading = false;
- this.EventListenerService.notifyObservers(EVENTS.ON_CHECKOUT, component);
- this.Notification.success({
- message: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TEXT"),
- title: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TITLE")
+ //when checking out a minor version uuid remains
+ const bcIdx = _.findIndex(this.components, (item) => {
+ return item.uuid === component.uuid;
+ });
+ if (bcIdx !== -1) {
+ this.components[bcIdx] = component;
+ } else {
+ //when checking out a major(certified) version
+ this.components.unshift(component);
+ }
+ // this.$state.go(this.$state.current.name, {
+ // id: component.uniqueId,
+ // type: component.componentType.toLowerCase(),
+ // components: this.components
+ // });
+ this.$scope.mode = this.initViewMode();
+ this.initChangeLifecycleStateButtons();
+ this.initVersionObject();
+ this.$scope.isLoading = false;
+ this.EventListenerService.notifyObservers(EVENTS.ON_CHECKOUT, component);
+ this.Notification.success({
+ message: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TEXT"),
+ title: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TITLE")
+ });
});
break;
case 'lifecycleState/CHECKIN':
@@ -512,7 +513,7 @@
});
break;
case 'lifecycleState/UNDOCHECKOUT':
- setTimeout(() => {
+ this.eventBusService.notify("UNDO_CHECK_OUT", eventData).subscribe(() => {
defaultActionAfterChangeLifecycleState();
this.Notification.success({
message: this.$filter('translate')("DELETE_SUCCESS_MESSAGE_TEXT"),