NetconfAlarmProvider alerts core about notifications given subscription.

Change-Id: I7561ba680eb8bac33a8543d6aa1bccf6732e95db
diff --git a/providers/netconf/alarm/src/main/java/org/onosproject/provider/netconf/alarm/NetconfAlarmProvider.java b/providers/netconf/alarm/src/main/java/org/onosproject/provider/netconf/alarm/NetconfAlarmProvider.java
new file mode 100644
index 0000000..5a86dd0
--- /dev/null
+++ b/providers/netconf/alarm/src/main/java/org/onosproject/provider/netconf/alarm/NetconfAlarmProvider.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2016-present 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.provider.netconf.alarm;
+
+import com.google.common.collect.Maps;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistry;
+import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfDevice;
+import org.onosproject.netconf.NetconfDeviceInfo;
+import org.onosproject.netconf.NetconfDeviceListener;
+import org.onosproject.netconf.NetconfDeviceOutputEvent;
+import org.onosproject.netconf.NetconfDeviceOutputEventListener;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.netconf.ctl.NetconfDeviceOutputEventListenerImpl;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provider which uses an Alarm Manager to keep track of device notifications.
+ */
+@Component(immediate = true)
+public class NetconfAlarmProvider extends AbstractProvider implements AlarmProvider {
+
+    public static final String ACTIVE = "active";
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected AlarmProviderRegistry providerRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetconfController controller;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected AlarmService alarmService;
+
+    protected AlarmProviderService providerService;
+
+    private Map<DeviceId, InternalNotificationListener> idNotificationListenerMap = Maps.newHashMap();
+
+    public NetconfAlarmProvider() {
+        super(new ProviderId("netconf", "org.onosproject.netconf"));
+    }
+
+    private NetconfDeviceListener deviceListener = new InnerDeviceListener();
+
+    @Activate
+    public void activate() {
+        providerService = providerRegistry.register(this);
+        controller.getNetconfDevices().forEach(id -> {
+            NetconfDevice device = controller.getNetconfDevice(id);
+            NetconfSession session = device.getSession();
+            InternalNotificationListener listener = new InternalNotificationListener(device.getDeviceInfo());
+            session.addDeviceOutputListener(listener);
+            idNotificationListenerMap.put(id, listener);
+        });
+        controller.addDeviceListener(deviceListener);
+        log.info("NetconfAlarmProvider Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        providerRegistry.unregister(this);
+        idNotificationListenerMap.forEach((id, listener) -> {
+            controller.getNetconfDevice(id)
+                      .getSession()
+                      .removeDeviceOutputListener(listener);
+        });
+        controller.removeDeviceListener(deviceListener);
+        providerService = null;
+        log.info("NetconfAlarmProvider Stopped");
+    }
+
+    @Override
+    public void triggerProbe(DeviceId deviceId) {
+        log.debug("Alarm probe triggered with " + deviceId);
+    }
+
+    private void triggerProbe(DeviceId deviceId, Collection<Alarm> alarms) {
+        providerService.updateAlarmList(deviceId, alarms);
+        triggerProbe(deviceId);
+    }
+
+    private class InternalNotificationListener extends NetconfDeviceOutputEventListenerImpl
+            implements NetconfDeviceOutputEventListener {
+
+        InternalNotificationListener(NetconfDeviceInfo deviceInfo) {
+            super(deviceInfo);
+        }
+
+        @Override
+        public void event(NetconfDeviceOutputEvent event) {
+            if (event.type() == NetconfDeviceOutputEvent.Type.DEVICE_NOTIFICATION) {
+                DeviceId deviceId = event.getDeviceInfo().getDeviceId();
+                Alarm newAlarm = new DefaultAlarm.Builder(deviceId, event.getMessagePayload(),
+                                                          Alarm.SeverityLevel.WARNING, 0).build();
+                Collection<Alarm> alarms = Collections.singleton(newAlarm);
+                triggerProbe(deviceId, alarms);
+            }
+        }
+    }
+
+    private class InnerDeviceListener implements NetconfDeviceListener {
+
+        @Override
+        public void deviceAdded(DeviceId deviceId) {
+            NetconfDevice device = controller.getNetconfDevice(deviceId);
+            NetconfSession session = device.getSession();
+            InternalNotificationListener listener = new InternalNotificationListener(device.getDeviceInfo());
+            session.addDeviceOutputListener(listener);
+            idNotificationListenerMap.put(deviceId, listener);
+        }
+
+        @Override
+        public void deviceRemoved(DeviceId deviceId) {
+            idNotificationListenerMap.remove(deviceId);
+        }
+    }
+}