Fix bugs and formatting issues
[dcaegen2/services/son-handler.git] / src / main / java / org / onap / dcaegen2 / services / sonhms / EventHandler.java
1 /*******************************************************************************
2  *  ============LICENSE_START=======================================================
3  *  son-handler
4  *  ================================================================================
5  *   Copyright (C) 2019 Wipro Limited.
6  *   ==============================================================================
7  *     Licensed under the Apache License, Version 2.0 (the "License");
8  *     you may not use this file except in compliance with the License.
9  *     You may obtain a copy of the License at
10  *  
11  *          http://www.apache.org/licenses/LICENSE-2.0
12  *  
13  *     Unless required by applicable law or agreed to in writing, software
14  *     distributed under the License is distributed on an "AS IS" BASIS,
15  *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *     See the License for the specific language governing permissions and
17  *     limitations under the License.
18  *     ============LICENSE_END=========================================================
19  *  
20  *******************************************************************************/
21
22 package org.onap.dcaegen2.services.sonhms;
23
24 import com.fasterxml.jackson.core.JsonProcessingException;
25 import com.fasterxml.jackson.databind.ObjectMapper;
26
27 import fj.data.Either;
28
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Map.Entry;
35 import java.util.Set;
36 import java.util.concurrent.BlockingQueue;
37 import java.util.concurrent.ExecutorService;
38
39 import org.onap.dcaegen2.services.sonhms.child.ChildThread;
40 import org.onap.dcaegen2.services.sonhms.child.Graph;
41 import org.onap.dcaegen2.services.sonhms.entity.ClusterDetails;
42 import org.onap.dcaegen2.services.sonhms.exceptions.ConfigDbNotFoundException;
43 import org.onap.dcaegen2.services.sonhms.model.CellPciPair;
44 import org.onap.dcaegen2.services.sonhms.model.ClusterMap;
45 import org.onap.dcaegen2.services.sonhms.model.FapServiceList;
46 import org.onap.dcaegen2.services.sonhms.model.LteNeighborListInUseLteCell;
47 import org.onap.dcaegen2.services.sonhms.model.Notification;
48 import org.onap.dcaegen2.services.sonhms.utils.ClusterUtils;
49 import org.onap.dcaegen2.services.sonhms.utils.ThreadUtils;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 public class EventHandler {
54
55     private static Logger log = LoggerFactory.getLogger(EventHandler.class);
56
57     private static Map<Long, ChildThread> childThreadMap = new HashMap<>();
58
59     private BlockingQueue<List<String>> childStatusQueue;
60
61     private Map<Long, String> childStatus;
62
63     private ExecutorService pool;
64
65     private ClusterUtils clusterUtils;
66
67     private ThreadUtils threadUtils;
68
69     /**
70      * Constructor.
71      */
72     public EventHandler(BlockingQueue<List<String>> childStatusQueue, ExecutorService pool,
73             Map<Long, String> childStatus, ClusterUtils clusterUtils, ThreadUtils threadUtils) {
74
75         this.childStatusQueue = childStatusQueue;
76         this.childStatus = childStatus;
77         this.pool = pool;
78         this.clusterUtils = clusterUtils;
79         this.threadUtils = threadUtils;
80     }
81
82     /**
83      * Handles fault notifications.
84      */
85     public Boolean handleFaultNotification(List<FaultEvent> fmNotification) {
86
87         log.info("Handling Fault notification");
88         log.info("fm notification {}", fmNotification);
89         
90         Set<String> cellIds = new HashSet<>();
91         List<ClusterDetails> clusterDetails = clusterUtils.getAllClusters();
92         String networkId = "";
93         Map<String, ArrayList<Integer>> collisionConfusionMap = new HashMap<>();
94
95         for (FaultEvent faultEvent : fmNotification) {
96             String cellId = faultEvent.getEvent().getCommonEventHeader().getSourceName();
97             cellIds.add(cellId);
98             networkId = faultEvent.getEvent().getFaultFields().getAlarmAdditionalInformation().getNetworkId();
99             ArrayList<Integer> counts = new ArrayList<>();
100             counts.add(faultEvent.getEvent().getFaultFields().getAlarmAdditionalInformation().getCollisions());
101             counts.add(faultEvent.getEvent().getFaultFields().getAlarmAdditionalInformation().getConfusions());
102             collisionConfusionMap.put(cellId, counts);
103         }
104         FaultNotificationtoClusterMapping faultNotificationtoClusterMapping = clusterUtils
105                 .getClustersForFmNotification(cellIds, clusterDetails);
106
107         faultNotificationtoClusterMapping.setCollisionConfusionMap(collisionConfusionMap);
108         // matching cells
109         if (faultNotificationtoClusterMapping.getCellsinCluster() != null && !faultNotificationtoClusterMapping.getCellsinCluster().isEmpty()) {
110             try {
111                 handleMatchedFmCells(faultNotificationtoClusterMapping, clusterDetails);
112             } catch (ConfigDbNotFoundException e) {
113                 log.error("Config DB Exception {}", e);
114             }
115
116         }
117         // unmatched new cells
118         if (faultNotificationtoClusterMapping.getNewCells() != null && !faultNotificationtoClusterMapping.getNewCells().isEmpty()) {
119             handleUnmatchedFmCells(faultNotificationtoClusterMapping, networkId);
120
121         }
122
123         return true;
124     }
125
126     /**
127      * handle matched fm cells.
128      * 
129      */
130     private void handleMatchedFmCells(FaultNotificationtoClusterMapping faultNotificationtoClusterMapping,
131             List<ClusterDetails> clusterDetails) throws ConfigDbNotFoundException {
132         Map<String, String> cellsinCluster = faultNotificationtoClusterMapping.getCellsinCluster();
133         log.info("Handling Matching cells for FM notification");
134
135         for (Entry<String, String> entry : cellsinCluster.entrySet()) {
136
137             String cellId = entry.getKey();
138             String clusterId = entry.getValue();
139             Map<CellPciPair, ArrayList<CellPciPair>> clusterMap = clusterUtils.findClusterMap(cellId);
140
141             Either<ClusterDetails, Integer> clusterDetail = clusterUtils.getClusterDetailsFromClusterId(clusterId,
142                     clusterDetails);
143
144             if (clusterDetail.isRight()) {
145                 log.error("Cannot find the cluster for Cluster ID");
146                 return;
147             } else {
148                 long threadId = clusterDetail.left().value().getChildThreadId();
149
150                 if (childStatus.get(threadId).equals("triggeredOof")) {
151                     log.info("OOF triggered for the cluster, buffering notification");
152                     bufferNotification(clusterMap, clusterId);
153                 } else {
154                     childThreadMap.get(threadId).putInQueue(clusterMap);
155                 }
156             }
157         }
158
159     }
160
161     /**
162      * handle unmatched fm cells.
163      * 
164      * @param networkId2
165      * @param faultNotificationtoClusterMapping
166      */
167     private void handleUnmatchedFmCells(FaultNotificationtoClusterMapping faultNotificationtoClusterMapping,
168             String networkId) {
169         List<String> newCells = faultNotificationtoClusterMapping.getNewCells();
170         log.info("Handle Unmatching cells for FM notificatins newCells{}", newCells);
171         List<Graph> newClusters = new ArrayList<>();
172
173         for (String cellId : newCells) {
174             ArrayList<Integer> collisionConfusionCount = faultNotificationtoClusterMapping.getCollisionConfusionMap()
175                     .get(cellId);
176             log.info("Handle Unmatching cells for FM notificatins,collisionConfusionCount{}", collisionConfusionCount);
177
178             Either<Graph, Integer> existingCluster = clusterUtils.getClusterForFMCell(cellId, newClusters);
179             if (existingCluster.isRight()) {
180                 try {
181                     Map<CellPciPair, ArrayList<CellPciPair>> clusterMap = clusterUtils.findClusterMap(cellId);
182                     Graph cluster = clusterUtils.createCluster(clusterMap);
183                     cluster.setNetworkId(networkId);
184                     Map<String, ArrayList<Integer>> collisionConfusionMap = new HashMap<>();
185                     collisionConfusionMap.put(cellId, collisionConfusionCount);
186                     cluster.setCollisionConfusionMap(collisionConfusionMap);
187
188                     newClusters.add(cluster);
189                 } catch (ConfigDbNotFoundException e) {
190                     log.error("Error connecting with configDB {}", e);
191                 }
192             }
193
194             else {
195                 Graph cluster = existingCluster.left().value();
196
197                 Graph modifiedCluster = null;
198                 try {
199                     modifiedCluster = clusterUtils.modifyCluster(cluster, clusterUtils.findClusterMap(cellId));
200                     Map<String, ArrayList<Integer>> collisionConfusionMap = cluster.getCollisionConfusionMap();
201                     collisionConfusionMap.put(cellId, collisionConfusionCount);
202                     cluster.setCollisionConfusionMap(collisionConfusionMap);
203                 } catch (ConfigDbNotFoundException e) {
204                     log.error("Config DB not found {}", e);
205                 }
206                 newClusters.remove(cluster);
207                 newClusters.add(modifiedCluster);
208             }
209
210         }
211
212         // create new child thread
213         log.info("New clusters {}", newClusters);
214
215         threadUtils.createNewThread(newClusters, childStatusQueue, pool, this, null);
216
217     }
218
219     /**
220      * handle sdnr notification.
221      */
222     public Boolean handleSdnrNotification(Notification notification) {
223         // Check if notification matches with a cluster
224         log.info("Handling SDNR notification");
225         try {
226             List<ClusterDetails> clusterDetails = clusterUtils.getAllClusters();
227
228             NotificationToClusterMapping mapping = clusterUtils.getClustersForNotification(notification,
229                     clusterDetails);
230
231             // Matching cells
232             if (mapping.getCellsinCluster() != null) {
233                 handleMatchingCells(mapping.getCellsinCluster(), clusterDetails);
234             }
235
236             // unmatched cells
237             if (mapping.getNewCells() != null) {
238                 handleUnMatchingCells(mapping.getNewCells());
239             }
240         } catch (Exception e) {
241             log.error("Exception in sdnr notification handling {}", e);
242             return false;
243         }
244
245         return true;
246
247     }
248
249     private void handleUnMatchingCells(List<FapServiceList> newCells) throws ConfigDbNotFoundException {
250
251         log.info("handling unmatched cells");
252
253         List<Graph> newClusters = new ArrayList<>();
254
255         for (FapServiceList fapService : newCells) {
256
257             Map<CellPciPair, ArrayList<CellPciPair>> clusterMap = clusterUtils.findClusterMap(fapService.getAlias());
258             Either<Graph, Integer> existingCluster = clusterUtils.getClusterForCell(fapService, newClusters);
259             if (existingCluster.isRight()) {
260                 try {
261                     Graph cluster = clusterUtils.createCluster(clusterMap);
262                     cluster.setNetworkId(fapService.getCellConfig().getLte().getRan().getNeighborListInUse()
263                             .getLteNeighborListInUseLteCell().get(0).getPlmnid());
264                     cluster.setCollisionConfusionMap(new HashMap<>());
265                     newClusters.add(cluster);
266                 } catch (ConfigDbNotFoundException e) {
267                     log.error("Error connecting with configDB {}", e);
268                 }
269             }
270
271             else {
272                 Graph cluster = existingCluster.left().value();
273                 Graph modifiedCluster = clusterUtils.modifyCluster(cluster,
274                         clusterUtils.findClusterMap(fapService.getAlias()));
275                 newClusters.remove(cluster);
276                 newClusters.add(modifiedCluster);
277             }
278
279         }
280
281         // create new child thread
282
283         threadUtils.createNewThread(newClusters, childStatusQueue, pool, this, null);
284
285     }
286
287     private void handleMatchingCells(Map<FapServiceList, String> cellsInCluster, List<ClusterDetails> clusterDetails)
288             throws ConfigDbNotFoundException {
289
290         log.info("handling matching cells");
291
292         for (Entry<FapServiceList, String> entry : cellsInCluster.entrySet()) {
293
294             FapServiceList fapService = entry.getKey();
295             String clusterId = entry.getValue();
296             String cellId = fapService.getAlias();
297             int pci = fapService.getX0005b9Lte().getPhyCellIdInUse();
298             ArrayList<CellPciPair> neighbours = new ArrayList<>();
299             for (LteNeighborListInUseLteCell neighbour : fapService.getCellConfig().getLte().getRan()
300                     .getNeighborListInUse().getLteNeighborListInUseLteCell()) {
301                 String neighbourCellId = neighbour.getAlias();
302                 int neighbourPci = neighbour.getPhyCellId();
303                 neighbours.add(new CellPciPair(neighbourCellId, neighbourPci));
304
305             }
306             Map<CellPciPair, ArrayList<CellPciPair>> clusterMap = new HashMap<>();
307             clusterMap.put(new CellPciPair(cellId, pci), neighbours);
308
309             Either<ClusterDetails, Integer> clusterDetail = clusterUtils.getClusterDetailsFromClusterId(clusterId,
310                     clusterDetails);
311
312             if (clusterDetail.isRight()) {
313                 log.error("Cannot find the cluster for Cluster ID");
314                 return;
315             } else {
316                 long threadId = clusterDetail.left().value().getChildThreadId();
317
318                 if (childStatus.get(threadId).equals("triggeredOof")) {
319                     log.info("OOF triggered for the cluster, buffering notification");
320
321                     bufferNotification(clusterMap, clusterId);
322                 } else {
323                     log.info("Forwarding notification to child thread {}", threadId);
324                     childThreadMap.get(threadId).putInQueue(clusterMap);
325                 }
326             }
327         }
328     }
329
330     private void bufferNotification(Map<CellPciPair, ArrayList<CellPciPair>> clusterMap, String clusterId) {
331
332         log.info("Buffering notifications ...");
333         ObjectMapper mapper = new ObjectMapper();
334         String serviceListString = "";
335
336         ClusterMap clusterMapJson = new ClusterMap();
337
338         clusterMapJson.setCell(clusterMap.keySet().iterator().next());
339         clusterMapJson.setNeighbourList(clusterMap.get(clusterMap.keySet().iterator().next()));
340
341         try {
342             serviceListString = mapper.writeValueAsString(clusterMapJson);
343         } catch (JsonProcessingException e) {
344             log.error("JSON processing exception: {}", e);
345         }
346         BufferNotificationComponent bufferNotifComponent = new BufferNotificationComponent();
347         bufferNotifComponent.bufferNotification(serviceListString, clusterId);
348
349     }
350
351     /**
352      * handle child status update.
353      */
354     public void handleChildStatusUpdate(List<String> childStatus) {
355
356         log.info("Handling child status update");
357
358         Long childThreadId = Long.parseLong(childStatus.get(0));
359         addChildStatus(childThreadId, childStatus.get(1));
360
361         // if child status is OOF result success, handle buffered notifications
362         if (childStatus.get(1).equals("done")) {
363             deleteChildStatus(childThreadId);
364         }
365         // else kill the child thread
366
367     }
368
369     public static void addChildThreadMap(Long childThreadId, ChildThread child) {
370         childThreadMap.put(childThreadId, child);
371     }
372
373     public static Map<Long, ChildThread> getChildThreadMap() {
374         return childThreadMap;
375     }
376
377     public void addChildStatus(Long threadId, String status) {
378         this.childStatus.put(threadId, status);
379     }
380
381     public String getChildStatus(Long threadId) {
382         return childStatus.get(threadId);
383
384     }
385
386     public void deleteChildStatus(Long childThreadId) {
387         this.childStatus.remove(childThreadId);
388
389     }
390
391     public ExecutorService getPool() {
392         return pool;
393     }
394
395 }