Addded alarm highlight on Topo View and link to Alarm View

Change-Id: I0de7a24e12fd7e299fc7e31747cb27cd4831828b
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/svg/glyphdata.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/svg/glyphdata.service.ts
index be2ddb4..8cb2551 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/svg/glyphdata.service.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/svg/glyphdata.service.ts
@@ -1,14 +1,14 @@
 /*
  *  Copyright 2018-present Open Networking Foundation
  *
- *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  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,
+ *  distributed under the License is distributed on an 'AS IS' BASIS,
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
@@ -536,6 +536,55 @@
 
     ['xClose', 'M20,8l35,35,35-35,12,12-35,35,35,35-12,12-35-35-35,35' +
     '-12-12,35-35-35-35,12-12Z'],
+
+    ['clock', 'M92.9,61.3a39,39,0,1,1-39-39,39,39,0,0,1,39,39h0Z' +
+    'M44,19.3c-4.4-7.4-14.8-9.3-23.2-4.2S9.1,30.2,13.5,37.6m80.8,0' +
+    'c4.4-7.4,1.2-17.5-7.3-22.5s-18.8-3.2-23.3,4.2m-8.4,1.8V16.5h4.4' +
+    'V11.9H48.2v4.6h4.6v4.6M51.6,56.4H51.5' +
+    'a5.4,5.4,0,0,0,2.4,10.3,4.7,4.7,0,0,0,4.9-3.1H74.5' +
+    'a2.2,2.2,0,0,0,2.4-2.2,2.4,2.4,0,0,0-2.4-2.3H58.8' +
+    'a5.3,5.3,0,0,0-2.5-2.6H56.2V32.9' +
+    'a2.3,2.3,0,0,0-.6-1.7,2.2,2.2,0,0,0-1.6-.7,2.4,2.4,0,0,0-2.4,2.4' +
+    'h0V56.4M82.2,91.1l-7.1,5.3-0.2.2-1.2,2.1a0.6,0.6,0,0,0,.2.8' +
+    'h0.2c2.6,0.4,10.7.9,10.3-1.2m-60.8,0c-0.4,2.1,7.7,1.6,10.3,1.2' +
+    'h0.2a0.6,0.6,0,0,0,.2-0.8l-1.2-2.1-0.2-.2-7.1-5.3'],
+
+// overlapping alarm clocks glyph (view box 110x110)
+    ['clocks', 'M65.7,26.6A34.7,34.7,0,0,0,31,61.5c0,19,16,35.2,35.5,34.8' +
+    'a35.1,35.1,0,0,0,34-35.1A34.7,34.7,0,0,0,65.7,26.6Z' +
+    'm8.6-2.7,27.4,16.4a31.3,31.3,0,0,0,1.2-3.1c1.3-5,0-9.4-3.2-13.2' +
+    'a16.9,16.9,0,0,0-16-6.2A12.8,12.8,0,0,0,74.3,23.9Z' +
+    'M57,23.9L56.4,23a12.9,12.9,0,0,0-10.7-5.5,16.9,16.9,0,0,0-15.1,8,' +
+    '14.1,14.1,0,0,0-2.3,11.2,10.4,10.4,0,0,0,1.4,3.5Z' +
+    'M26.9,31.6A33.7,33.7,0,0,0,9.7,59.3C9.2,72.8,14.9,83.1,26,90.7l1-1.9' +
+    'a0.6,0.6,0,0,0-.2-1A34.2,34.2,0,0,1,15.5,50.4' +
+    'a33.8,33.8,0,0,1,10.8-16,1.2,1.2,0,0,0,.5-0.6' +
+    'C26.9,33.1,26.9,32.4,26.9,31.6Z' +
+    'm1,8.1C14.6,55.9,19.2,81,37.6,91.1l1-2.3-2.8-2.4' +
+    'C26.4,77.6,22.9,66.7,25.1,54' +
+    'a31.6,31.6,0,0,1,4.2-10.8,0.8,0.8,0,0,0,.1-0.6Z' +
+    'M12,38.4a11.2,11.2,0,0,1-1.4-5.8A13.7,13.7,0,0,1,14.3,24' +
+    'a17.3,17.3,0,0,1,10.5-5.7h0.4C19,18,13.7,20,9.9,25.2' +
+    'a14.5,14.5,0,0,0-3,11,11.2,11.2,0,0,0,1.6,4.3Z' +
+    'm5.5-2.7L21,33' +
+    'a1,1,0,0,0,.3-0.7,14,14,0,0,1,3.9-8.6,17.3,17.3,0,0,1,10.2-5.4' +
+    'l0.6-.2C24.4,17.3,16.4,27,17.4,35.7Z' +
+    'M70.9,17.2H60.7v4.1h4v4.2H67V21.3h3.9V17.2Z' +
+    'M90.9,87.9l-0.5.3L86,91.5a7.9,7.9,0,0,0-2.6,3.1' +
+    'c-0.3.6-.2,0.8,0.5,0.9a27.9,27.9,0,0,0,6.8.2l1.6-.4' +
+    'a0.8,0.8,0,0,0,.6-1.2l-0.4-1.4Z' +
+    'm-50.2,0-1.8,6c-0.3,1.1-.1,1.4.9,1.7h0.7a26.3,26.3,0,0,0,7.2-.1' +
+    'c0.8-.1.9-0.4,0.5-1.1a8.2,8.2,0,0,0-2.7-3.1Z' +
+    'm-10.8-.4-0.2.6L28,93.5a0.9,0.9,0,0,0,.7,1.3,7.7,7.7,0,0,0,2.2.4' +
+    'l5.9-.2c0.5,0,.7-0.3.5-0.8a7.6,7.6,0,0,0-2.2-2.9Z' +
+    'm-11.3,0-0.2.7-1.6,5.4c-0.2.8-.1,1.2,0.7,1.4a8,8,0,0,0,2.2.4l6-.2' +
+    'c0.4,0,.7-0.3.5-0.6a7.1,7.1,0,0,0-1.9-2.7l-2.8-2.1Z' +
+    'M65.7,26.6m-2,30.3a4.4,4.4,0,0,0-2.2,2,4.8,4.8,0,0,0,4,7.2,' +
+    '4.1,4.1,0,0,0,4.3-2.3,0.8,0.8,0,0,1,.8-0.5H84.1' +
+    'a1.9,1.9,0,0,0,2-1.7,2.1,2.1,0,0,0-1.7-2.2H70.8' +
+    'a1,1,0,0,1-1-.5,6.4,6.4,0,0,0-1.5-1.6,1.1,1.1,0,0,1-.5-1' +
+    'q0-10.1,0-20.3a1.9,1.9,0,0,0-2.2-2.1,2.1,2.1,0,0,0-1.8,2.2' +
+    'q0,6.1,0,12.2C63.7,51.2,63.7,54,63.7,56.9Z'],
 ]);
 
 export const badgeDataSet = new Map<string, string>([
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/svg/icon.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/svg/icon.service.ts
index e556782..da86354 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/svg/icon.service.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/svg/icon.service.ts
@@ -151,6 +151,8 @@
     ['nav_intents', 'relatedIntents'],
     ['nav_tunnels', 'ports'], // TODO: use tunnel glyph, when available
     ['nav_yang', 'yang'],
+    ['clock', 'clock'],
+    ['clocks', 'clocks'],
 ]);
 
 /**
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/gui2-topo-lib.module.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/gui2-topo-lib.module.ts
index dcb6321..a19b73d 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/gui2-topo-lib.module.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/gui2-topo-lib.module.ts
@@ -38,6 +38,7 @@
 import { GridsvgComponent } from './layer/gridsvg/gridsvg.component';
 import {TrafficService} from './traffic.service';
 import {LayoutService} from './layout.service';
+import { BadgeSvgComponent } from './layer/forcesvg/visuals/badgesvg/badgesvg.component';
 
 /**
  * ONOS GUI -- Topology View Module
@@ -73,6 +74,7 @@
         TopologyComponent,
         ZoomableDirective,
         DraggableDirective,
+        BadgeSvgComponent,
     ],
     providers: [
         TopologyService,
@@ -97,6 +99,7 @@
         TopologyComponent,
         ZoomableDirective,
         DraggableDirective,
+        BadgeSvgComponent
     ]
 })
 export class Gui2TopoLibModule { }
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/backgroundsvg/backgroundsvg.component.spec.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/backgroundsvg/backgroundsvg.component.spec.ts
index cefeaea..cac0b2d 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/backgroundsvg/backgroundsvg.component.spec.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/backgroundsvg/backgroundsvg.component.spec.ts
@@ -28,6 +28,7 @@
 import {SubRegionNodeSvgComponent} from '../forcesvg/visuals/subregionnodesvg/subregionnodesvg.component';
 import {LinkSvgComponent} from '../forcesvg/visuals/linksvg/linksvg.component';
 import {HostNodeSvgComponent} from '../forcesvg/visuals/hostnodesvg/hostnodesvg.component';
+import {BadgeSvgComponent} from '../forcesvg/visuals/badgesvg/badgesvg.component';
 
 
 describe('BackgroundSvgComponent', () => {
@@ -60,7 +61,8 @@
                 HostNodeSvgComponent,
                 SubRegionNodeSvgComponent,
                 LinkSvgComponent,
-                DraggableDirective
+                DraggableDirective,
+                BadgeSvgComponent
             ],
             providers: [
                 { provide: LogService, useValue: logSpy },
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/forcesvg.component.spec.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/forcesvg.component.spec.ts
index d10df1c9..56634ee 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/forcesvg.component.spec.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/forcesvg.component.spec.ts
@@ -33,6 +33,7 @@
 import {Device, Host, Link, LinkType, Region} from './models';
 import {ChangeDetectorRef, SimpleChange} from '@angular/core';
 import {TopologyService} from '../../topology.service';
+import {BadgeSvgComponent} from './visuals/badgesvg/badgesvg.component';
 
 class MockActivatedRoute extends ActivatedRoute {
     constructor(params: Params) {
@@ -137,7 +138,8 @@
                 HostNodeSvgComponent,
                 SubRegionNodeSvgComponent,
                 LinkSvgComponent,
-                DraggableDirective
+                DraggableDirective,
+                BadgeSvgComponent
             ],
             providers: [
                 { provide: LogService, useValue: logSpy },
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/forcesvg.component.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/forcesvg.component.ts
index eebe851..534802c 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/forcesvg.component.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/forcesvg.component.ts
@@ -20,7 +20,7 @@
     EventEmitter,
     HostListener,
     Input,
-    OnChanges,
+    OnChanges, OnDestroy,
     OnInit,
     Output,
     QueryList,
@@ -28,12 +28,13 @@
     SimpleChanges,
     ViewChildren
 } from '@angular/core';
-import {LocMeta, LogService, MetaUi, SvgUtilService, WebSocketService, ZoomUtils} from 'gui2-fw-lib';
+import {LocMeta, LogService, MetaUi, WebSocketService, ZoomUtils} from 'gui2-fw-lib';
 import {
-    Device,
+    Badge,
+    Device, DeviceHighlight,
     DeviceProps,
     ForceDirectedGraph,
-    Host,
+    Host, HostHighlight,
     HostLabelToggle,
     LabelToggle,
     LayerType,
@@ -83,10 +84,11 @@
     styleUrls: ['./forcesvg.component.css'],
     changeDetection: ChangeDetectionStrategy.OnPush,
 })
-export class ForceSvgComponent implements OnInit, OnChanges {
+export class ForceSvgComponent implements OnInit, OnDestroy, OnChanges {
     @Input() deviceLabelToggle: LabelToggle.Enum = LabelToggle.Enum.NONE;
     @Input() hostLabelToggle: HostLabelToggle.Enum = HostLabelToggle.Enum.NONE;
     @Input() showHosts: boolean = false;
+    @Input() showAlarms: boolean = false;
     @Input() highlightPorts: boolean = true;
     @Input() onosInstMastership: string = '';
     @Input() visibleLayer: LayerType = LayerType.LAYER_DEFAULT;
@@ -97,6 +99,7 @@
     @Output() selectedNodeEvent = new EventEmitter<UiElement[]>();
     public graph: ForceDirectedGraph;
     private selectedNodes: UiElement[] = [];
+    viewInitialized: boolean = false;
 
     // References to the children of this component - these are created in the
     // template view with the *ngFor and we get them by a query here
@@ -255,7 +258,30 @@
             }
             this.log.debug('ForceSvgComponent input changed',
                 this.graph.nodes.length, 'nodes,', this.graph.links.length, 'links');
+            if (!this.viewInitialized) {
+                this.viewInitialized = true;
+                if (this.showAlarms) {
+                    this.wss.sendEvent('alarmTopovDisplayStart', {});
+                }
+            }
         }
+
+        if (changes['showAlarms'] && this.viewInitialized) {
+            if (this.showAlarms) {
+                this.wss.sendEvent('alarmTopovDisplayStart', {});
+            } else {
+                this.wss.sendEvent('alarmTopovDisplayStop', {});
+                this.cancelAllDeviceHighlightsNow();
+            }
+        }
+    }
+
+    ngOnDestroy(): void {
+        if (this.showAlarms) {
+            this.wss.sendEvent('alarmTopovDisplayStop', {});
+            this.cancelAllDeviceHighlightsNow();
+        }
+        this.viewInitialized = false;
     }
 
     /**
@@ -537,32 +563,30 @@
      * @param hosts - an array of host highlights
      * @param links - an array of link highlights
      */
