Implemented Instance View of Topo in GUI2

Change-Id: If603481e729ebc19a6f91db2739f1b422cc762d0
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
index 0db2c82..d74991c 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
@@ -15,7 +15,7 @@
 -->
 <onos-flash id="topoMsgFlash" message="{{ flashMsg }}" (closed)="flashMsg = ''"></onos-flash>
 
-<onos-instance #instance></onos-instance>
+<onos-instance #instance [divTopPx]="80" (mastershipEvent)="force.onosInstMastership = $event"></onos-instance>
 <onos-summary #summary></onos-summary>
 <onos-toolbar #toolbar></onos-toolbar>
 <onos-details #details></onos-details>
@@ -24,8 +24,8 @@
     <svg viewBox="0 0 1000 1000" id="topo2">
         <svg:g onos-nodeviceconnected />
         <svg:g id="topo-zoomlayer">
-            <svg:g onos-backgroundsvg/>
-            <svg:g onos-forcesvg/>
+            <svg:g #background onos-backgroundsvg/>
+            <svg:g #force onos-forcesvg/>
         </svg:g>
     </svg>
 </div>
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
index 5933d37..d98a55c 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
@@ -20,10 +20,14 @@
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 
 import { TopologyComponent } from './topology.component';
-import { InstanceComponent } from '../panel/instance/instance.component';
+import {
+    Instance,
+    InstanceComponent
+} from '../panel/instance/instance.component';
 import { SummaryComponent } from '../panel/summary/summary.component';
 import { ToolbarComponent } from '../panel/toolbar/toolbar.component';
 import { DetailsComponent } from '../panel/details/details.component';
+import { TopologyService } from '../topology.service';
 
 import {
     FlashComponent,
@@ -41,6 +45,32 @@
 
 class MockHttpClient {}
 
+class MockTopologyService {
+    init(instance: InstanceComponent) {
+        instance.onosInstances = [
+            <Instance>{
+                'id': 'inst1',
+                'ip': '127.0.0.1',
+                'reachable': true,
+                'online': true,
+                'ready': true,
+                'switches': 4,
+                'uiAttached': true
+            },
+            <Instance>{
+                'id': 'inst1',
+                'ip': '127.0.0.2',
+                'reachable': true,
+                'online': true,
+                'ready': true,
+                'switches': 3,
+                'uiAttached': false
+            }
+        ];
+    }
+    destroy() {}
+}
+
 /**
  * ONOS GUI -- Topology View -- Unit Tests
  */
@@ -84,6 +114,7 @@
                 { provide: LogService, useValue: logSpy },
                 { provide: 'Window', useValue: windowMock },
                 { provide: HttpClient, useClass: MockHttpClient },
+                { provide: TopologyService, useClass: MockTopologyService }
             ]
         }).compileComponents();
         logServiceSpy = TestBed.get(LogService);
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
index bf46637..728347d 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import { Component, OnInit, ViewChild } from '@angular/core';
+import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
 import * as d3 from 'd3';
 import {
     FnService,
@@ -21,9 +21,12 @@
     LogService, PrefsService,
     SvgUtilService, WebSocketService, Zoomer, ZoomOpts, ZoomService
 } from 'gui2-fw-lib';
-import {InstanceComponent} from '../panel/instance/instance.component';
-import {SummaryComponent} from '../panel/summary/summary.component';
-import {DetailsComponent} from '../panel/details/details.component';
+import { InstanceComponent } from '../panel/instance/instance.component';
+import { SummaryComponent } from '../panel/summary/summary.component';
+import { DetailsComponent } from '../panel/details/details.component';
+import { BackgroundSvgComponent } from '../layer/backgroundsvg/backgroundsvg.component';
+import { ForceSvgComponent } from '../layer/forcesvg/forcesvg.component';
+import { TopologyService } from '../topology.service';
 
 /**
  * ONOS GUI Topology View
@@ -54,10 +57,13 @@
   templateUrl: './topology.component.html',
   styleUrls: ['./topology.component.css']
 })
-export class TopologyComponent implements OnInit {
+export class TopologyComponent implements OnInit, OnDestroy {
+    // These are references to the components inserted in the template
     @ViewChild(InstanceComponent) instance: InstanceComponent;
     @ViewChild(SummaryComponent) summary: SummaryComponent;
     @ViewChild(DetailsComponent) details: DetailsComponent;
+    @ViewChild(BackgroundSvgComponent) background: BackgroundSvgComponent;
+    @ViewChild(ForceSvgComponent) force: ForceSvgComponent;
 
     flashMsg: string = '';
     prefsState = {};
@@ -73,7 +79,8 @@
         protected sus: SvgUtilService,
         protected ps: PrefsService,
         protected wss: WebSocketService,
-        protected zs: ZoomService
+        protected zs: ZoomService,
+        protected ts: TopologyService,
     ) {
 
         this.log.debug('Topology component constructed');
@@ -90,9 +97,19 @@
             zoomCallback: (() => { return; })
         });
         this.zoomEventListeners = [];
+        // The components from the template are handed over to TopologyService here
+        // so that WebSocket responses can be passed back in to them
+        // The handling of the WebSocket call is delegated out to the Topology
+        // Service just to compartmentalize things a bit
+        this.ts.init(this.instance, this.background, this.force);
         this.log.debug('Topology component initialized');
     }
 
+    ngOnDestroy() {
+        this.ts.destroy();
+        this.log.debug('Topology component destroyed');
+    }
+
     actionMap() {
         return {
             L: [() => {this.cycleDeviceLabels(); }, 'Cycle device labels'],