From 71904f241cd3047054dc0a36c04120a3f53205ae Mon Sep 17 00:00:00 2001 From: Idan Amit Date: Tue, 13 Feb 2018 10:38:16 +0200 Subject: [PATCH] Plugin pubsub implementation Added implementation for sdc-hub and plugin pubsub classes Added timeout in the plugin head request health check Passing parentUrl in query params to each plugin Change-Id: Ie94aa4b398dd2fcfdf2d134f6c5785d3aa50d237 Issue-ID: SDC-1007 Signed-off-by: Idan Amit --- .../org/openecomp/sdc/fe/impl/PluginStatusBL.java | 7 ++ catalog-ui/src/app/models/base-pubsub.ts | 95 ++++++++++++++++++++++ catalog-ui/src/app/ng2/app.module.ts | 5 +- .../src/app/ng2/services/event-bus.service.ts | 39 +++++++++ .../view-models/plugins/plugins-tab-view-model.ts | 3 +- .../tabs/plugins/plugins-context-view-model.ts | 4 +- sdc-os-chef/environments/Template.json | 14 ++-- 7 files changed, 155 insertions(+), 12 deletions(-) create mode 100644 catalog-ui/src/app/models/base-pubsub.ts create mode 100644 catalog-ui/src/app/ng2/services/event-bus.service.ts diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/PluginStatusBL.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/PluginStatusBL.java index a369d661fc..563dc22507 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/PluginStatusBL.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/PluginStatusBL.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpHead; import org.apache.http.impl.client.CloseableHttpClient; @@ -60,6 +61,12 @@ public class PluginStatusBL { boolean result = false; HttpHead head = new HttpHead(plugin.getPluginDiscoveryUrl()); + RequestConfig requestConfig = RequestConfig.custom() + .setSocketTimeout(1000) + .setConnectTimeout(1000) + .setConnectionRequestTimeout(1000).build(); + + head.setConfig(requestConfig); try (CloseableHttpResponse response = this.client.execute(head)) { result = response != null && response.getStatusLine().getStatusCode() == 200; diff --git a/catalog-ui/src/app/models/base-pubsub.ts b/catalog-ui/src/app/models/base-pubsub.ts new file mode 100644 index 0000000000..ca500ca173 --- /dev/null +++ b/catalog-ui/src/app/models/base-pubsub.ts @@ -0,0 +1,95 @@ +declare const window: Window; + +export class BasePubSub { + + subscribers: Map; + eventsCallbacks: Array; + clientId: string; + + constructor(pluginId: string) { + this.subscribers = new Map(); + this.eventsCallbacks = new Array(); + this.clientId = pluginId; + this.onMessage = this.onMessage.bind(this); + + window.addEventListener("message", this.onMessage); + } + + public register(subscriberId: string, subscriberWindow: Window, subscriberUrl: string) { + const subscriber = { + window: subscriberWindow, + locationUrl: subscriberUrl || subscriberWindow.location.href + } as ISubscriber; + + this.subscribers.set(subscriberId, subscriber); + } + + public unregister(subscriberId: string) { + this.subscribers.delete(subscriberId); + } + + public on(callback: Function) { + this.eventsCallbacks.push(callback); + } + + public off(callback: Function) { + let index = this.eventsCallbacks.indexOf(callback); + this.eventsCallbacks.splice(index, 1) + } + + public notify(eventType:string, eventData:any) { + let eventObj = { + type: eventType, + data: eventData, + originId: this.clientId + } as IPubSubEvent; + + this.subscribers.forEach( (subscriber: ISubscriber, id: string) => { + subscriber.window.postMessage(eventObj, subscriber.locationUrl) + }); + } + + protected onMessage(event: any) { + if (this.subscribers.has(event.data.originId)) { + this.eventsCallbacks.forEach((callback: Function) => { + callback(event.data, event); + }) + } + } +} + +export class PluginPubSub extends BasePubSub { + + constructor(pluginId: string, subscriberUrl: string) { + super(pluginId); + this.register('sdc-hub', window.parent, subscriberUrl); + 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; + data: any; +} + +export interface ISubscriber { + window: Window; + locationUrl: string; +} diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts index a5a2fed18b..0346b10915 100644 --- a/catalog-ui/src/app/ng2/app.module.ts +++ b/catalog-ui/src/app/ng2/app.module.ts @@ -48,6 +48,7 @@ import { TranslateModule } from "./shared/translator/translate.module"; import { TranslationServiceConfig } from "./config/translation.service.config"; import {PluginFrameModule} from "./components/ui/plugin/plugin-frame.module"; import {PluginsService} from "./services/plugins.service"; +import {EventBusService} from "./services/event-bus.service"; export const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule)); @@ -99,6 +100,7 @@ export function configServiceFactory(config:ConfigService) { ComponentInstanceServiceNg2, TranslationServiceConfig, PluginsService, + EventBusService, { provide: APP_INITIALIZER, useFactory: configServiceFactory, @@ -112,7 +114,6 @@ export function configServiceFactory(config:ConfigService) { export class AppModule { - constructor(public upgrade:UpgradeModule) { - + constructor(public upgrade:UpgradeModule, eventBusService:EventBusService) { } } diff --git a/catalog-ui/src/app/ng2/services/event-bus.service.ts b/catalog-ui/src/app/ng2/services/event-bus.service.ts new file mode 100644 index 0000000000..7730a77f41 --- /dev/null +++ b/catalog-ui/src/app/ng2/services/event-bus.service.ts @@ -0,0 +1,39 @@ +import { Injectable } from '@angular/core'; +import {BasePubSub, IPubSubEvent} from "../../models/base-pubsub"; + +@Injectable() +export class EventBusService extends BasePubSub { + + constructor() { + super("sdc-hub"); + } + + protected handlePluginRegistration(eventData: IPubSubEvent, event: any) { + if (eventData.type === 'PLUGIN_REGISTER') { + this.register(eventData.data.pluginId, event.source, event.origin); + } else if (eventData.type === 'PLUGIN_UNREGISTER') { + this.unregister(eventData.data.pluginId); + } + } + + public unregister(pluginId: string) { + const unregisterData = { + pluginId: pluginId + }; + + this.notify('PLUGIN_CLOSE', unregisterData); + super.unregister(pluginId); + } + + protected onMessage(event: any) { + if (event.data.type === 'PLUGIN_REGISTER') { + this.handlePluginRegistration(event.data, event); + } + + super.onMessage(event); + + if (event.data.type === 'PLUGIN_UNREGISTER') { + this.handlePluginRegistration(event.data, event); + } + } +} diff --git a/catalog-ui/src/app/view-models/plugins/plugins-tab-view-model.ts b/catalog-ui/src/app/view-models/plugins/plugins-tab-view-model.ts index d9dc40bdaf..5e2a59925c 100644 --- a/catalog-ui/src/app/view-models/plugins/plugins-tab-view-model.ts +++ b/catalog-ui/src/app/view-models/plugins/plugins-tab-view-model.ts @@ -36,7 +36,8 @@ export class PluginsTabViewModel { this.$scope.queryParams = { userId: this.$scope.user.userId, userRole: this.$scope.user.role, - displayType: "tab" + displayType: "tab", + parentUrl: window.location.origin }; } } diff --git a/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view-model.ts index 7a399d860a..959aead3ae 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view-model.ts @@ -38,7 +38,9 @@ export class PluginsContextViewModel { contextType: this.$scope.component.getComponentSubType(), uuid: this.$scope.component.uuid, lifecycleState: this.$scope.component.lifecycleState, - isOwner: this.$scope.component.lastUpdaterUserId === this.$scope.user.userId + isOwner: this.$scope.component.lastUpdaterUserId === this.$scope.user.userId, + version: this.$scope.component.version , + parentUrl: window.location.origin }; } diff --git a/sdc-os-chef/environments/Template.json b/sdc-os-chef/environments/Template.json index 5d11261f05..af32e6f199 100644 --- a/sdc-os-chef/environments/Template.json +++ b/sdc-os-chef/environments/Template.json @@ -40,18 +40,16 @@ "ES": "yyy", "KB": "yyy" }, - "Designers": { + "Plugins": { "DCAE": { - "dcae_protocol": "yyy", - "dcae_host": "yyy", - "dcae_port": "yyy" + "dcae_discovery_url": "yyy", + "dcae_source_url": "yyy" }, "WORKFLOW": { - "workflow_protocol": "yyy", - "workflow_host": "yyy", - "workflow_port": "yyy" + "workflow_discovery_url": "yyy", + "workflow_source_url": "yyy" } - } + }, }, "override_attributes": { "FE": { -- 2.16.6