-    handleHighlights(devices: Device[], hosts: Host[], links: LinkHighlight[], fadeMs: number = 0): void {
+    handleHighlights(devices: DeviceHighlight[], hosts: HostHighlight[], links: LinkHighlight[], fadeMs: number = 0): void {
 
         if (devices.length > 0) {
             this.log.debug(devices.length, 'Devices highlighted');
-            devices.forEach((dh) => {
-                const deviceComponent: DeviceNodeSvgComponent = this.devices.find((d) => d.device.id === dh.id );
-                if (deviceComponent) {
-                    deviceComponent.ngOnChanges(
-                        {'deviceHighlight': new SimpleChange(<Device>{}, dh, true)}
-                    );
-                    this.log.debug('Highlighting device', deviceComponent.device.id);
-                } else {
-                    this.log.warn('Device component not found', dh.id);
-                }
+            devices.forEach((dh: DeviceHighlight) => {
+                this.devices.forEach((d: DeviceNodeSvgComponent) => {
+                    if (d.device.id === dh.id) {
+                        d.badge = dh.badge;
+                        this.ref.markForCheck(); // Forces ngOnChange in the DeviceSvgComponent
+                        this.log.debug('Highlighting device', dh.id);
+                    }
+                });
             });
         }
         if (hosts.length > 0) {
             this.log.debug(hosts.length, 'Hosts highlighted');
-            hosts.forEach((hh) => {
-                const hostComponent: HostNodeSvgComponent = this.hosts.find((h) => h.host.id === hh.id );
-                if (hostComponent) {
-                    hostComponent.ngOnChanges(
-                        {'hostHighlight': new SimpleChange(<Host>{}, hh, true)}
-                    );
-                    this.log.debug('Highlighting host', hostComponent.host.id);
-                }
+            hosts.forEach((hh: HostHighlight) => {
+                this.hosts.forEach((h) => {
+                    if (h.host.id === hh.id) {
+                        h.badge = hh.badge;
+                        this.ref.markForCheck(); // Forces ngOnChange in the HostSvgComponent
+                        this.log.debug('Highlighting host', hh.id);
+                    }
+                });
             });
         }
         if (links.length > 0) {
@@ -575,19 +599,31 @@
                 this.links.forEach((l) => {
                     if (l.link.id === Link.linkIdFromShowHighlights(lh.id)) {
                         l.linkHighlight = lh;
-                        l.ngOnChanges(
-                            <SimpleChanges>{'linkHighlight': new SimpleChange(<LinkHighlight>{}, lh, true)}
-                        );
+                        this.ref.markForCheck(); // Forces ngOnChange in the LinkSvgComponent
                     }
                 });
             });
         }
     }
 
+    cancelAllHostHighlightsNow() {
+        this.hosts.forEach((host: HostNodeSvgComponent) => {
+            host.badge = undefined;
+            this.ref.markForCheck(); // Forces ngOnChange in the HostSvgComponent
+        });
+    }
+
+    cancelAllDeviceHighlightsNow() {
+        this.devices.forEach((device: DeviceNodeSvgComponent) => {
+            device.badge = undefined;
+            this.ref.markForCheck(); // Forces ngOnChange in the DeviceSvgComponent
+        });
+    }
+
     cancelAllLinkHighlightsNow() {
         this.links.forEach((link: LinkSvgComponent) => {
             link.linkHighlight = <LinkHighlight>{};
-            this.ngOnChanges(<SimpleChanges>{'linkHighlight': new SimpleChange(<LinkHighlight>{}, <LinkHighlight>{}, false)});
+            this.ref.markForCheck(); // Forces ngOnChange in the LinkSvgComponent
         });
     }
 
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/models/node.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/models/node.ts
index ccd9250..6a2d77f 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/models/node.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/models/node.ts
@@ -202,6 +202,13 @@
     }
 }
 
+export interface Badge {
+    status: string;
+    isGlyph: boolean;
+    txt: string;
+    msg: string;
+}
+
 /**
  * model of the topo2CurrentRegion device from Region below
  */
@@ -219,6 +226,16 @@
     }
 }
 
