[ONOS-3203] End-to-end demo of Fault Management via SNMP.

This adds SNMP device-discovery, and a Fault Management app which makes alarms available to users via REST/GUI/CLI interfaces.
There is still code cleanup that could be done, but aim of this commit is an end-to-end proof of concept.

To demonstrate :

1) /opt/onos/bin/onos-service
onos> app activate org.onosproject.snmp
onos> app activate org.onosproject.faultmanagement

2) SNMP devices are seeded via config file. The default seed file contains connection details for devices (SNMP agents) available via internet  e.g. demo.snmplabs.com
cp /opt/onos/apache-karaf-3.0.3/etc/samples/org.onosproject.provider.snmp.device.impl.SnmpDeviceProvider.cfg   /opt/onos/apache-karaf-3.0.3/etc/

3) ONOS will poll these SNMP devices and store their alarms.

4) You can now manipulate the alarms via REST  e.g. http://<onos>:8181/onos/v1/fm/alarms , via CLI  via various "alarm-*” commands or in UI with an Alarms Overlay.

More info at https://wiki.onosproject.org/display/ONOS/Fault+Management

15/Dec/15: Updated regarding review comments from Thomas Vachuska.
17/Dec/15: Updated coreService.registerApplication(name) as per https://gerrit.onosproject.org/#/c/6878/

Change-Id: I886f8511f178dc4600ab96e5ff10cc90329cabec
diff --git a/apps/faultmanagement/fmgui/src/main/java/org/onosproject/faultmanagement/alarms/gui/AlarmTopovOverlay.java b/apps/faultmanagement/fmgui/src/main/java/org/onosproject/faultmanagement/alarms/gui/AlarmTopovOverlay.java
new file mode 100644
index 0000000..7fc87db
--- /dev/null
+++ b/apps/faultmanagement/fmgui/src/main/java/org/onosproject/faultmanagement/alarms/gui/AlarmTopovOverlay.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.faultmanagement.alarms.gui;
+
+import java.util.Map;
+import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
+import org.onosproject.net.DeviceId;
+import org.onosproject.ui.UiTopoOverlay;
+import org.onosproject.ui.topo.ButtonId;
+import org.onosproject.ui.topo.PropertyPanel;
+import org.onosproject.ui.topo.TopoConstants.CoreButtons;
+import static org.onosproject.ui.topo.TopoConstants.Properties.*;
+
+/**
+ * Our topology overlay.
+ */
+public class AlarmTopovOverlay extends UiTopoOverlay {
+
+    // NOTE: this must match the ID defined in alarmTopov.js
+    private static final String OVERLAY_ID = "alarmsTopo-overlay";
+
+    private static final ButtonId ALARM1_BUTTON = new ButtonId("alarm1button");
+    private static final ButtonId ALARM2_BUTTON = new ButtonId("alarm2button");
+
+    public AlarmTopovOverlay() {
+        super(OVERLAY_ID);
+    }
+
+    @Override
+    public void modifySummary(PropertyPanel pp) {
+        pp.title("Alarms Overview");
+        // We could just remove some properties here but lets keep it uncluttered, unless
+        //    there is feedback other properties are essential.
+        pp.removeAllProps();
+        Map<Alarm.SeverityLevel, Long> countsForAll = AlarmServiceUtil.lookUpAlarmCounts();
+        addAlarmCountsProperties(pp, countsForAll);
+
+    }
+
+    @Override
+    public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) {
+        pp.title("Alarm Details");
+        pp.removeProps(LATITUDE, LONGITUDE, PORTS, FLOWS, TUNNELS, SERIAL_NUMBER, PROTOCOL);
+
+        Map<Alarm.SeverityLevel, Long> countsForDevice = AlarmServiceUtil.lookUpAlarmCounts(deviceId);
+        addAlarmCountsProperties(pp, countsForDevice);
+
+        pp.addButton(ALARM1_BUTTON)
+                .addButton(ALARM2_BUTTON);
+
+        pp.removeButtons(CoreButtons.SHOW_PORT_VIEW)
+                .removeButtons(CoreButtons.SHOW_GROUP_VIEW);
+    }
+
+    private void addAlarmCountsProperties(PropertyPanel pp, Map<Alarm.SeverityLevel, Long> countsForDevice) {
+
+        // TODO we could show these as color-coded squares with a count inside, to save space on the screen.
+
+        long cr = countsForDevice.getOrDefault(Alarm.SeverityLevel.CRITICAL, 0L);
+        long ma = countsForDevice.getOrDefault(Alarm.SeverityLevel.MAJOR, 0L);
+        long mi = countsForDevice.getOrDefault(Alarm.SeverityLevel.MINOR, 0L);
+        long wa = countsForDevice.getOrDefault(Alarm.SeverityLevel.WARNING, 0L);
+        long in = countsForDevice.getOrDefault(Alarm.SeverityLevel.INDETERMINATE, 0L);
+        long cl = countsForDevice.getOrDefault(Alarm.SeverityLevel.CLEARED, 0L);
+
+        // Unfortunately the PropertyPanel does not righ justify numbers even when using longs,
+        // but that not in scope of fault management work
+        pp.addProp("Critical", cr);
+        pp.addProp("Major", ma);
+        pp.addProp("Minor", mi);
+        pp.addProp("Warning", wa);
+        pp.addProp("Indeter.", in);
+        pp.addProp("Cleared", cl);
+        pp.addSeparator();
+        pp.addProp("Total", cr + ma + mi + wa + in + cl);
+
+    }
+
+}