Plugin pubsub implementation 85/31585/5
authorIdan Amit <ia096e@intl.att.com>
Tue, 13 Feb 2018 08:38:16 +0000 (10:38 +0200)
committerIdan Amit <ia096e@intl.att.com>
Tue, 13 Feb 2018 14:43:30 +0000 (16:43 +0200)
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 <ia096e@intl.att.com>
catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/PluginStatusBL.java
catalog-ui/src/app/models/base-pubsub.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/app.module.ts
catalog-ui/src/app/ng2/services/event-bus.service.ts [new file with mode: 0644]
catalog-ui/src/app/view-models/plugins/plugins-tab-view-model.ts
catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view-model.ts
sdc-os-chef/environments/Template.json

index a369d66..563dc22 100644 (file)
@@ -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 (file)
index 0000000..ca500ca
--- /dev/null
@@ -0,0 +1,95 @@
+declare const window: Window;
+
+export class BasePubSub {
+
+    subscribers: Map<string, ISubscriber>;
+    eventsCallbacks: Array<Function>;
+    clientId: string;
+
+    constructor(pluginId: string) {
+        this.subscribers = new Map<string, ISubscriber>();
+        this.eventsCallbacks = new Array<Function>();
+        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;
+}
index a5a2fed..0346b10 100644 (file)
@@ -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 (file)
index 0000000..7730a77
--- /dev/null
@@ -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);
+        }
+    }
+}
index d9dc40b..5e2a599 100644 (file)
@@ -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
         };
     }
 }
index 7a399d8..959aead 100644 (file)
@@ -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
         };
 
     }
index 5d11261..af32e6f 100644 (file)
             "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": {