add new devicemanager
[ccsdk/features.git] / sdnr / wt / devicemanager / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / devicemanager / devicemonitor / impl / DeviceMonitorImpl.java
1 /*******************************************************************************
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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
15  * the License.
16  * ============LICENSE_END==========================================================================
17  ******************************************************************************/
18 /**
19  * (c) 2017 highstreet technologies GmbH
20  */
21
22 package org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl;
23
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
30 import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation;
31 import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener;
32 import org.onap.ccsdk.features.sdnr.wt.devicemanager.DeviceMonitoredNe;
33 import org.onap.ccsdk.features.sdnr.wt.devicemanager.NetworkElement;
34 import org.onap.ccsdk.features.sdnr.wt.devicemanager.devicemonitor.impl.config.DmConfig;
35 import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.handler.ODLEventListenerHandler;
36 import org.opendaylight.mdsal.binding.api.DataBroker;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  *  Implementation of concept "Active monitoring" of a device.<br>
42  *    <br>
43  *  For each existing mountpoint a task runs with 120s cycle time. Every 120 seconds the check actions are performed.
44  *  The 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>
49  *    <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>
52  *    <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>
56  *    <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>
62  *    <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>
67  *    <br>
68  * @author herbert
69  */
70
71 public class DeviceMonitorImpl implements DeviceMonitor, IConfigChangedListener {
72
73     private static final Logger LOG = LoggerFactory.getLogger(DeviceMonitorImpl.class);
74
75     private final ConcurrentHashMap<String, DeviceMonitorTask> queue;
76     private final ScheduledExecutorService scheduler;
77     private final ODLEventListenerHandler odlEventListener;
78     @SuppressWarnings("unused")
79     private final DataBroker dataBroker; //Future usage
80     private final DmConfig dmConfig;
81     private final DeviceMonitoredNe dummyNe;
82
83     /*-------------------------------------------------------------
84      * Construction/ destruction of service
85      */
86
87     /**
88      * Basic implementation of devicemonitoring
89      * @param odlEventListener as destination for problems
90      */
91     public DeviceMonitorImpl(DataBroker dataBroker, ODLEventListenerHandler odlEventListener, ConfigurationFileRepresentation htconfig) {
92         LOG.info("Construct {}", this.getClass().getSimpleName());
93
94         this.odlEventListener = odlEventListener;
95         this.dataBroker = dataBroker;
96         this.dummyNe = getDummyNe();
97
98         htconfig.registerConfigChangedListener(this);
99         this.dmConfig = new DmConfig(htconfig);
100         setDmConfig(dmConfig);
101
102         this.queue = new ConcurrentHashMap<>();
103         this.scheduler = Executors.newScheduledThreadPool(10);
104     }
105
106     /**
107      * Stop the service. Stop all running monitoring tasks.
108      */
109     @Override
110     synchronized public void close() {
111         LOG.info("Close {}", this.getClass().getSimpleName());
112
113         Enumeration<String> e = queue.keys();
114         while (e.hasMoreElements()) {
115             deviceDisconnectIndication(e.nextElement());
116         }
117
118         scheduler.shutdown();
119     }
120
121     @Override
122     public void onConfigChanged() {
123         setDmConfig(dmConfig);
124     }
125
126     private void setDmConfig(DmConfig dmConfig) {
127         for (DeviceMonitorProblems problem : DeviceMonitorProblems.values()) {
128             problem.setSeverity(dmConfig.getSeverity(problem));
129         }
130     }
131
132     /*-------------------------------------------------------------
133      * Start/ stop/ update service for Mountpoint
134      */
135
136     /**
137      * Notify of device state changes to "connected" for slave nodes
138      * @param mountPointNodeName name of mount point
139      */
140     @Override
141     synchronized public void deviceConnectSlaveIndication(String mountPointNodeName) {
142         deviceConnectMasterIndication(mountPointNodeName, (DeviceMonitoredNe)null);
143     }
144
145     @Override
146     public void deviceConnectMasterIndication(String mountPointNodeName, NetworkElement networkElement) {
147         Optional<DeviceMonitoredNe> monitoredNe = networkElement.getService(DeviceMonitoredNe.class);
148            deviceConnectMasterIndication(mountPointNodeName, monitoredNe.isPresent() ? monitoredNe.get() : dummyNe);
149     }
150
151     /**
152      * Notify of device state changes to "connected"
153      * @param mountPointNodeName name of mount point
154      * @param ne to monitor
155      */
156     @Override
157     synchronized public void deviceConnectMasterIndication(String mountPointNodeName, DeviceMonitoredNe ne) {
158
159         LOG.debug("ne changes to connected state {}",mountPointNodeName);
160         createMonitoringTask(mountPointNodeName);
161         if (queue.containsKey(mountPointNodeName)) {
162             DeviceMonitorTask task = queue.get(mountPointNodeName);
163             task.deviceConnectIndication(ne);
164         } else {
165             LOG.warn("Monitoring task not in queue: {} {} {}", mountPointNodeName, mountPointNodeName.hashCode(), queue.size());
166         }
167     }
168
169    /**
170     * Notify of device state change to "disconnected"
171     * Mount point supervision
172     * @param mountPointNodeName to deregister
173     */
174     @Override
175     synchronized public void deviceDisconnectIndication(String mountPointNodeName) {
176
177         LOG.debug("State changes to not connected state {}",mountPointNodeName);
178         createMonitoringTask(mountPointNodeName);
179         if (queue.containsKey(mountPointNodeName)) {
180             DeviceMonitorTask task = queue.get(mountPointNodeName);
181             task.deviceDisconnectIndication();
182         } else {
183             LOG.warn("Monitoring task not in queue: {} {} {}", mountPointNodeName, mountPointNodeName.hashCode(), queue.size());
184         }
185     }
186
187     /**
188      * removeMountpointIndication deregisters a mountpoint for registration services
189      * @param mountPointNodeName to deregister
190      */
191     @Override
192     synchronized public void removeMountpointIndication(String mountPointNodeName) {
193
194         if (queue.containsKey(mountPointNodeName)) {
195             DeviceMonitorTask task = queue.get(mountPointNodeName);
196             //Remove from here
197             queue.remove(mountPointNodeName);
198             //Clear all problems
199             task.removeMountpointIndication();
200             LOG.debug("Task stopped: {}", mountPointNodeName);
201         } else {
202             LOG.warn("Task not in queue: {}", mountPointNodeName);
203         }
204     }
205
206     /**
207      * Referesh database by raising all alarms again.
208      */
209     @Override
210     public void refreshAlarmsInDb() {
211         synchronized(queue) {
212             for (DeviceMonitorTask task : queue.values()) {
213                 task.refreshAlarms();
214             }
215         }
216     }
217
218     /*-------------------------------------------------------------
219      * Private functions
220      */
221
222     /**
223      * createMountpoint registers a new mountpoint monitoring service
224      * @param mountPointNodeName name of mountpoint
225      */
226     synchronized private DeviceMonitorTask createMonitoringTask(String mountPointNodeName) {
227
228         DeviceMonitorTask task;
229         LOG.debug("Register for monitoring {} {}",mountPointNodeName, mountPointNodeName.hashCode());
230
231         if (queue.containsKey(mountPointNodeName)) {
232             LOG.info("Monitoring task exists");
233             task = queue.get(mountPointNodeName);
234         } else {
235             LOG.info("Do start of DeviceMonitor task");
236             //Runnable task = new PerformanceManagerTask(queue, databaseService);
237             task = new DeviceMonitorTask(mountPointNodeName, this.odlEventListener);
238             queue.put(mountPointNodeName, task);
239             task.start(scheduler);
240         }
241         return task;
242     }
243
244
245     private static DeviceMonitoredNe getDummyNe() {
246         return new DeviceMonitoredNe() {
247
248             @Override
249             public void prepareCheck() {
250                 // Do nothing
251             }
252
253             @Override
254             public boolean checkIfConnectionToMediatorIsOk() {
255                 return true;
256             }
257
258             @Override
259             public boolean checkIfConnectionToNeIsOk() {
260                 return true;
261             }
262         };
263     }
264 }