b14c8fc598eb1b72fc2e86ad6cae03c767d32aee
[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 == -1) {
138                 LOGGER.error("Connection closed by BGPd.");
139                 socket.close();
140                 return;
141             } else {
142                 sb.append(cbuf);
143                 if (sb.toString().contains(passwordCheckStr)) {
144                     break;
145                 }
146             }
147         }
148
149         sb.setLength(0);
150         out_to_socket.println(vtyPassword);
151
152         while (true) {
153             try {
154                 ip = in_from_socket.read();
155             }
156             catch (SocketTimeoutException ste) {
157                 LOGGER.error(sb.toString());
158                 LOGGER.error("Read from Socket timed Out while verifying the password.");
159                 socket.close();
160                 return;
161             }
162             if (ip == (int)gt) {
163                 break;
164             } else if (ip == -1) {
165                 LOGGER.error(sb.toString());
166                 LOGGER.error("Connection closed by BGPd.");
167                 socket.close();
168                 return;
169             } else {
170                 ch = (char)ip;
171                 sb.append(ch);
172
173             }
174         }
175
176         prompt = sb.toString();
177         prompt = prompt.trim();
178         sb.setLength(0);
179         out_to_socket.println(enableString);
180
181         while (true) {
182             try {
183                 ip = in_from_socket.read();
184             }
185             catch (SocketTimeoutException ste) {
186                 LOGGER.error(sb.toString());
187                 LOGGER.error("Read from Socket timed Out while keying the en keyword.");
188                 socket.close();
189                 return;
190             }
191             if (ip == (int)hash) {
192                 break;
193             } else if (ip == -1) {
194                 LOGGER.error(sb.toString());
195                 LOGGER.error("Connection closed by BGPd.");
196                 socket.close();
197                 return;
198             } else {
199                 ch = (char)ip;
200                 sb.append(ch);
201
202             }
203         }
204         sb.setLength(0);
205         temp = new StringBuilder();
206         File file;
207         FileWriter fileWritter;
208         BufferedWriter bufferWritter;
209
210         try {
211             file = new File(filename);
212             if (!file.exists()) {
213                 file.createNewFile();
214             }
215             fileWritter = new FileWriter(file.getName(), true);
216             bufferWritter = new BufferedWriter(fileWritter);
217         } catch (IOException e) {
218             return;
219         }
220         out_to_socket.println(cmdName);
221         temp.setLength(0);
222         while (true) {
223             try {
224                 op_buf = new char[100];
225                 ret = in_from_socket.read(op_buf);
226
227             } catch (SocketTimeoutException ste) {
228                 break;
229             } catch (SocketException soc) {
230                 break;
231             } catch (IOException ioe) {
232                 ioe.printStackTrace();
233                 break;
234             }
235
236             if (ret == -1) {
237                 break;
238             }
239             temp.append(op_buf);
240         }
241         String outputStr = temp.toString();
242         StringBuffer output = new StringBuffer();
243
244         outputStr.replaceAll("^\\s+|\\s+$", "");
245         output.append(outputStr);
246         if (output.toString().trim().contains(prompt)) {
247             int index = output.toString().lastIndexOf(prompt);
248             String newString = output.toString().substring(0, index);
249             output.setLength(0);
250             output.append(newString);
251         }
252         try {
253             bufferWritter.write(output.toString().trim());
254             temp.setLength(0);
255         } catch (IOException e) {
256             e.printStackTrace();
257             return;
258         }
259         try {
260             bufferWritter.close();
261             fileWritter.close();
262             socket.close();
263
264         } catch (IOException e) {
265             e.printStackTrace();
266             return;
267         }
268     }
269
270     public boolean validate(final String ip){
271         if (ip == null || ip.equals("")) {
272             return false;
273         }
274         final String PATTERN =
275                 "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
276         Pattern pattern = Pattern.compile(PATTERN);
277         Matcher matcher = pattern.matcher(ip);
278         return matcher.matches();
279     }
280
281
282     /*
283      * The below function parses the output of "show ip bgp summary" saved in a file.
284      * Below is the snippet for the same :-
285         <output>
286         BGP router identifier 10.183.254.53, local AS number 101
287         .....
288         Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
289         10.183.254.76   4   100       3       4        0    0    0 00:01:27        0
290         .........
291         Total number of neighbors 1
292         </output>
293      */
294
295     public void parse_ip_bgp_summary() {
296         File file = new File("cmd_ip_bgp_summary.txt");
297         Scanner scanner;
298         String lineFromFile;
299         List<String> inputStrs = new ArrayList<String>();
300         int i = 0;
301         String as,rx, tx;
302         boolean startEntries = false;
303         String[] result;
304         String StrIP;
305
306         try {
307             scanner = new Scanner(file);
308         } catch (IOException e) {
309             LOGGER.error("Could not process the file " + file.getAbsolutePath());
310             return ;
311         }
312         while (scanner.hasNextLine()) {
313
314             lineFromFile = scanner.nextLine();
315             inputStrs.add(lineFromFile);
316         }
317         String str;
318         StringBuilder NbrInfoKey = new StringBuilder();
319
320         while (i < inputStrs.size()) {
321             str = inputStrs.get(i);
322             if (str.contains("State/PfxRcd")) {
323                 startEntries = true;
324             } else if (startEntries == true) {
325                 result = str.split("\\s+");
326                try {
327                     StrIP = result[0].trim();
328                     if (!validate(StrIP)) {
329                         return;
330                     }
331                     as = result[2];
332                     rx = result[3];
333                     tx = result[4];
334
335                     NbrInfoKey.setLength(0);
336                     NbrInfoKey.append(BgpConstants.BGP_COUNTER_NBR_PKTS_RX).append(":").
337                            append("BGP_Nbr_IP_").append(StrIP).append("_AS_").append(as).append("_PktsReceived");
338                     countersMap.put(NbrInfoKey.toString(), rx);
339
340
341                     NbrInfoKey.setLength(0);
342                     NbrInfoKey.append(BgpConstants.BGP_COUNTER_NBR_PKTS_TX).append(":").
343                            append("BGP_Nbr_IP_").append(StrIP).append("_AS_").append(as).append("_PktsSent");
344                     countersMap.put(NbrInfoKey.toString(), tx);
345                 } catch (Exception e) {
346                     return;
347                 }
348             }
349             i++;
350         }
351  }
352     /*
353      * The below function parses the output of "show bgp ipv4 unicast statistics" saved in a file.
354      * Below is the sample output for the same :-
355         <output>
356         BGP IPv4 Unicast RIB statistics
357         ...
358         Total Prefixes                :            8
359         ......
360         </output>
361      */
362
363     public void parse_bgp_ipv4_unicast_statistics() {
364        File file = new File("cmd_bgp_ipv4_unicast_statistics.txt");
365        Scanner scanner;
366        String lineFromFile;
367        StringBuilder key = new StringBuilder();
368        String totPfx = "";
369        List<String> inputStrs = new ArrayList<String>();
370        try {
371            scanner = new Scanner(file);
372        } catch (IOException e) {
373            System.err.println("Could not process the file " + file.getAbsolutePath());
374            return ;
375        }
376        while (scanner.hasNextLine()) {
377
378            lineFromFile = scanner.nextLine();
379            inputStrs.add(lineFromFile);
380        }
381
382        int i = 0;
383        String instr;
384        while (i < inputStrs.size()) {
385            instr = inputStrs.get(i);
386            if (instr.contains("Total Prefixes")) {
387                String[] result = instr.split(":");
388                try {
389                    totPfx = result[1].trim();
390                } catch (Exception e) {
391                    totPfx = "0";
392                }
393                break;
394            }
395            i++;
396        }
397         key.setLength(0);
398         key.append(BgpConstants.BGP_COUNTER_TOTAL_PFX).append(":").
399                 append("Bgp_Total_Prefixes");
400         countersMap.put(key.toString(), totPfx);
401     }
402
403     /*
404      *  The below function parses the output of "show ip bgp vpnv4 all" saved in a file.
405      *  Below is the sample output for the same :-
406      *  show ip bgp vpnv4 all
407         <output>
408         BGP table version is 0, local router ID is 10.183.181.21
409         ......
410         Route Distinguisher: 100:1
411         *>i15.15.15.15/32   10.183.181.25            0    100      0 ?
412         *>i17.18.17.17/32   10.183.181.25            0    100      0 ?
413         *>i17.18.17.17/32   10.183.181.25            0    100      0 ?
414         *>i17.18.17.17/32   10.183.181.25            0    100      0 ?
415         Route Distinguisher: 100:2
416         *>i16.16.16.16/32   10.183.181.25            0    100      0 ?
417         *>i18.18.18.18/32   10.183.181.25            0    100      0 ?
418         *>i17.18.17.17/32   10.183.181.25            0    100      0 ?
419         </output>
420      */
421     public void parse_ip_bgp_vpnv4_all() {
422         File file = new File("cmd_ip_bgp_vpnv4_all.txt");
423         Scanner scanner;
424         String lineFromFile;
425         List<String> inputStrs = new ArrayList<String>();
426
427         try {
428             scanner = new Scanner(file);
429         } catch (IOException e) {
430             System.err.println("Could not process the file " + file.getAbsolutePath());
431             return ;
432         }
433         while (scanner.hasNextLine()) {
434             lineFromFile = scanner.nextLine();
435             inputStrs.add(lineFromFile);
436         }
437         int i = 0;
438         String instr, rd;
439         while (i < inputStrs.size()) {
440             instr = inputStrs.get(i);
441             if (instr.contains("Route Distinguisher")) {
442                 String[] result = instr.split(":");
443                 rd = result[1].trim() + "_" + result[2].trim();
444                 i = processRouteCount(rd, i + 1,  inputStrs);
445
446             }
447             i++;
448         }
449
450     }
451
452     public int processRouteCount(String rd, int startIndex, List<String> inputStrs) {
453         int num = startIndex, route_count = 0;
454         String str;
455         StringBuilder key = new StringBuilder();
456         str = inputStrs.get(num);
457
458         while (str != null && !str.trim().equals("") &&
459                 num <inputStrs.size()) {
460             if (str.contains("Route Distinguisher")) {
461                 key.setLength(0);
462                 key.append(BgpConstants.BGP_COUNTER_RD_ROUTE_COUNT).append(":").
463                         append("BGP_RD_").append(rd).append("_route_count");
464                 countersMap.put(key.toString(), Integer.toString(route_count));
465                 return num - 1;
466             }
467             route_count++;
468             num++;
469             if (num == inputStrs.size()) {
470                 break;
471             }
472             str = inputStrs.get(num);
473         }
474         if (route_count == 0) {
475             // Erroneous condition, should never happen.
476             // Implies that the file contains marker for RD  without routes.
477             // will form an infinite loop if not broken
478             // by sending a big number back.
479             return ~0;
480         }
481         key.setLength(0);
482         key.append(BgpConstants.BGP_COUNTER_RD_ROUTE_COUNT).append(":").
483                 append("BGP_RD_").append(rd).append("_route_count");
484         countersMap.put(key.toString(), Integer.toString(route_count));
485         return num - 1;
486     }
487
488     public void resetCounters() {
489         countersMap.clear();
490         resetFile("cmd_ip_bgp_summary.txt");
491         resetFile("cmd_bgp_ipv4_unicast_statistics.txt");
492         resetFile("cmd_ip_bgp_vpnv4_all.txt");
493     }
494
495     public void resetFile(String fileName) {
496         File fileHndl = (new File(fileName));
497         PrintWriter writer;
498         boolean success;
499
500         System.gc();
501         success = fileHndl.delete();
502         if (!success) {
503             try {
504                 writer = new PrintWriter(fileHndl);
505                 writer.print("");
506                 writer.close();
507             } catch (Exception e) {
508                 return;
509             }
510         }
511
512     }
513
514 }