+export interface DeviceHighlight {
+    id: string;
+    badge: Badge;
+}
+
+export interface HostHighlight {
+    id: string;
+    badge: Badge;
+}
+
 /**
  * Model of the ONOS Host element in the topology
  */
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.css b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.css
new file mode 100644
index 0000000..373b57b
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.css
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+.status.e {
+    fill: #c72930;
+}
+
+.text.e {
+    fill: white;
+    font-weight: bold;
+}
+
+.status.w {
+    fill: #db7773;
+}
+
+.text.w {
+    fill: white;
+    font-weight: bold;
+}
+
+.status.i {
+    fill: #007dc4;
+}
+
+.text.i {
+    fill: white;
+}
+
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.html b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.html
new file mode 100644
index 0000000..e8dfcb9
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.html
@@ -0,0 +1,19 @@
+<!--
+~ Copyright 2019-present Open Networking Foundation
+~
+~ 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.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<svg:g xmlns:svg="http://www.w3.org/2000/svg" [title]="badge.msg">
+    <svg:circle r="12" [ngClass]="['status', badge.status ? badge.status : '']" cx="-18" cy="-18"></svg:circle>
+    <svg:text x="-18" y="-11" text-anchor="middle" [ngClass]="['text', badge.status ? badge.status : '']">{{ badge.txt }}</svg:text>
+</svg:g>
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.spec.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.spec.ts
new file mode 100644
index 0000000..2b457b4
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.spec.ts
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {BadgeSvgComponent} from './badgesvg.component';
+
+describe('BadgeSvgComponent', () => {
+    let component: BadgeSvgComponent;
+    let fixture: ComponentFixture<BadgeSvgComponent>;
+
+    beforeEach(async(() => {
+        TestBed.configureTestingModule({
+            declarations: [BadgeSvgComponent]
+        })
+        .compileComponents();
+    }));
+
+    beforeEach(() => {
+        fixture = TestBed.createComponent(BadgeSvgComponent);
+        component = fixture.componentInstance;
+        fixture.detectChanges();
+    });
+
+    it('should create', () => {
+        expect(component).toBeTruthy();
+    });
+});
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.ts
new file mode 100644
index 0000000..f0bbc7a
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/badgesvg/badgesvg.component.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Component, Input, OnInit} from '@angular/core';
+import {Badge} from '../../models';
+
+@Component({
+    selector: '[onos-badgesvg]',
+    templateUrl: './badgesvg.component.html',
+    styleUrls: ['./badgesvg.component.css']
+})
+export class BadgeSvgComponent implements OnInit {
+    @Input() badge: Badge = <Badge>{};
+
+    constructor() {
+    }
+
+    ngOnInit() {
+    }
+
+}
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.css b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.css
index 204b85c..e7ce209 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.css
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.css
@@ -48,4 +48,10 @@
 g.node.hovered .node-container {
     stroke-width: 2.0;
     stroke: #454545;
-}
\ No newline at end of file
+}
+
+path.bracket {
+    stroke: white;
+    stroke-width: 1;
+    fill: none
+}
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.html b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.html
index 49f9416..c4f5621 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.html
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.html
@@ -69,10 +69,14 @@
     -->
     <svg:rect x="-16" y="-16" width="32" height="32" [ngStyle]="{'fill': panelColor}">
     </svg:rect>
