publish event to all models involved

Change-Id: I869692fbababaa881ce2a0fc8f2ef6add5c7c243
diff --git a/src/app/datasources/websocket/global.ts b/src/app/datasources/websocket/global.ts
index a5852c8..a820269 100644
--- a/src/app/datasources/websocket/global.ts
+++ b/src/app/datasources/websocket/global.ts
@@ -1,4 +1,5 @@
 import * as io from 'socket.io-client';
+import * as _ from 'lodash';
 import {Subject, Observable} from 'rxjs/Rx';
 import {IXosAppConfig} from '../../../index';
 
@@ -17,16 +18,31 @@
 
 export class WebSocketEvent {
 
-  static $inject = ['AppConfig'];
+  static $inject = [
+    'AppConfig',
+    '$log'
+  ];
 
   private _events: Subject<IWSEvent> = new Subject<IWSEvent>();
     private socket;
     constructor(
-      private AppConfig: IXosAppConfig
+      private AppConfig: IXosAppConfig,
+      private $log: ng.ILogService
     ) {
       this.socket = io(this.AppConfig.websocketClient);
       this.socket.on('event', (data: IWSEvent): void => {
+          this.$log.debug(`[WebSocket] Received Event for: ${data.model} [${data.msg.pk}]`);
           this._events.next(data);
+
+          // NOTE update observers of parent classes
+          if (data.msg.object.class_names && angular.isString(data.msg.object.class_names)) {
+            const models = data.msg.object.class_names.split(',');
+            _.forEach(models, (m: string) => {
+              data.model = m;
+              this._events.next(data);
+            });
+          }
+
         });
     }
     list() {
diff --git a/src/app/service-graph/components/coarse/coarse.component.ts b/src/app/service-graph/components/coarse/coarse.component.ts
index 4e681d7..fb04e2d 100644
--- a/src/app/service-graph/components/coarse/coarse.component.ts
+++ b/src/app/service-graph/components/coarse/coarse.component.ts
@@ -43,12 +43,12 @@
     this.CoarseGraphSubscription = this.XosServiceGraphStore.getCoarse()
       .subscribe(
         (res: IXosServiceGraph) => {
+          this.$log.debug(`[XosCoarseTenancyGraph] Coarse Event and render`, res);
 
           // id there are no data, do nothing
           if (!res.nodes || res.nodes.length === 0 || !res.links || res.links.length === 0) {
             return;
           }
-          this.$log.debug(`[XosCoarseTenancyGraph] Coarse Event and render`, res);
           this.graph = res;
           this.renderGraph();
         },
@@ -138,6 +138,9 @@
   }
 
   private addNodeLinksToForceLayout(data: IXosServiceGraph) {
+    if (!data.nodes || !data.links) {
+      return;
+    }
     this.forceLayout
       .nodes(data.nodes)
       .links(data.links)
diff --git a/src/app/service-graph/components/fine-grained/fine-grained.component.ts b/src/app/service-graph/components/fine-grained/fine-grained.component.ts
index c7efd1c..5647c75 100644
--- a/src/app/service-graph/components/fine-grained/fine-grained.component.ts
+++ b/src/app/service-graph/components/fine-grained/fine-grained.component.ts
@@ -53,12 +53,12 @@
     this.GraphSubscription = this.XosServiceGraphStore.get()
       .subscribe(
         (graph) => {
+          this.$log.debug(`[XosFineGrainedTenancyGraphCtrl] Fine-Grained Event and render`, graph);
 
           if (!graph.nodes || graph.nodes.length === 0 || !graph.links || graph.links.length === 0) {
             return;
           }
 
-          this.$log.debug(`[XosFineGrainedTenancyGraphCtrl] Coarse Event and render`, graph);
           this.graph = graph;
           this.renderGraph();
         },
diff --git a/src/app/service-graph/services/graph.store.ts b/src/app/service-graph/services/graph.store.ts
index 54bc083..9ab1a5d 100644
--- a/src/app/service-graph/services/graph.store.ts
+++ b/src/app/service-graph/services/graph.store.ts
@@ -106,6 +106,7 @@
     this.graphData
       .subscribe(
         (res: IXosFineGrainedGraphData) => {
+          this.$log.debug(`[XosServiceGraphStore] New graph data received`, res);
           this.graphDataToCoarseGraph(res);
           this.graphDataToFineGrainedGraph(res);
         },