2  * ============LICENSE_START========================================================================
 
   3  * ONAP : ccsdk feature sdnr wt
 
   4  * =================================================================================================
 
   5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
 
   6  * =================================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 
   8  * in compliance with the License. You may obtain a copy of the License at
 
  10  * http://www.apache.org/licenses/LICENSE-2.0
 
  12  * Unless required by applicable law or agreed to in writing, software distributed under the License
 
  13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 
  14  * or implied. See the License for the specific language governing permissions and limitations under
 
  16  * ============LICENSE_END==========================================================================
 
  19  * (c) 2017 highstreet technologies GmbH
 
  22 package org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl;
 
  24 import java.util.Enumeration;
 
  25 import java.util.Optional;
 
  26 import java.util.concurrent.ConcurrentHashMap;
 
  27 import java.util.concurrent.Executors;
 
  28 import java.util.concurrent.ScheduledExecutorService;
 
  29 import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation;
 
  30 import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener;
 
  31 import org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl.config.DmConfig;
 
  32 import org.onap.ccsdk.features.sdnr.wt.devicemanager.eventdatahandler.ODLEventListenerHandler;
 
  33 import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.DeviceMonitoredNe;
 
  34 import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement;
 
  35 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
 
  36 import org.opendaylight.mdsal.binding.api.DataBroker;
 
  37 import org.slf4j.Logger;
 
  38 import org.slf4j.LoggerFactory;
 
  41  * Implementation of concept "Active monitoring" of a device.<br>
 
  43  * For each existing mountpoint a task runs with 120s cycle time. Every 120 seconds the check actions are performed. The
 
  44  * request is handled by the NETCONF layer with a (default)configured time-out of 60 seconds.<br>
 
  45  * Generated alarms, by the object/node "SDN-Controller" are (enum DeviceMonitorProblems):<br>
 
  46  * - notConnected(InternalSeverity.Warning)<br>
 
  47  * - noConnectionMediator(InternalSeverity.Minor)<br>
 
  48  * - noConnectionNe(InternalSeverity.Critical)<br>
 
  50  * 1. Mountpoint does not exist<br>
 
  51  * If the mountpoint does not exists there are no related current alarms in the database.<br>
 
  53  * 2. Created mountpoint with state "Connecting" or "UnableToConnect"<br>
 
  54  * If the Mountpoint is created and connection status is "Connecting" or "UnableToConnect".<br>
 
  55  * - After about 2..4 Minutes ... raise alarm "notConnected" with severity warning<br>
 
  57  * 3. Created mountpoint with state "Connection"<br>
 
  58  * There are two monitor activities.<br>
 
  59  * 3a. Check of Mediator connection by requesting (typical) cached data.<br>
 
  60  * - After about 60 seconds raise alarm: connection-loss-mediator with severity minor<br>
 
  61  * - Request from Mediator: network-element<br>
 
  63  * 3b. Check connection to NEby requesting (typical) non-cached data.<br>
 
  64  * - Only if AirInterface available. The first one is used.<br>
 
  65  * - Requested are the currentAlarms<br>
 
  66  * - After about 60 seconds raise alarm: connection-loss-network-element with severity critical<br>
 
  72 public class DeviceMonitorImpl implements DeviceMonitor, IConfigChangedListener {
 
  74     private static final Logger LOG = LoggerFactory.getLogger(DeviceMonitorImpl.class);
 
  76     private final ConcurrentHashMap<String, DeviceMonitorTask> queue;
 
  77     private final ScheduledExecutorService scheduler;
 
  78     private final ODLEventListenerHandler odlEventListener;
 
  79     @SuppressWarnings("unused")
 
  80     private final DataBroker dataBroker; //Future usage
 
  81     private final DmConfig dmConfig;
 
  82     private final DeviceMonitoredNe dummyNe;
 
  84     /*-------------------------------------------------------------
 
  85      * Construction/ destruction of service
 
  89      * Basic implementation of devicemonitoring
 
  91      * @param odlEventListener as destination for problems
 
  93     public DeviceMonitorImpl(DataBroker dataBroker, ODLEventListenerHandler odlEventListener,
 
  94             ConfigurationFileRepresentation htconfig) {
 
  95         LOG.info("Construct {}", this.getClass().getSimpleName());
 
  97         this.odlEventListener = odlEventListener;
 
  98         this.dataBroker = dataBroker;
 
  99         this.dummyNe = getDummyNe();
 
 101         htconfig.registerConfigChangedListener(this);
 
 102         this.dmConfig = new DmConfig(htconfig);
 
 103         setDmConfig(dmConfig);
 
 105         this.queue = new ConcurrentHashMap<>();
 
 106         this.scheduler = Executors.newScheduledThreadPool(10);
 
 110      * Stop the service. Stop all running monitoring tasks.
 
 113     synchronized public void close() {
 
 114         LOG.info("Close {}", this.getClass().getSimpleName());
 
 116         Enumeration<String> e = queue.keys();
 
 117         while (e.hasMoreElements()) {
 
 118             deviceDisconnectIndication(e.nextElement());
 
 121         scheduler.shutdown();
 
 125     public void onConfigChanged() {
 
 126         setDmConfig(dmConfig);
 
 129     private void setDmConfig(DmConfig dmConfig) {
 
 130         for (DeviceMonitorProblems problem : DeviceMonitorProblems.values()) {
 
 131             problem.setSeverity(dmConfig.getSeverity(problem));
 
 135     /*-------------------------------------------------------------
 
 136      * Start/ stop/ update service for Mountpoint
 
 140      * Notify of device state changes to "connected" for slave nodes
 
 142      * @param mountPointNodeName name of mount point
 
 145     synchronized public void deviceConnectSlaveIndication(String mountPointNodeName) {
 
 146         deviceConnectMasterIndication(mountPointNodeName, (DeviceMonitoredNe) null);
 
 150     public void deviceConnectMasterIndication(String mountPointNodeName, NetworkElement networkElement) {
 
 151         Optional<DeviceMonitoredNe> monitoredNe = networkElement.getService(DeviceMonitoredNe.class);
 
 152         deviceConnectMasterIndication(mountPointNodeName, monitoredNe.isPresent() ? monitoredNe.get() : dummyNe);
 
 156      * Notify of device state changes to "connected"
 
 158      * @param mountPointNodeName name of mount point
 
 159      * @param ne to monitor
 
 162     synchronized public void deviceConnectMasterIndication(String mountPointNodeName, DeviceMonitoredNe ne) {
 
 164         LOG.debug("ne changes to connected state {}", mountPointNodeName);
 
 165         createMonitoringTask(mountPointNodeName);
 
 166         if (queue.containsKey(mountPointNodeName)) {
 
 167             DeviceMonitorTask task = queue.get(mountPointNodeName);
 
 168             task.deviceConnectIndication(ne);
 
 170             LOG.warn("Monitoring task not in queue: {} {} {}", mountPointNodeName, mountPointNodeName.hashCode(),
 
 176      * Notify of device state change to "disconnected" Mount point supervision
 
 178      * @param mountPointNodeName to deregister
 
 181     synchronized public void deviceDisconnectIndication(String mountPointNodeName) {
 
 183         LOG.debug("State changes to not connected state {}", mountPointNodeName);
 
 184         createMonitoringTask(mountPointNodeName);
 
 185         if (queue.containsKey(mountPointNodeName)) {
 
 186             DeviceMonitorTask task = queue.get(mountPointNodeName);
 
 187             task.deviceDisconnectIndication();
 
 189             LOG.warn("Monitoring task not in queue: {} {} {}", mountPointNodeName, mountPointNodeName.hashCode(),
 
 195      * removeMountpointIndication deregisters a mountpoint for registration services
 
 197      * @param mountPointNodeName to deregister
 
 200     synchronized public void removeMountpointIndication(String mountPointNodeName) {
 
 202         if (queue.containsKey(mountPointNodeName)) {
 
 203             DeviceMonitorTask task = queue.get(mountPointNodeName);
 
 205             queue.remove(mountPointNodeName);
 
 207             task.removeMountpointIndication();
 
 208             LOG.debug("Task stopped: {}", mountPointNodeName);
 
 210             LOG.warn("Task not in queue: {}", mountPointNodeName);
 
 215      * Referesh database by raising all alarms again.
 
 218     public void refreshAlarmsInDb() {
 
 219         synchronized (queue) {
 
 220             for (DeviceMonitorTask task : queue.values()) {
 
 221                 task.refreshAlarms();
 
 227      * For test run the tasks
 
 229     public void taskTestRun() {
 
 230         synchronized (queue) {
 
 231             for (DeviceMonitorTask task : queue.values()) {
 
 237     /*-------------------------------------------------------------
 
 242      * createMountpoint registers a new mountpoint monitoring service
 
 244      * @param mountPointNodeName name of mountpoint
 
 246     synchronized private DeviceMonitorTask createMonitoringTask(String mountPointNodeName) {
 
 248         DeviceMonitorTask task;
 
 249         LOG.debug("Register for monitoring {} {}", mountPointNodeName, mountPointNodeName.hashCode());
 
 251         if (queue.containsKey(mountPointNodeName)) {
 
 252             LOG.info("Monitoring task exists");
 
 253             task = queue.get(mountPointNodeName);
 
 255             LOG.info("Do start of DeviceMonitor task");
 
 256             //Runnable task = new PerformanceManagerTask(queue, databaseService);
 
 257             task = new DeviceMonitorTask(mountPointNodeName, this.odlEventListener);
 
 258             queue.put(mountPointNodeName, task);
 
 259             task.start(scheduler);
 
 265     private static DeviceMonitoredNe getDummyNe() {
 
 266         return new DeviceMonitoredNe() {
 
 269             public void prepareCheck() {
 
 274             public boolean checkIfConnectionToMediatorIsOk() {
 
 279             public boolean checkIfConnectionToNeIsOk() {
 
 284             public Optional<NetconfAccessor> getAcessor() {
 
 285                 return Optional.empty();