+    <!-- Create an L shaped bracket on bottom left of icon if it has either grid or geo location-->
     <svg:path *ngIf="device.location && device.location.locType != 'none'"
-              d="M-15 12 v3 h3" style="stroke: white; stroke-width: 1; fill: none"></svg:path>
+              d="M-15 12 v3 h3" class="bracket">
+    </svg:path>
+    <!-- Create an L shaped bracket on top right of icon if it has been pinned or has fixed location-->
     <svg:path *ngIf="device.fx != null"
-              d="M15 -12 v-3 h-3" style="stroke: white; stroke-width: 1; fill: none"></svg:path>
+              d="M15 -12 v-3 h-3" class="bracket">
+    </svg:path>
     <!-- Template explanation: Creates an SVG Text element and in
         line 1) make it left aligned and slightly down and to the right of the last rect
         line 2) set its text length to be the calculated value - see that function
@@ -92,4 +96,5 @@
     </svg:text>
     <svg:use [attr.xlink:href]="'#' + deviceIcon()" width="36" height="36" x="-18" y="-18">
     </svg:use>
+    <svg:g *ngIf="badge" onos-badgesvg [badge]="badge"></svg:g>
 </svg:g>
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.spec.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.spec.ts
index 994967d..067cce6 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.spec.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.spec.ts
@@ -23,6 +23,7 @@
 import {Device} from '../../models';
 import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
 import {TopologyService} from '../../../../topology.service';
