5 package org.opendaylight.mwtn.deviceMonitor.impl;
7 import java.util.Collections;
8 import java.util.EnumSet;
10 import java.util.concurrent.ScheduledExecutorService;
11 import java.util.concurrent.ScheduledFuture;
12 import java.util.concurrent.TimeUnit;
14 import javax.annotation.Nullable;
16 import org.opendaylight.mwtn.base.internalTypes.InternalSeverity;
17 import org.opendaylight.mwtn.base.netconf.ONFCoreNetworkElementRepresentation;
18 import org.opendaylight.mwtn.devicemanager.impl.listener.ODLEventListener;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
22 public class DeviceMonitorTask implements Runnable {
24 private static final Logger LOG = LoggerFactory.getLogger(DeviceMonitorTask.class);
25 private static final String LOGMARKER = "DMTick";
27 private final String mountPointName;
28 private final ODLEventListener odlEventListener;
29 private final Checker checkConnectionToMediator;
30 private final Checker checkConnectionToNe;
32 private int tickCounter; //Added for each tick. Not relevant for internal status
34 private ScheduledFuture<?> taskHandle;
35 private final Object lockNe = new Object(); //USe top lock access to member ne
36 private @Nullable ONFCoreNetworkElementRepresentation ne; //Indication if in status connect or disconnect
37 private Integer disconnectSupervisionTickout; //Tickcounter of task ticks for "not connected indication"
38 private Set<DeviceMonitorProblems> currentProblems; //List with actual problems. Synchronized by itself
42 /*------------------------------------------------------------
47 * Setup monitoring task
48 * @param mountPointName to monitor
49 * @param odlEventListener to forward problems to
51 public DeviceMonitorTask(String mountPointName, ODLEventListener odlEventListener) {
52 LOG.debug("Init task {}", DeviceMonitorTask.class.getSimpleName());
55 this.mountPointName = mountPointName;
56 this.odlEventListener = odlEventListener;
57 this.checkConnectionToMediator = new Checker() {
59 boolean isReachableOnce() {
60 synchronized(lockNe) {
61 //If ne is not connected anymore clear alarms
62 return ne == null ? true : ne.checkAndConnectionToMediatorIsOk();
66 this.checkConnectionToNe = new Checker() {
68 boolean isReachableOnce() {
69 synchronized(lockNe) {
70 //If ne is not connected anymore clear alarms
71 return ne == null ? true : ne.checkAndConnectionToNeIsOk();
77 this.taskHandle = null;
80 this.currentProblems = Collections.synchronizedSet(EnumSet.noneOf(DeviceMonitorProblems.class));
81 this.disconnectSupervisionTickout = 0;
83 int removed = odlEventListener.removeAllCurrentProblemsOfNode(mountPointName);
84 LOG.debug("{} Init task removed fault entries {}", LOGMARKER, removed);
89 * Start for each object an own instance of the thread.
90 * @param scheduler for all the threads.
92 public void start(ScheduledExecutorService scheduler) {
93 LOG.info("{} {} DeviceMonitor task to create", LOGMARKER, tickCounter);
94 if (taskHandle == null) {
95 startDisconnectSupervision();
96 taskHandle = scheduler.scheduleAtFixedRate(this, 0, 120, TimeUnit.SECONDS);
97 LOG.info("DeviceMonitor task scheduled");
99 LOG.error("{} {} Task already running.", LOGMARKER, tickCounter);
104 * Call after NE change state to connected
105 * @param neParam that connected
108 public void deviceConnectIndication(ONFCoreNetworkElementRepresentation neParam) {
109 LOG.info("{} {} Connect {} and stop.", LOGMARKER, tickCounter, mountPointName);
110 clear(DeviceMonitorProblems.connectionLossOAM);
111 synchronized(lockNe) {
114 stopDisconnectSupervision();
118 * If ne is disconnected do the related actions.
121 public void deviceDisconnectIndication() {
122 LOG.info("{} {} Disconnect {} and start.", LOGMARKER, tickCounter, mountPointName);
123 clear(DeviceMonitorProblems.connectionLossOAM);
124 synchronized(lockNe) {
127 startDisconnectSupervision();
131 * Do all actions to clean up the log if mountpoint has been deleted.
132 * Prepare cancellation of the task and cancel task
135 public void removeMountpointIndication() {
136 for (DeviceMonitorProblems problem : DeviceMonitorProblems.values()) {
140 if (this.taskHandle != null) {
141 this.taskHandle.cancel(false);
142 LOG.info("{} {} DeviceMonitor task canceled for {}", LOGMARKER, tickCounter, mountPointName);
144 LOG.error("{} {} Task already stopped", LOGMARKER, tickCounter);
148 /*------------------------------------------------------------
153 * Raise a problem, but only once
156 private void raise(DeviceMonitorProblems problem) {
157 LOG.debug("{} Raise problem {} Raised-status {}",LOGMARKER, problem.name(), currentProblems.contains(problem));
158 synchronized(currentProblems) {
159 if (! currentProblems.contains(problem)) {
160 currentProblems.add(problem);
161 odlEventListener.onProblemNotification(mountPointName, problem.name(), problem.getSeverity());
168 * Raise a problem, but only once
171 private void clear(DeviceMonitorProblems problem) {
172 LOG.debug("{} Clear problem {} Raised-status {}",LOGMARKER, problem.name(), currentProblems.contains(problem));
173 synchronized(currentProblems) {
174 if (currentProblems.contains(problem)) {
175 currentProblems.remove(problem);
176 odlEventListener.onProblemNotification(mountPointName, problem.name(), InternalSeverity.NonAlarmed);
182 * Process problem notification cascade
186 private void clearRaiseIfConnected(Checker checker, DeviceMonitorProblems problem) {
187 LOG.debug("{} check start {} problem {} Raised-status {}",LOGMARKER, tickCounter, problem.name(), currentProblems.contains(problem));
188 if (checker.isConnected()) {
193 LOG.debug("{} check end {} problem {} Raised-status {}",LOGMARKER, tickCounter, problem.name(), currentProblems.contains(problem));
197 private void startDisconnectSupervision() {
198 synchronized(disconnectSupervisionTickout) {
199 this.disconnectSupervisionTickout = 2;
203 private void stopDisconnectSupervision() {
204 synchronized(disconnectSupervisionTickout) {
205 this.disconnectSupervisionTickout = 0;
209 private boolean processDisconnectSupervisionAndCheckExceeded() {
210 synchronized(disconnectSupervisionTickout) {
211 if (disconnectSupervisionTickout == 0) {
213 } else if (disconnectSupervisionTickout > 0) {
214 disconnectSupervisionTickout--;
220 /*------------------------------------------------------------
225 * Task to monitor connectivity to Network Elements.
226 * Connectivity problems lead to alarm indication.
232 boolean neNullIndicator;
233 synchronized (lockNe) {
234 neNullIndicator = ne == null;
236 LOG.debug("{} START mountpoint {} tick {} ne==null {} tickout {}",LOGMARKER, mountPointName, tickCounter, neNullIndicator, disconnectSupervisionTickout);
237 if (neNullIndicator) { //NE not connected
238 LOG.debug("{} {} NE disconnected check {}", LOGMARKER, tickCounter, disconnectSupervisionTickout);
239 if (processDisconnectSupervisionAndCheckExceeded()) {
240 raise(DeviceMonitorProblems.connectionLossOAM);
243 clear(DeviceMonitorProblems.connectionLossOAM); //Always cleared never raised
244 LOG.debug("{} {} Prepare check", LOGMARKER, tickCounter);
245 ne.prepareCheck(); // Prepare ne check
247 LOG.debug("{} {} Mediator check", LOGMARKER, tickCounter);
248 clearRaiseIfConnected(checkConnectionToMediator, DeviceMonitorProblems.connectionLossMediator);
251 LOG.debug("{} {} Ne check", LOGMARKER, tickCounter);
252 clearRaiseIfConnected(checkConnectionToNe, DeviceMonitorProblems.connectionLossNeOAM);
254 } catch (Exception e) {
255 //Prevent stopping the task
256 LOG.warn("{} {} (..something..) failed",LOGMARKER, tickCounter, e);
258 LOG.debug("{} {} END", LOGMARKER, tickCounter++);