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==========================================================================
 
  22 package org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl;
 
  24 import java.util.Collections;
 
  25 import java.util.EnumSet;
 
  27 import java.util.concurrent.ScheduledExecutorService;
 
  28 import java.util.concurrent.ScheduledFuture;
 
  29 import java.util.concurrent.TimeUnit;
 
  30 import org.eclipse.jdt.annotation.NonNull;
 
  31 import org.eclipse.jdt.annotation.Nullable;
 
  32 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp;
 
  33 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl;
 
  34 import org.onap.ccsdk.features.sdnr.wt.devicemanager.eventdatahandler.ODLEventListenerHandler;
 
  35 import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.InternalSeverity;
 
  36 import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.DeviceMonitoredNe;
 
  37 import org.slf4j.Logger;
 
  38 import org.slf4j.LoggerFactory;
 
  40 public class DeviceMonitorTask implements Runnable {
 
  42     private static final Logger LOG = LoggerFactory.getLogger(DeviceMonitorTask.class);
 
  43     private static final String LOGMARKER = "DMTick";
 
  44     private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStampImpl.getConverter();
 
  46     private final String mountPointName;
 
  47     private final ODLEventListenerHandler odlEventListener;
 
  48     private final Checker checkConnectionToMediator;
 
  49     private final Checker checkConnectionToNe;
 
  51     private int tickCounter; //Added for each tick. Not relevant for internal status
 
  53     private ScheduledFuture<?> taskHandle;
 
  54     private final Object lockNe = new Object(); //USe top lock access to member ne
 
  55     private @Nullable DeviceMonitoredNe ne; //Indication if in status connect or disconnect
 
  56     private @NonNull Boolean mountpointConnectingStateSupervision; //Indication of mountpoint supervision
 
  58     private final Object lockDisconnectSupervisionTickout = new Object();
 
  59     private Integer disconnectSupervisionTickout; //Tickcounter of task ticks for "not connected indication"
 
  60     private Set<DeviceMonitorProblems> currentProblems; //List with actual problems. Synchronized by itself
 
  62     /*------------------------------------------------------------
 
  67      * Setup monitoring task
 
  69      * @param mountPointName to monitor
 
  70      * @param odlEventListener to forward problems to
 
  72     public DeviceMonitorTask(String mountPointName, ODLEventListenerHandler odlEventListener) {
 
  73         LOG.debug("Init task {}", DeviceMonitorTask.class.getSimpleName());
 
  76         this.mountPointName = mountPointName;
 
  77         this.odlEventListener = odlEventListener;
 
  78         this.checkConnectionToMediator = new Checker() {
 
  80             boolean isReachableOnce() {
 
  81                 synchronized (lockNe) {
 
  82                     //mountpoint state "Connected"
 
  83                     //If for any reason the mountpoint is Connected, but Notconf messages are not received
 
  84                     return ne == null ? true : ne.checkIfConnectionToMediatorIsOk();
 
  88         this.checkConnectionToNe = new Checker() {
 
  90             boolean isReachableOnce() {
 
  91                 synchronized (lockNe) {
 
  92                     //mountpoint state "Connected"
 
  93                     //If netconf mediator (netconf application software for NE) has connection loss to managed device.
 
  94                     //The networkelement object is available, but there is no interfacepack available.
 
  95                     return ne == null ? true : ne.checkIfConnectionToNeIsOk();
 
 101         this.taskHandle = null;
 
 102         this.tickCounter = 0;
 
 104         this.mountpointConnectingStateSupervision = false;
 
 105         this.currentProblems = Collections.synchronizedSet(EnumSet.noneOf(DeviceMonitorProblems.class));
 
 106         this.disconnectSupervisionTickout = 0;
 
 108         int removed = odlEventListener.removeAllCurrentProblemsOfNode(mountPointName);
 
 109         LOG.debug("{} Init task removed fault entries {}", LOGMARKER, removed);
 
 114      * Start for each object an own instance of the thread.
 
 116      * @param scheduler for all the threads.
 
 118     public void start(ScheduledExecutorService scheduler) {
 
 119         LOG.info("{} {} DeviceMonitor task to create", LOGMARKER, tickCounter);
 
 120         if (taskHandle == null) {
 
 121             startDisconnectSupervision();
 
 122             taskHandle = scheduler.scheduleAtFixedRate(this, 0, 120, TimeUnit.SECONDS);
 
 123             LOG.info("DeviceMonitor task scheduled");
 
 125             LOG.error("{} {} Task already running.", LOGMARKER, tickCounter);
 
 130      * Call after NE change state to connected. Mountpoint exists. Status is Connecting.
 
 132      * @param neParam that connected
 
 135     public void deviceConnectIndication(@Nullable DeviceMonitoredNe neParam) {
 
 136         LOG.info("{} {} Connect {} and stop.", LOGMARKER, tickCounter, mountPointName);
 
 137         clear(DeviceMonitorProblems.connectionLossOAM);
 
 138         synchronized (lockNe) {
 
 140             this.mountpointConnectingStateSupervision = false;
 
 142         stopDisconnectSupervision();
 
 146      * If ne is disconnected do the related actions. - Mountpoint exists. Status is Connecting or UnableToConnect
 
 149     public void deviceDisconnectIndication() {
 
 150         LOG.info("{} {} Disconnect {} and start.", LOGMARKER, tickCounter, mountPointName);
 
 151         clear(DeviceMonitorProblems.connectionLossOAM);
 
 152         synchronized (lockNe) {
 
 154             this.mountpointConnectingStateSupervision = true;
 
 156         startDisconnectSupervision();
 
 160      * Do all actions to clean up the log if mountpoint has been deleted. - Mountpoint removed Prepare cancellation of
 
 161      * the task and cancel task
 
 164     public void removeMountpointIndication() {
 
 165         for (DeviceMonitorProblems problem : DeviceMonitorProblems.values()) {
 
 169         if (this.taskHandle != null) {
 
 170             this.taskHandle.cancel(false);
 
 171             LOG.info("{} {} DeviceMonitor task canceled for {}", LOGMARKER, tickCounter, mountPointName);
 
 173             LOG.error("{} {} Task already stopped", LOGMARKER, tickCounter);
 
 180     public void refreshAlarms() {
 
 181         LOG.debug("{} Start refresh of all problems", LOGMARKER);
 
 182         synchronized (currentProblems) {
 
 183             for (DeviceMonitorProblems problem : currentProblems) {
 
 184                 LOG.debug("{} Refresh problem {} Raised-status {}", LOGMARKER, problem.name(),
 
 185                         currentProblems.contains(problem));
 
 186                 odlEventListener.onProblemNotification(mountPointName, problem.name(), problem.getSeverity());
 
 189         LOG.debug("{} Finish refresh of all problems", LOGMARKER);
 
 192     /*------------------------------------------------------------
 
 193      * Functions to clear/raise alarm
 
 197      * Raise a problem, but only once
 
 201     private void raise(DeviceMonitorProblems problem) {
 
 202         LOG.debug("{} Raise problem {} Raised-status {}", LOGMARKER, problem.name(), currentProblems.contains(problem));
 
 203         synchronized (currentProblems) {
 
 204             if (!currentProblems.contains(problem)) {
 
 205                 currentProblems.add(problem);
 
 206                 odlEventListener.onProblemNotification(mountPointName, problem.name(), problem.getSeverity());
 
 212      * Raise a problem, but only once
 
 216     private void clear(DeviceMonitorProblems problem) {
 
 217         LOG.debug("{} Clear problem {} Raised-status {}", LOGMARKER, problem.name(), currentProblems.contains(problem));
 
 218         synchronized (currentProblems) {
 
 219             if (currentProblems.contains(problem)) {
 
 220                 currentProblems.remove(problem);
 
 221                 odlEventListener.onProblemNotification(mountPointName, problem.name(), InternalSeverity.NonAlarmed);
 
 227      * Process problem notification cascade
 
 232     private void clearRaiseIfConnected(Checker checker, DeviceMonitorProblems problem) {
 
 233         LOG.debug("{} check start {} problem {} Raised-status {}", LOGMARKER, tickCounter, problem.name(),
 
 234                 currentProblems.contains(problem));
 
 235         if (checker.isConnected()) {
 
 240         LOG.debug("{} check end {} problem {} Raised-status {}", LOGMARKER, tickCounter, problem.name(),
 
 241                 currentProblems.contains(problem));
 
 244     /*------------------------------------------------------------
 
 245      * Functions to start/stop
 
 248     private void startDisconnectSupervision() {
 
 249         synchronized (lockDisconnectSupervisionTickout) {
 
 250             this.disconnectSupervisionTickout = 2;
 
 254     private void stopDisconnectSupervision() {
 
 255         synchronized (lockDisconnectSupervisionTickout) {
 
 256             this.disconnectSupervisionTickout = 0;
 
 260     private boolean processDisconnectSupervisionAndCheckExceeded() {
 
 261         synchronized (lockDisconnectSupervisionTickout) {
 
 262             if (disconnectSupervisionTickout == 0) {
 
 264             } else if (disconnectSupervisionTickout > 0) {
 
 265                 disconnectSupervisionTickout--;
 
 271     /*------------------------------------------------------------
 
 276      * Task to monitor connectivity to Network Elements. Connectivity problems lead to alarm indication.
 
 282             LOG.debug("{} UTCTime {} START mountpoint {} tick {} connecting supervision {} tickout {}", LOGMARKER,
 
 283                     NETCONFTIME_CONVERTER.getTimeStamp(), mountPointName, tickCounter,
 
 284                     mountpointConnectingStateSupervision, disconnectSupervisionTickout);
 
 286             if (mountpointConnectingStateSupervision) {
 
 287                 LOG.debug("{} {} Mountpoint supervision {}", LOGMARKER, tickCounter, mountPointName);
 
 288                 if (processDisconnectSupervisionAndCheckExceeded()) {
 
 289                     raise(DeviceMonitorProblems.connectionLossOAM);
 
 293                 synchronized (lockNe) {
 
 295                         //checks during "Connected"
 
 296                         clear(DeviceMonitorProblems.connectionLossOAM); //Always cleared never raised
 
 297                         LOG.debug("{} {} Prepare check", LOGMARKER, tickCounter);
 
 298                         ne.prepareCheck(); // Prepare ne check
 
 300                         LOG.debug("{} {} Mediator check", LOGMARKER, tickCounter);
 
 301                         clearRaiseIfConnected(checkConnectionToMediator, DeviceMonitorProblems.connectionLossMediator);
 
 304                         LOG.debug("{} {} Ne check", LOGMARKER, tickCounter);
 
 305                         clearRaiseIfConnected(checkConnectionToNe, DeviceMonitorProblems.connectionLossNeOAM);
 
 307                         //Monitor switch off.
 
 308                         LOG.debug("{} {} Monitor switch off state", LOGMARKER, tickCounter);
 
 309                         clear(DeviceMonitorProblems.connectionLossOAM); //Always cleared never raised
 
 310                         clear(DeviceMonitorProblems.connectionLossMediator); //Always cleared never raised
 
 311                         clear(DeviceMonitorProblems.connectionLossNeOAM); //Always cleared never raised
 
 315         } catch (Exception e) {
 
 316             //Prevent stopping the task
 
 317             LOG.warn("{} {} During DeviceMontoring task", LOGMARKER, tickCounter, e);
 
 319         LOG.debug("{} {} END", LOGMARKER, tickCounter++);