Migrating BGP PM Counters to Infrautils Counters
[netvirt.git] / vpnservice / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / netvirt / bgpmanager / oam / BgpCounters.java
index cfaaca9dd99969e79b10a7091f366410909be692..7a0cf2aa9d9ecc53adae7cad85c27251510285b9 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.netvirt.bgpmanager.oam;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
@@ -16,7 +18,6 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
-import java.lang.management.ManagementFactory;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -24,36 +25,46 @@ import java.net.Socket;
 import java.net.SocketTimeoutException;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Scanner;
-import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.annotation.Nonnull;
-import javax.management.JMException;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
+import javax.inject.Inject;
 
+import org.opendaylight.infrautils.metrics.Counter;
+import org.opendaylight.infrautils.metrics.Labeled;
+import org.opendaylight.infrautils.metrics.MetricDescriptor;
+import org.opendaylight.infrautils.metrics.MetricProvider;
 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
-public class BgpCounters extends TimerTask {
-
-    private static final Logger LOG = LoggerFactory.getLogger(BgpCounters.class);
-    private static BgpCountersBroadcaster bgpStatsBroadcaster = null;
-    private MBeanServer bgpStatsServer = null;
-    private Map<String, String> countersMap = new HashMap<>();
-    private String bgpSdncMip = "127.0.0.1";
+@SuppressFBWarnings("DM_DEFAULT_ENCODING")
+public class BgpCounters implements Runnable, AutoCloseable {
     public static final String BGP_VPNV6_FILE = "cmd_ip_bgp_vpnv6_all.txt";
     public static final String BGP_VPNV4_FILE = "cmd_ip_bgp_vpnv4_all.txt";
+    public static final String BGP_EVPN_FILE = "cmd_bgp_l2vpn_evpn_all.txt";
     public static final String BGP_VPNV6_SUMMARY_FILE = "cmd_ip_bgp_vpnv6_all_summary.txt";
     public static final String BGP_VPNV4_SUMMARY_FILE = "cmd_ip_bgp_vpnv4_all_summary.txt";
+    public static final String BGP_EVPN_SUMMARY_FILE = "cmd_bgp_evpn_all_summary.txt";
+
+    private static final Logger LOG = LoggerFactory.getLogger(BgpCounters.class);
+
+    private final Map<String, String> totalPfxMap = new ConcurrentHashMap<>();
+
+    private final String bgpSdncMip;
+    private final MetricProvider metricProvider;
 
-    public BgpCounters(String mipAddress) {
-        bgpSdncMip = mipAddress;
+    @Inject
+    public BgpCounters(String mipAddress, final MetricProvider metricProvider) {
+        this.metricProvider = metricProvider;
+        this.bgpSdncMip = mipAddress;
+    }
+
+    @Override
+    public void close() {
     }
 
     @Override
@@ -65,38 +76,17 @@ public class BgpCounters extends TimerTask {
             fetchCmdOutputs("cmd_bgp_ipv4_unicast_statistics.txt", "show bgp ipv4 unicast statistics");
             fetchCmdOutputs(BGP_VPNV4_FILE, "show ip bgp vpnv4 all");
             fetchCmdOutputs(BGP_VPNV6_FILE, "show ip bgp vpnv6 all");
+            fetchCmdOutputs(BGP_EVPN_FILE, "show bgp l2vpn evpn all");
             parseIpBgpSummary();
             parseIpBgpVpnv4All();
             parseIpBgpVpnv6All();
-            if (LOG.isDebugEnabled()) {
-                dumpCounters();
-            }
-            if (bgpStatsBroadcaster == null) {
-                //First time execution
-                try {
-                    bgpStatsBroadcaster = new BgpCountersBroadcaster();
-                    bgpStatsServer = ManagementFactory.getPlatformMBeanServer();
-                    ObjectName bgpStatsObj = new ObjectName("SDNC.PM:type=BgpCountersBroadcaster");
-                    bgpStatsServer.registerMBean(bgpStatsBroadcaster, bgpStatsObj);
-                    LOG.info("BGP Counters MBean Registered :::");
-                } catch (JMException e) {
-                    LOG.error("Adding a NotificationBroadcaster failed.", e);
-                    return;
-                }
-            }
-            bgpStatsBroadcaster.setBgpCountersMap(countersMap);
+            parseBgpL2vpnEvpnAll();
             LOG.debug("Finished updating the counters from BGP");
         } catch (IOException e) {
             LOG.error("Failed to publish bgp counters ", e);
         }
     }
 
-    private void dumpCounters() {
-        for (Map.Entry<String, String> entry : countersMap.entrySet()) {
-            LOG.debug("{}, Value = {}", entry.getKey(), entry.getValue());
-        }
-    }
-
     void fetchCmdOutputs(String filename, String cmdName) throws IOException {
         try (Socket socket = new Socket(bgpSdncMip, 2605);
              PrintWriter toRouter = new PrintWriter(socket.getOutputStream(), true);
@@ -196,7 +186,7 @@ public class BgpCounters extends TimerTask {
             /*if exception is catched then the prefix is not an IPv6 and IPv4*/
             LOG.error("Unrecognized ip address ipAddress: {}", ip);
         }
-        return (identifiedAFI == afi.getValue() ? true : false);
+        return identifiedAFI == afi.getValue() ? true : false;
     }
 
     /*
@@ -234,51 +224,18 @@ public class BgpCounters extends TimerTask {
                     final String rx = result[3];
                     final String tx = result[4];
 
-                    countersMap.put(
-                            BgpConstants.BGP_COUNTER_NBR_PKTS_RX + ":BGP_Nbr_IP_" + strIp + "_AS_" + as
-                                    + "_PktsReceived",
-                            rx);
-                    countersMap.put(
-                            BgpConstants.BGP_COUNTER_NBR_PKTS_TX + ":BGP_Nbr_IP_" + strIp + "_AS_" + as + "_PktsSent",
-                            tx);
-                }
-            }
-        } catch (IOException e) {
-            LOG.error("Could not process the file {}", file.getAbsolutePath());
-        }
-    }
-    /*
-     * The below function parses the output of "show bgp ipv4 unicast statistics" saved in a file.
-     * Below is the sample output for the same :-
-        <output>
-        BGP IPv4 Unicast RIB statistics
-        ...
-        Total Prefixes                :            8
-        ......
-        </output>
-     */
+                    Counter counter = getCounter(BgpConstants.BGP_COUNTER_NBR_PKTS_RX, as,
+                            rx, null, strIp, null);
+                    updateCounter(counter, Long.parseLong(rx));
 
-    private void parseBgpIpv4UnicastStatistics() {
-        File file = new File("cmd_bgp_ipv4_unicast_statistics.txt");
-        String totPfx = "";
-        try (Scanner scanner = new Scanner(file)) {
-            while (scanner.hasNextLine()) {
-                String instr = scanner.nextLine();
-                if (instr.contains("Total Prefixes")) {
-                    String[] result = instr.split(":");
-                    if (result.length > 1) {
-                        totPfx = result[1].trim();
-                    } else {
-                        totPfx = "0";
-                    }
-                    break;
+                    counter = getCounter(BgpConstants.BGP_COUNTER_NBR_PKTS_TX, as,
+                            null, tx, strIp, null);
+                    updateCounter(counter, Long.parseLong(tx));
                 }
             }
         } catch (IOException e) {
             LOG.error("Could not process the file {}", file.getAbsolutePath());
-            return;
         }
-        countersMap.put(BgpConstants.BGP_COUNTER_TOTAL_PFX, totPfx);
     }
 
     /*
@@ -316,14 +273,9 @@ public class BgpCounters extends TimerTask {
             if (instr.contains("Route Distinguisher")) {
                 String[] result = instr.split(":");
                 String rd = result[1].trim() + "_" + result[2].trim();
-                i = processRouteCount(rd, i + 1, inputStrs);
+                i = processRouteCount(rd + "_VPNV4", i + 1, inputStrs);
             }
         }
-        /*populate the "BgpTotalPrefixes" counter by combining
-        the prefixes that are calculated per RD basis*/
-        int bgpTotalPfxs = calculateBgpTotalPrefixes();
-        LOG.trace("BGP Total Prefixes:{}",bgpTotalPfxs);
-        countersMap.put(BgpConstants.BGP_COUNTER_TOTAL_PFX,String.valueOf(bgpTotalPfxs));
     }
 
     /*
@@ -361,20 +313,54 @@ public class BgpCounters extends TimerTask {
             if (instr.contains("Route Distinguisher")) {
                 String[] result = instr.split(":");
                 String rd = result[1].trim() + "_" + result[2].trim();
-                i = processRouteCount(rd, i + 1, inputStrs);
+                i = processRouteCount(rd + "_VPNV6", i + 1, inputStrs);
             }
         }
     }
 
+    private void parseBgpL2vpnEvpnAll() {
+        File file = new File(BGP_EVPN_FILE);
+        List<String> inputStrs = new ArrayList<>();
+
+        try (Scanner scanner = new Scanner(file)) {
+            while (scanner.hasNextLine()) {
+                inputStrs.add(scanner.nextLine());
+            }
+        } catch (IOException e) {
+            LOG.error("Could not process the file {}", file.getAbsolutePath());
+            return;
+        }
+        for (int i = 0; i < inputStrs.size(); i++) {
+            String instr = inputStrs.get(i);
+            if (instr.contains("Route Distinguisher")) {
+                String[] result = instr.split(":");
+                String rd = result[1].trim() + "_" + result[2].trim();
+                i = processRouteCount(rd + "_EVPN", i + 1, inputStrs);
+            }
+        }
+        /*populate the "BgpTotalPrefixes" counter by combining
+        the prefixes that are calculated per RD basis*/
+        long bgpTotalPfxs = calculateBgpTotalPrefixes();
+        LOG.trace("BGP Total Prefixes:{}",bgpTotalPfxs);
+        Counter counter = getCounter(BgpConstants.BGP_COUNTER_TOTAL_PFX, null, null, null,
+                null, null);
+        updateCounter(counter, bgpTotalPfxs);
+    }
+
     private int processRouteCount(String rd, int startIndex, List<String> inputStrs) {
         int num = startIndex;
-        int routeCount = 0;
-        String key = BgpConstants.BGP_COUNTER_RD_ROUTE_COUNT + ":BGP_RD_" + rd + "_route_count";
+        long routeCount = 0;
+
+        String bgpRdRouteCountKey = BgpConstants.BGP_COUNTER_RD_ROUTE_COUNT + rd;
+        Counter counter = getCounter(BgpConstants.BGP_COUNTER_RD_ROUTE_COUNT, null, null, null,
+                null, rd);
 
-        for (String str = inputStrs.get(num); str != null && !str.trim().equals("") && num < inputStrs.size();
+        for (String str = inputStrs.get(num); str != null && !str.trim().equals("")
+                && num < inputStrs.size();
                 str = inputStrs.get(num)) {
             if (str.contains("Route Distinguisher")) {
-                countersMap.put(key, Integer.toString(routeCount));
+                totalPfxMap.put(bgpRdRouteCountKey, Long.toString(routeCount));
+                updateCounter(counter, routeCount);
                 return num - 1;
             }
             routeCount++;
@@ -390,25 +376,26 @@ public class BgpCounters extends TimerTask {
             // by sending a big number back.
             return Integer.MAX_VALUE;
         }
-        countersMap.put(key, Integer.toString(routeCount));
+        updateCounter(counter, routeCount);
         return num - 1;
     }
 
-    private int calculateBgpTotalPrefixes() {
-        return countersMap.entrySet().stream().filter(entry -> entry.getKey().contains(BgpConstants
-                .BGP_COUNTER_RD_ROUTE_COUNT)).map(Map.Entry::getValue).mapToInt(Integer::parseInt).sum();
+    private Long calculateBgpTotalPrefixes() {
+        return totalPfxMap.entrySet().stream()
+                .map(Map.Entry::getValue).mapToLong(Long::parseLong).sum();
     }
 
     private void resetCounters() {
-        countersMap.clear();
+        totalPfxMap.clear();
         resetFile("cmd_ip_bgp_summary.txt");
         resetFile("cmd_bgp_ipv4_unicast_statistics.txt");
         resetFile(BGP_VPNV4_FILE);
         resetFile(BGP_VPNV6_FILE);
+        resetFile(BGP_EVPN_FILE);
     }
 
     static void resetFile(String fileName) {
-        File file = (new File(fileName));
+        File file = new File(fileName);
         if (!file.delete()) {
             try (PrintWriter pw = new PrintWriter(file)) {
                 pw.print("");
@@ -461,6 +448,108 @@ public class BgpCounters extends TimerTask {
     static Map<String, String> parseIpBgpVpnv6AllSummary(Map<String, String> countMap) {
         return BgpCounters.parseIpBgpVpnAllSummary(countMap,
                                                    BGP_VPNV6_SUMMARY_FILE,
-                                                   af_afi.AFI_IPV6);
+                                                   af_afi.AFI_IP);
+    }
+
+    static Map<String, String> parseBgpL2vpnEvpnAllSummary(Map<String, String> countMap) {
+        return BgpCounters.parseIpBgpVpnAllSummary(countMap,
+                                                   BGP_EVPN_SUMMARY_FILE,
+                                                   af_afi.AFI_IP);
+    }
+
+    /**
+     * This method updates Counter values.
+     * @param counter object of the Counter
+     * @param counterValue value of Counter
+     */
+    private void updateCounter(Counter counter, long counterValue) {
+        try {
+            /*Reset counter to zero*/
+            counter.decrement(counter.get());
+            /*Set counter to specified value*/
+            counter.increment(counterValue);
+        } catch (IllegalStateException e) {
+            LOG.error("Exception occured during updating the Counter {}", counter, e);
+        }
     }
+
+    /**
+     * Returns the counter.
+     * This method returns counter and also creates counter if does not exist.
+     *
+     * @param counterName name of the counter.
+     * @param asValue as value.
+     * @param rxValue rx value.
+     * @param txValue tx value.
+     * @param neighborIp neighbor Ipaddress.
+     * @param rdValue rd value.
+     * @return counter object.
+     */
+    private Counter getCounter(String counterName, String asValue,
+            String rxValue, String txValue, String neighborIp, String rdValue) {
+        String counterTypeEntityCounter = "entitycounter";
+        String labelKeyEntityType = "entitytype";
+
+        String labelValEntityTypeBgpPeer = "bgp-peer";
+        String labelKeyAsId = "asid";
+        String labelKeyNeighborIp = "neighborip";
+
+        String labelValEntityTypeBgpRd = "bgp-rd";
+        String labelKeyRd = "rd";
+
+        String counterTypeAggregateCounter = "aggregatecounter";
+        String labelKeyCounterName = "name";
+
+        Counter counter = null;
+
+        if (rxValue != null) {
+            /*
+             * Following is the key pattern for Counter BgpNeighborPacketsReceived
+             * netvirt.bgpmanager.entitycounter{entitytype=bgp-peer, asid=value, neighborip=value, name=countername}
+             * */
+            Labeled<Labeled<Labeled<Labeled<Counter>>>> labeledCounter =
+                    metricProvider.newCounter(MetricDescriptor.builder().anchor(this).project("netvirt")
+                        .module("bgpmanager").id(counterTypeEntityCounter).build(),
+                        labelKeyEntityType, labelKeyAsId,
+                        labelKeyNeighborIp, labelKeyCounterName);
+            counter = labeledCounter.label(labelValEntityTypeBgpPeer).label(asValue)
+                    .label(neighborIp).label(counterName);
+        } else if (txValue != null) {
+            /*
+             * Following is the key pattern for Counter BgpNeighborPacketsSent
+             * netvirt.bgpmanager.entitycounter{entitytype=bgp-peer, asid=value, neighborip=value, name=countername}
+             * */
+            Labeled<Labeled<Labeled<Labeled<Counter>>>> labeledCounter =
+                    metricProvider.newCounter(MetricDescriptor.builder().anchor(this).project("netvirt")
+                        .module("bgpmanager").id(counterTypeEntityCounter).build(),
+                        labelKeyEntityType, labelKeyAsId,
+                        labelKeyNeighborIp, labelKeyCounterName);
+            counter = labeledCounter.label(labelValEntityTypeBgpPeer).label(asValue)
+                    .label(neighborIp).label(counterName);
+        } else if (rdValue != null) {
+            /*
+             * Following is the key pattern for Counter BgpRdRouteCount
+             * netvirt.bgpmanager.entitycounter{entitytype=bgp-rd, rd=value, name=countername}
+             * */
+            Labeled<Labeled<Labeled<Counter>>> labeledCounter =
+                    metricProvider.newCounter(MetricDescriptor.builder().anchor(this).project("netvirt")
+                        .module("bgpmanager").id(counterTypeEntityCounter).build(),
+                        labelKeyEntityType, labelKeyRd,
+                        labelKeyCounterName);
+            counter = labeledCounter.label(labelValEntityTypeBgpRd).label(rdValue)
+                    .label(counterName);
+        } else {
+            /*
+             * Following is the key pattern for Counter BgpTotalPrefixes:Bgp_Total_Prefixes
+             * netvirt.bgpmanager.aggregatecounter{name=countername}
+             * */
+            Labeled<Counter> labeledCounter =
+                    metricProvider.newCounter(MetricDescriptor.builder().anchor(this).project("netvirt")
+                        .module("bgpmanager").id(counterTypeAggregateCounter).build(),
+                        labelKeyCounterName);
+            counter = labeledCounter.label(counterName);
+        }
+        return counter;
+    }
+
 }