+import {BadgeSvgComponent} from '../badgesvg/badgesvg.component';
 
 class MockActivatedRoute extends ActivatedRoute {
     constructor(params: Params) {
@@ -100,7 +101,7 @@
 
         TestBed.configureTestingModule({
             imports: [ BrowserAnimationsModule ],
-            declarations: [ DeviceNodeSvgComponent ],
+            declarations: [ DeviceNodeSvgComponent, BadgeSvgComponent ],
             providers: [
                 { provide: LogService, useValue: logSpy },
                 { provide: ActivatedRoute, useValue: ar },
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.ts
index 9c246d9..4f06137 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.ts
@@ -22,11 +22,14 @@
     OnChanges, OnInit, Output,
     SimpleChanges,
 } from '@angular/core';
-import {Device, LabelToggle, UiElement} from '../../models';
-import {IconService, LocMeta, LogService, MetaUi, SvgUtilService, ZoomUtils} from 'gui2-fw-lib';
+import {
+    Badge,
+    Device,
+    LabelToggle,
+} from '../../models';
+import {IconService, LogService, SvgUtilService} from 'gui2-fw-lib';
 import {NodeVisual, SelectedEvent} from '../nodevisual';
 import {animate, state, style, transition, trigger} from '@angular/animations';
-import {LocationType} from '../../../backgroundsvg/backgroundsvg.component';
 import {TopologyService} from '../../../../topology.service';
 
 /**
@@ -71,6 +74,7 @@
     @Input() labelToggle: LabelToggle.Enum = LabelToggle.Enum.NONE;
     @Input() colorMuted: boolean = false;
     @Input() colorTheme: string = 'light';
+    @Input() badge: Badge;
     @Output() selectedEvent = new EventEmitter<SelectedEvent>();
     textWidth: number = 36;
     panelColor: string = '#9ebedf';
@@ -110,7 +114,10 @@
             this.colorMuted = changes['colorMuted'].currentValue;
             this.panelColor = this.panelColour();
         }
-        this.ref.markForCheck();
+
+        if (changes['badge']) {
+            this.badge = changes['badge'].currentValue;
+        }
     }
 
     /**
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html
index 0ce4a4a..bdaf54a 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html
@@ -67,4 +67,5 @@
         *ngIf="labelToggle != 0"
         dy="30" text-anchor="middle"
         >{{hostName()}}</svg:text>
+    <svg:g *ngIf="badge" onos-badgesvg [badge]="badge"></svg:g>
 </svg:g>
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.spec.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.spec.ts
index e3efb3f..d70387e 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.spec.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.spec.ts
@@ -22,6 +22,7 @@
 import {Host} from '../../models';
 import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
 import {ChangeDetectorRef} from '@angular/core';
+import {BadgeSvgComponent} from '../badgesvg/badgesvg.component';
 
 class MockActivatedRoute extends ActivatedRoute {
   constructor(params: Params) {
@@ -45,7 +46,7 @@
 
         TestBed.configureTestingModule({
             imports: [ BrowserAnimationsModule ],
-            declarations: [ HostNodeSvgComponent ],
+            declarations: [ HostNodeSvgComponent, BadgeSvgComponent ],
             providers: [
               { provide: LogService, useValue: logSpy },
               { provide: ActivatedRoute, useValue: ar },
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts
index 806f9b2..b4c4a05 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts
@@ -21,7 +21,7 @@
     Output,
     SimpleChanges
 } from '@angular/core';
-import {Host, HostLabelToggle, Node} from '../../models';
+import {Badge, Host, HostLabelToggle, Node} from '../../models';
 import {LogService} from 'gui2-fw-lib';
 import {NodeVisual, SelectedEvent} from '../nodevisual';
 
@@ -40,6 +40,7 @@
     @Input() host: Host;
     @Input() scale: number = 1.0;
     @Input() labelToggle: HostLabelToggle.Enum = HostLabelToggle.Enum.IP;
+    @Input() badge: Badge;
     @Output() selectedEvent = new EventEmitter<SelectedEvent>();
 
     constructor(
@@ -49,9 +50,15 @@
     }
 
     ngOnChanges(changes: SimpleChanges) {
-        if (!this.host.x) {
-            this.host.x = 0;
-            this.host.y = 0;
+        if (changes['host']) {
+            if (!this.host.x) {
+                this.host.x = 0;
+                this.host.y = 0;
+            }
+        }
+
+        if (changes['badge']) {
+            this.badge = changes['badge'].currentValue;
         }
     }
 
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/details/details.component.html b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/details/details.component.html
index 845611f..236cefe 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/details/details.component.html
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/details/details.component.html
@@ -61,6 +61,14 @@
                         classes="button icon selected">
                 </onos-icon>
             </div>
+            <div *ngIf="showDetails?.buttons?.includes('showDeviceView')" class="actionBtn">
+                <onos-icon id="topo2-p-detail-core-alarms"
+                           (click)="navto('alarmTable')"
+                           [iconSize]="25"
+                           [iconId]="'clock'"
+                           classes="button icon selected">
+                </onos-icon>
+            </div>
         </div>
     </div>
 </div>
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/toolbar/toolbar.component.html b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/toolbar/toolbar.component.html
index 69d4557..a0e2d23 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/toolbar/toolbar.component.html
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/toolbar/toolbar.component.html
@@ -81,5 +81,8 @@
         <div class="button" id="toolbar-topo2-toolbar-topo2-layout-access" (click)="buttonClicked('layout-access-btn')">
             <onos-icon iconSize="25" iconId="m_disjointPaths" toolTip="Access layout - separate service leafs" classes="button"></onos-icon>
         </div>
+        <div class="button" id="toolbar-topo2-toolbar-topo2-alarms-tog" (click)="buttonClicked('alarms-tog')">
+            <onos-icon iconSize="25" iconId="clock" toolTip="Toggle Alarms display" classes="button" [classes]="['toggleButton', alarmsVisible?'selected':'']"></onos-icon>
+        </div>
     </div>
 </div>
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/toolbar/toolbar.component.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/toolbar/toolbar.component.ts
index 40fdfda..5ea7d03 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/toolbar/toolbar.component.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/panel/toolbar/toolbar.component.ts
@@ -40,7 +40,7 @@
 export const QUICKHELP_BTN = 'quickhelp-btn';
 export const LAYOUT_DEFAULT_BTN = 'layout-default-btn';
 export const LAYOUT_ACCESS_BTN = 'layout-access-btn';
-
+export const ALARMS_TOGGLE = 'alarms-tog';
 
 /*
  ONOS GUI -- Topology Toolbar Module.
@@ -81,6 +81,7 @@
     @Input() detailsVisible: boolean = true;
     @Input() backgroundVisible: boolean = false;
     @Input() portsVisible: boolean = true;
+    @Input() alarmsVisible: boolean = true;
 
     @Output() buttonEvent = new EventEmitter<string>();
 
@@ -134,6 +135,9 @@
             case BKGRND_TOGGLE:
                 this.backgroundVisible = !this.backgroundVisible;
                 break;
+            case ALARMS_TOGGLE:
+                this.alarmsVisible = !this.alarmsVisible;
+                break;
             default:
         }
         // Send a message up to let TopologyComponent know of the event
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.html b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.html
index 7381a42..019c0d6 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.html
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.html
@@ -115,6 +115,7 @@
                    [deviceLabelToggle]="prefsState.dlbls"
                    [hostLabelToggle]="prefsState.hlbls"
                    [showHosts]="prefsState.hosts"
+                   [showAlarms]="prefsState.alarms"
                    [highlightPorts]="prefsState.porthl"
                    [scale]="window.innerHeight / (window.innerWidth * zoomDirective?.zoomCached.sc)"
                    (selectedNodeEvent)="nodeSelected($event)">
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.spec.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.spec.ts
index ba99fc8..15c2bd1 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.spec.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.spec.ts
@@ -51,6 +51,7 @@
 import {SubRegionNodeSvgComponent} from '../layer/forcesvg/visuals/subregionnodesvg/subregionnodesvg.component';
 import {HostNodeSvgComponent} from '../layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component';
 import {LayoutService} from '../layout.service';
+import {BadgeSvgComponent} from '../layer/forcesvg/visuals/badgesvg/badgesvg.component';
 
 
 class MockActivatedRoute extends ActivatedRoute {
@@ -215,7 +216,8 @@
                 MapSelectorComponent,
                 BackgroundSvgComponent,
                 MapSvgComponent,
-                GridsvgComponent
+                GridsvgComponent,
+                BadgeSvgComponent
             ],
             providers: [
                 { provide: FnService, useValue: fs },
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts
index fb4e4cb..f48f33a 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts
@@ -63,7 +63,8 @@
     PORTS_TOGGLE,
     QUICKHELP_BTN,
     RESETZOOM_BTN,
-    SUMMARY_TOGGLE
+    SUMMARY_TOGGLE,
+    ALARMS_TOGGLE
 } from '../panel/toolbar/toolbar.component';
 import {TrafficService, TrafficType} from '../traffic.service';
 import {ZoomableDirective} from '../layer/zoomable.directive';
@@ -88,6 +89,7 @@
 const PREF_TOOLBAR = 'toolbar';
 const PREF_PINNED = 'pinned';
 const PREF_TRAFFIC = 'traffic';
+const PREF_ALARMS = 'alarms';
 
 const BACKGROUND_ELEMENTS = [
     'svg topo2',
@@ -114,6 +116,7 @@
     grid: number;
     pinned: number;
     traffic: number;
+    alarms: number;
 }
 
 /**
@@ -171,7 +174,8 @@
         toolbar: 0,
         grid: 0,
         pinned: 0,
-        traffic: 2 // default to PORTSTATSPKTSEC, as it will iterate over to 0 on init
+        traffic: 2, // default to PORTSTATSPKTSEC, as it will iterate over to 0 on init
+        alarms: 1,
     };
 
     mapIdState: MapObject = <MapObject>{
@@ -436,6 +440,9 @@
             case LAYOUT_ACCESS_BTN:
                 this.layout.changeLayout(LayoutType.LAYOUT_ACCESS);
                 break;
+            case ALARMS_TOGGLE:
+                this.toggleAlarms();
+                break;
             default:
                 this.log.warn('Unhandled Toolbar action', name);
         }
@@ -659,6 +666,14 @@
         this.log.debug('toggling offline devices', this.prefsState.offdev);
     }
 
+
+    protected toggleAlarms() {
+        const on: boolean = !Boolean(this.prefsState.alarms);
+        this.flashMsg = this.lionFn(on ? 'show' : 'hide') + ' Alarms';
+        this.updatePrefsState(PREF_ALARMS, on ? 1 : 0);
+        this.log.debug('Alarms toggled', on);
+    }
+
     protected resetZoom() {
         const zoomMapExtents = ZoomUtils.zoomToWindowSize(
             this.bannerHeight, this.window.innerWidth, this.window.innerHeight);