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