Use Java declarations instead of Google Collections
[netvirt.git] / vpnservice / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / netvirt / bgpmanager / oam / BgpCounters.java
1 /*
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.bgpmanager.oam;
10
11 import javax.management.JMException;
12 import javax.management.MBeanServer;
13 import javax.management.ObjectName;
14 import java.io.BufferedReader;
15 import java.io.BufferedWriter;
16 import java.io.File;
17 import java.io.FileWriter;
18 import java.io.IOException;
19 import java.io.InputStreamReader;
20 import java.io.PrintWriter;
21 import java.lang.management.ManagementFactory;
22 import java.net.Socket;
23 import java.net.SocketException;
24 import java.net.SocketTimeoutException;
25 import java.net.UnknownHostException;
26 import java.util.ArrayList;
27 import java.util.Date;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Scanner;
33 import java.util.TimerTask;
34 import java.util.regex.Matcher;
35 import java.util.regex.Pattern;
36 import org.opendaylight.netvirt.bgpmanager.BgpManager;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40
41 /**
42  * Created by ECHIAPT on 8/4/2015.
43  */
44 public class BgpCounters extends TimerTask {
45
46     private static final Logger LOGGER = LoggerFactory.getLogger(BgpCounters.class);
47     public static BgpCountersBroadcaster bgpStatsBroadcaster = null;
48     public MBeanServer bgpStatsServer = null;
49     public  Map <String, String> countersMap = new HashMap<String, String>();
50     private String bgpSdncMip = "127.0.0.1";
51
52     public BgpCounters(String mipAddress) {
53         bgpSdncMip = mipAddress;
54     }
55
56     @Override
57     public void run () {
58         try {
59             LOGGER.debug("Fetching counters from BGP");
60             resetCounters();
61             fetchCmdOutputs("cmd_ip_bgp_summary.txt","show ip bgp summary");
62             fetchCmdOutputs("cmd_bgp_ipv4_unicast_statistics.txt", "show bgp ipv4 unicast statistics");
63             fetchCmdOutputs("cmd_ip_bgp_vpnv4_all.txt", "show ip bgp vpnv4 all");
64             parse_ip_bgp_summary();
65             parse_bgp_ipv4_unicast_statistics();
66             parse_ip_bgp_vpnv4_all();
67             if (LOGGER.isDebugEnabled()) {
68                 dumpCounters();
69             }
70             if (bgpStatsBroadcaster == null) {
71                 //First time execution
72                 try {
73                     bgpStatsBroadcaster = new BgpCountersBroadcaster();
74                     bgpStatsServer = ManagementFactory.getPlatformMBeanServer();
75                     ObjectName bgpStatsObj = new ObjectName("SDNC.PM:type=BgpCountersBroadcaster");
76                     bgpStatsServer.registerMBean(bgpStatsBroadcaster, bgpStatsObj);
77                     LOGGER.info("BGP Counters MBean Registered :::");
78                 } catch (JMException e) {
79                     LOGGER.error("Adding a NotificationBroadcaster failed." , e);
80                     return;
81                 }
82             }
83             bgpStatsBroadcaster.setBgpCountersMap(countersMap);
84             LOGGER.debug("Finished updating the counters from BGP");
85         } catch (Exception e) {
86             LOGGER.error("Failed to publish bgp counters ", e);
87         }
88     }
89
90     public void dumpCounters () {
91         for (Map.Entry<String, String> entry : countersMap.entrySet()) {
92             LOGGER.debug("{}, Value = {}", entry.getKey(), entry.getValue());
93         }
94     }
95
96     public void fetchCmdOutputs (String filename, String cmdName) throws  IOException  {
97         Socket socket;
98         int serverPort = 2605;
99         String serverName = bgpSdncMip;
100         int sockTimeout = 2;
101         PrintWriter out_to_socket;
102         BufferedReader in_from_socket;
103         char cbuf[] = new char[10];
104         char op_buf[];
105         StringBuilder sb = new StringBuilder();
106         int ip, ret;
107         StringBuilder temp;
108         char ch, gt = '>', hash = '#';
109         String vtyPassword = BgpConstants.QBGP_VTY_PASSWORD;
110         String passwordCheckStr = "Password:";
111         String enableString = "en";
112         String prompt, replacedStr;
113
114         try
115         {
116             socket = new Socket(serverName, serverPort);
117
118         }
119         catch (UnknownHostException ioe) {
120             LOGGER.error("No host exists: " + ioe.getMessage());
121             return;
122         }
123         catch (IOException ioe) {
124             LOGGER.error("I/O error occured " + ioe.getMessage());
125             return;
126         }
127         try {
128             socket.setSoTimeout(sockTimeout*1000);
129             out_to_socket = new PrintWriter(socket.getOutputStream(), true);
130             in_from_socket = new BufferedReader(new InputStreamReader(socket.getInputStream()));
131
132         } catch (IOException ioe) {
133             LOGGER.error("IOException thrown.");
134             socket.close();
135             return;
136         }
137         while (true) {
138             try {
139                 ret = in_from_socket.read(cbuf);
140             }
141             catch (SocketTimeoutException ste) {
142                 LOGGER.error("Read from Socket timed Out while asking for password.");
143                 socket.close();
144                 return;
145             }
146             catch (IOException ioe) {
147                 LOGGER.error("Caught IOException");
148                 socket.close();
149                 return;
150             }
151             if (ret == -1) {
152                 LOGGER.error("Connection closed by BGPd.");
153                 socket.close();
154                 return;
155             } else {
156                 sb.append(cbuf);
157                 if (sb.toString().contains(passwordCheckStr)) {
158                     break;
159                 }
160             }
161         }
162
163         sb.setLength(0);
164         out_to_socket.println(vtyPassword);
165
166         while (true) {
167             try {
168                 ip = in_from_socket.read();
169             }
170             catch (SocketTimeoutException ste) {
171                 LOGGER.error(sb.toString());
172                 LOGGER.error("Read from Socket timed Out while verifying the password.");
173                 socket.close();
174                 return;
175             }
176             if (ip == (int)gt || ip == (int)hash) {
177                 break;
178             } else if (ip == -1) {
179                 LOGGER.error(sb.toString());
180                 LOGGER.error("Connection closed by BGPd.");
181                 socket.close();
182                 return;
183             } else {
184                 ch = (char)ip;
185                 sb.append(ch);
186
187             }
188         }
189
190         prompt = sb.toString();
191         prompt = prompt.trim();
192         sb.setLength(0);
193         out_to_socket.println(enableString);
194
195         while (true) {
196             try {
197                 ip = in_from_socket.read();
198             }
199             catch (SocketTimeoutException ste) {
200                 LOGGER.error(sb.toString());
201                 LOGGER.error("Read from Socket timed Out while keying the en keyword.");
202                 socket.close();
203                 return;
204             }
205             if (ip == (int)hash) {
206                 break;
207             } else if (ip == -1) {
208                 LOGGER.error(sb.toString());
209                 LOGGER.error("Connection closed by BGPd.");
210                 socket.close();
211                 return;
212             } else {
213                 ch = (char)ip;
214                 sb.append(ch);
215
216             }
217         }
218         sb.setLength(0);
219         temp = new StringBuilder();
220         File file;
221         FileWriter fileWritter;
222         BufferedWriter bufferWritter;
223
224         try {
225             file = new File(filename);
226             if (!file.exists()) {
227                 file.createNewFile();
228             }
229             fileWritter = new FileWriter(file.getName(), true);
230             bufferWritter = new BufferedWriter(fileWritter);
231         } catch (IOException e) {
232             return;
233         }
234         out_to_socket.println(cmdName);
235         temp.setLength(0);
236         while (true) {
237             try {
238                 op_buf = new char[100];
239                 ret = in_from_socket.read(op_buf);
240
241             } catch (SocketTimeoutException ste) {
242                 break;
243             } catch (SocketException soc) {
244                 break;
245             } catch (IOException ioe) {
246                 ioe.printStackTrace();
247                 break;
248             }
249
250             if (ret == -1) {
251                 break;
252             }
253             temp.append(op_buf);
254         }
255         String outputStr = temp.toString();
256         StringBuffer output = new StringBuffer();
257
258         outputStr.replaceAll("^\\s+|\\s+$", "");
259         output.append(outputStr);
260         if (output.toString().trim().contains(prompt)) {
261             int index = output.toString().lastIndexOf(prompt);
262             String newString = output.toString().substring(0, index);
263             output.setLength(0);
264             output.append(newString);
265         }
266         try {
267             bufferWritter.write(output.toString().trim());
268             temp.setLength(0);
269         } catch (IOException e) {
270             e.printStackTrace();
271             return;
272         }
273         try {
274             bufferWritter.close();
275             fileWritter.close();
276             socket.close();
277
278         } catch (IOException e) {
279             e.printStackTrace();
280             return;
281         }
282     }
283
284     public static boolean validate(final String ip){
285         if (ip == null || ip.equals("")) {
286             return false;
287         }
288         final String PATTERN =
289                 "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
290         Pattern pattern = Pattern.compile(PATTERN);
291         Matcher matcher = pattern.matcher(ip);
292         return matcher.matches();
293     }
294
295
296     /*
297      * The below function parses the output of "show ip bgp summary" saved in a file.
298      * Below is the snippet for the same :-
299         <output>
300         BGP router identifier 10.183.254.53, local AS number 101
301         .....
302         Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
303         10.183.254.76   4   100       3       4        0    0    0 00:01:27        0
304         .........
305         Total number of neighbors 1
306         </output>
307      */
308
309     public void parse_ip_bgp_summary() {
310         File file = new File("cmd_ip_bgp_summary.txt");
311         Scanner scanner;
312         String lineFromFile;
313         List<String> inputStrs = new ArrayList<String>();
314         int i = 0;
315         String as,rx, tx;
316         boolean startEntries = false;
317         String[] result;
318         String StrIP;
319
320         try {
321             scanner = new Scanner(file);
322         } catch (IOException e) {
323             LOGGER.error("Could not process the file " + file.getAbsolutePath());
324             return ;
325         }
326         while (scanner.hasNextLine()) {
327
328             lineFromFile = scanner.nextLine();
329             inputStrs.add(lineFromFile);
330         }
331         String str;
332         StringBuilder NbrInfoKey = new StringBuilder();
333
334         while (i < inputStrs.size()) {
335             str = inputStrs.get(i);
336             if (str.contains("State/PfxRcd")) {
337                 startEntries = true;
338             } else if (startEntries == true) {
339                 result = str.split("\\s+");
340                try {
341                     StrIP = result[0].trim();
342                     if (!validate(StrIP)) {
343                         return;
344                     }
345                     as = result[2];
346                     rx = result[3];
347                     tx = result[4];
348
349                     NbrInfoKey.setLength(0);
350                     NbrInfoKey.append(BgpConstants.BGP_COUNTER_NBR_PKTS_RX).append(":").
351                            append("BGP_Nbr_IP_").append(StrIP).append("_AS_").append(as).append("_PktsReceived");
352                     countersMap.put(NbrInfoKey.toString(), rx);
353
354
355                     NbrInfoKey.setLength(0);
356                     NbrInfoKey.append(BgpConstants.BGP_COUNTER_NBR_PKTS_TX).append(":").
357                            append("BGP_Nbr_IP_").append(StrIP).append("_AS_").append(as).append("_PktsSent");
358                     countersMap.put(NbrInfoKey.toString(), tx);
359                 } catch (Exception e) {
360                     return;
361                 }
362             }
363             i++;
364         }
365  }
366     /*
367      * The below function parses the output of "show bgp ipv4 unicast statistics" saved in a file.
368      * Below is the sample output for the same :-
369         <output>
370         BGP IPv4 Unicast RIB statistics
371         ...
372         Total Prefixes                :            8
373         ......
374         </output>
375      */
376
377     public void parse_bgp_ipv4_unicast_statistics() {
378        File file = new File("cmd_bgp_ipv4_unicast_statistics.txt");
379        Scanner scanner;
380        String lineFromFile;
381        StringBuilder key = new StringBuilder();
382        String totPfx = "";
383        List<String> inputStrs = new ArrayList<String>();
384        try {
385            scanner = new Scanner(file);
386        } catch (IOException e) {
387            System.err.println("Could not process the file " + file.getAbsolutePath());
388            return ;
389        }
390        while (scanner.hasNextLine()) {
391
392            lineFromFile = scanner.nextLine();
393            inputStrs.add(lineFromFile);
394        }
395
396        int i = 0;
397        String instr;
398        while (i < inputStrs.size()) {
399            instr = inputStrs.get(i);
400            if (instr.contains("Total Prefixes")) {
401                String[] result = instr.split(":");
402                try {
403                    totPfx = result[1].trim();
404                } catch (Exception e) {
405                    totPfx = "0";
406                }
407                break;
408            }
409            i++;
410        }
411         key.setLength(0);
412         key.append(BgpConstants.BGP_COUNTER_TOTAL_PFX).append(":").
413                 append("Bgp_Total_Prefixes");
414         countersMap.put(key.toString(), totPfx);
415     }
416
417     /*
418      *  The below function parses the output of "show ip bgp vpnv4 all" saved in a file.
419      *  Below is the sample output for the same :-
420      *  show ip bgp vpnv4 all
421         <output>
422         BGP table version is 0, local router ID is 10.183.181.21
423         ......
424         Route Distinguisher: 100:1
425         *>i15.15.15.15/32   10.183.181.25            0    100      0 ?
426         *>i17.18.17.17/32   10.183.181.25            0    100      0 ?
427         *>i17.18.17.17/32   10.183.181.25            0    100      0 ?
428         *>i17.18.17.17/32   10.183.181.25            0    100      0 ?
429         Route Distinguisher: 100:2
430         *>i16.16.16.16/32   10.183.181.25            0    100      0 ?
431         *>i18.18.18.18/32   10.183.181.25            0    100      0 ?
432         *>i17.18.17.17/32   10.183.181.25            0    100      0 ?
433         </output>
434      */
435     public void parse_ip_bgp_vpnv4_all() {
436         File file = new File("cmd_ip_bgp_vpnv4_all.txt");
437         Scanner scanner;
438         String lineFromFile;
439         List<String> inputStrs = new ArrayList<String>();
440
441         try {
442             scanner = new Scanner(file);
443         } catch (IOException e) {
444             System.err.println("Could not process the file " + file.getAbsolutePath());
445             return ;
446         }
447         while (scanner.hasNextLine()) {
448             lineFromFile = scanner.nextLine();
449             inputStrs.add(lineFromFile);
450         }
451         int i = 0;
452         String instr, rd;
453         while (i < inputStrs.size()) {
454             instr = inputStrs.get(i);
455             if (instr.contains("Route Distinguisher")) {
456                 String[] result = instr.split(":");
457                 rd = result[1].trim() + "_" + result[2].trim();
458                 i = processRouteCount(rd, i + 1,  inputStrs);
459
460             }
461             i++;
462         }
463
464     }
465
466     public int processRouteCount(String rd, int startIndex, List<String> inputStrs) {
467         int num = startIndex, route_count = 0;
468         String str;
469         StringBuilder key = new StringBuilder();
470         str = inputStrs.get(num);
471
472         while (str != null && !str.trim().equals("") &&
473                 num <inputStrs.size()) {
474             if (str.contains("Route Distinguisher")) {
475                 key.setLength(0);
476                 key.append(BgpConstants.BGP_COUNTER_RD_ROUTE_COUNT).append(":").
477                         append("BGP_RD_").append(rd).append("_route_count");
478                 countersMap.put(key.toString(), Integer.toString(route_count));
479                 return num - 1;
480             }
481             route_count++;
482             num++;
483             if (num == inputStrs.size()) {
484                 break;
485             }
486             str = inputStrs.get(num);
487         }
488         if (route_count == 0) {
489             // Erroneous condition, should never happen.
490             // Implies that the file contains marker for RD  without routes.
491             // will form an infinite loop if not broken
492             // by sending a big number back.
493             return ~0;
494         }
495         key.setLength(0);
496         key.append(BgpConstants.BGP_COUNTER_RD_ROUTE_COUNT).append(":").
497                 append("BGP_RD_").append(rd).append("_route_count");
498         countersMap.put(key.toString(), Integer.toString(route_count));
499         return num - 1;
500     }
501
502     public void resetCounters() {
503         countersMap.clear();
504         resetFile("cmd_ip_bgp_summary.txt");
505         resetFile("cmd_bgp_ipv4_unicast_statistics.txt");
506         resetFile("cmd_ip_bgp_vpnv4_all.txt");
507     }
508
509     public static void resetFile(String fileName) {
510         File fileHndl = (new File(fileName));
511         PrintWriter writer;
512         boolean success;
513
514         success = fileHndl.delete();
515         if (!success) {
516             try {
517                 writer = new PrintWriter(fileHndl);
518                 writer.print("");
519                 writer.close();
520             } catch (Exception e) {
521                 return;
522             }
523         }
524
525     }
526
527     public static Map<String, String> parse_ip_bgp_vpnv4_all_summary(Map<String, String> countMap) {
528         File file = new File("cmd_ip_bgp_vpnv4_all_summary.txt");
529         Scanner scanner;
530         String lineFromFile;
531         List<String> inputStrs = new ArrayList<String>();
532         int i = 0;
533         boolean startEntries = false;
534         String[] result;
535         String StrIP;
536
537         try {
538             scanner = new Scanner(file);
539         } catch (IOException e) {
540             LOGGER.trace("Could not process the file " + file.getAbsolutePath());
541             return null;
542         }
543         while (scanner.hasNextLine()) {
544
545             lineFromFile = scanner.nextLine();
546             inputStrs.add(lineFromFile);
547         }
548         String str;
549         while (i < inputStrs.size()) {
550             str = inputStrs.get(i);
551             LOGGER.trace("str is:: {}", str);
552             if (str.contains("State/PfxRcd")) {
553                 startEntries = true;
554             } else if (startEntries == true) {
555                 result = str.split("\\s+");
556                 try {
557                     StrIP = result[0].trim();
558                     LOGGER.trace("strIP " + StrIP);
559
560                     if (!validate(StrIP)) {
561                         break;
562                     }
563                     String state_pfxRcvd = result[9];
564                     countMap.put(StrIP, state_pfxRcvd);
565                 } catch (Exception e) {
566                     LOGGER.trace("Exception {} caught while processing ip bgp vpnv4 all summary command output, e");
567                     i++;
568                     continue;
569                 }
570             }
571             i++;
572         }
573         return countMap;
574     }
575
576 }