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