Package edu.iu.incntre.flowscalestatcollector

Source Code of edu.iu.incntre.flowscalestatcollector.StatCollector

/**
*Copyright 2012, InCNTRE. This file is licensed under Apache 2.0 *
**/

package edu.iu.incntre.flowscalestatcollector;

import java.util.Calendar;
import java.util.List;

import org.openflow.protocol.OFPhysicalPort;
import org.openflow.protocol.statistics.OFStatistics;
import org.openflow.util.HexString;

import java.util.HashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.iu.incntre.flowscale.FlowscaleController;
import edu.iu.incntre.flowscale.SwitchDevice;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import edu.iu.incntre.flowscale.exception.NoSwitchException;
import edu.iu.incntre.flowscale.util.JSONConverter;

import java.io.IOException;
import java.sql.*;

/**
* The class responsible for polling all statistics from the switch and storing
* them in a database
*
*
* @author Ali Khalfan (akhalfan@indiana.edu)
*
* **/

public class StatCollector {

  private boolean isQuery;
  private long intervalTime;
  private FlowscaleController flowscaleController;
  protected static Logger logger = LoggerFactory
      .getLogger(StatCollector.class);

  private String datapathIdStrings;

  private Connection conn;

  private String databaseDriver;
  private String databaseClass;
  protected Thread statThread;

  private HashMap<Long, HashMap<Long, Long>> tempPortStatTransmittedHashMap = new HashMap<Long, HashMap<Long, Long>>();
  private HashMap<Long, HashMap<Long, Long>> tempPortStatReceivedHashMap = new HashMap<Long, HashMap<Long, Long>>();
  private HashMap<Long, HashMap<String, Long>> tempFlowStatHashMap = new HashMap<Long, HashMap<String, Long>>();
  private String dbUsername;
  private String dbPassword;

  private Calendar calendar;

  public void setIsQuery(boolean isQuery) {

    this.isQuery = isQuery;
  }

  public void setIntervalTime(long intervalTime) {
    this.intervalTime = intervalTime;
  }

  public void setFlowscaleController(FlowscaleController flowscaleController) {
    this.flowscaleController = flowscaleController;
  }

  public void setDatapathIdStrings(String datapathIdStrings) {

    this.datapathIdStrings = datapathIdStrings;

  }

  public void setDatabaseDriver(String databaseDriver) {
    this.databaseDriver = databaseDriver;
  }

  public void setDatabaseClass(String databaseClass) {
    this.databaseClass = databaseClass;
  }

  public void setDbUsername(String dbUsername) {
    this.dbUsername = dbUsername;
  }

  public void setDbPassword(String dbPassword) {
    this.dbPassword = dbPassword;

  }

  public void killThread() {

    this.statThread = null;
   
  }

  public void startUp() {

    logger.trace("Startup of StatCollector");
    try{
    if (isQuery) {

      // initiate sqlite database

      try {

        Class.forName(databaseClass);
        conn = DriverManager.getConnection(databaseDriver, dbUsername,
            dbPassword);
       
      } catch (ClassNotFoundException e2) {

        logger.error("{}", e2);
      } catch (SQLException e1) {
        // TODO Auto-generated catch block
        logger.error("{}", e1);
      }

      // end initiate database

      // start up thread

      statThread = new Thread(new Runnable() {

        @Override
        public void run() {
          try {
            logger.trace("Starting Thread ..");
            logger.trace(
                "Getting flows from switch every {} seconds",
                intervalTime);

            List<OFStatistics> portStats;
            List<OFStatistics> flowStats;
            List<OFPhysicalPort> portStatus;
            SwitchDevice swd = null;
            String[] datapathIdStringElements = datapathIdStrings.split(",");
            try {

              while (statThread != null) {
                calendar = Calendar.getInstance();
                logger.trace("getting flows from switches");
               
                //check if conn is null if it is, reset connection
                if(conn == null){
                conn = DriverManager.getConnection(databaseDriver, dbUsername,
                    dbPassword);
                }
               
               
                for (String datapathIdString : datapathIdStringElements) {

                  try {

                 
                    swd = flowscaleController
                        .getSwitchDevices()
                        .get(HexString
                            .toLong(datapathIdString));
                   
                   
                   
                    if (swd == null) {
                      logger.info("switch {} does not exist, is it connected?",
                          datapathIdString);
                      continue;
                    }
                   
                   
                    logger.info(
                        "Getting flows from switch {} with ID {}",
                        swd.getSwitchName(), datapathIdString);

                   

                    try {
                      portStats = flowscaleController
                          .getSwitchStatisticsFromInterface(
                              datapathIdString,
                              "port");

                      flowStats = flowscaleController
                          .getSwitchStatisticsFromInterface(
                              datapathIdString,
                              "flow");

                      portStatus = swd.getPortStates();

                      if (flowStats != null
                          && portStats != null) {

                        String flowStatsJSON = JSONConverter
                            .toStat(flowStats,
                                "flow")
                            .toJSONString();
                        String portStatsJSON = JSONConverter
                            .toStat(portStats,
                                "port")
                            .toJSONString();
                        String portStatusJSON = JSONConverter
                            .toPortStatus(
                                portStatus)
                            .toJSONString();

                        // initialize or set hashmaps

                        HashMap<Long, Long> tempPortStatTransmitted;
                        HashMap<Long, Long> tempPortStatReceived;
                        HashMap<String, Long> tempFlowStat;

                        long datapathId = HexString
                            .toLong(datapathIdString);
                        if (tempPortStatTransmittedHashMap
                            .get(datapathId) == null) {

                          tempPortStatTransmitted = new HashMap<Long, Long>();
                          tempPortStatTransmittedHashMap
                              .put(datapathId,
                                  tempPortStatTransmitted);
                        } else {
                          tempPortStatTransmitted = tempPortStatTransmittedHashMap
                              .get(datapathId);

                        }

                        if (tempPortStatReceivedHashMap
                            .get(datapathId) == null) {
                          tempPortStatReceived = new HashMap<Long, Long>();
                          tempPortStatReceivedHashMap
                              .put(datapathId,
                                  tempPortStatReceived);
                        } else {
                          tempPortStatReceived = tempPortStatReceivedHashMap
                              .get(datapathId);
                        }
                        if (tempFlowStatHashMap
                            .get(datapathId) == null) {
                          tempFlowStat = new HashMap<String, Long>();
                          tempFlowStatHashMap.put(
                              datapathId,
                              tempFlowStat);
                        } else {

                          tempFlowStat = tempFlowStatHashMap
                              .get(datapathId);
                        }

                        storeSwitchDetails(
                            HexString
                                .toLong(datapathIdString),
                            portStatsJSON,
                            flowStatsJSON,
                            portStatusJSON,
                            tempPortStatTransmitted,
                            tempPortStatReceived,
                            tempFlowStat);
                      } else {
                        logger.error(
                            "Switch {} returned a null result possibility because the switch is not connected to the controller",
                            datapathIdString);
                      }
                    } catch (NoSwitchException e1) {
                      // TODO Auto-generated catch block
                      logger.error(
                          "Switch {} with ID {} is not connected aborting",
                          swd.getSwitchName(),datapathIdString)
                    } catch (IOException e1) {
                      logger.error("IOException {}", e1);

                    } catch (InterruptedException e1) {
                      logger.error(
                          "Thread Interrupted {}", e1);
                      killThread();
                    } catch (ExecutionException e1) {
                      logger.error(
                          "Execution Exception {}",
                          e1);
                    } catch (TimeoutException e1) {
                      logger.error(
                          "Switch Timeout Exception {}",
                          e1);
                      killThread();

                    }

                  } catch (Exception e) {
                    logger.error(
                        "unchecked exception here {}",
                        e);

                    killThread();
                    shutDown();
                    Thread.yield();

                  }

                }

                try {

                  Thread.sleep(intervalTime);

                } catch (InterruptedException e) {

                  logger.error("{}", e);

                  break;
                }

              }
            } catch (Exception e) {
              logger.error("exception in while {}", e);
              shutDown();

            }

            try {
              conn.close();
            } catch (SQLException e) {
              // TODO Auto-generated catch block
              logger.error("{}", e);
            }

          } catch (Exception generalException) {
            logger.error("General Exception throws {} ",
                generalException);

          }
        }
/**
* insert details into database, 3 tables will be populated: flow_stats, port_stats ,and port_status
*
* @param datapathId
* @param portStats
* @param flowStats
* @param portStatus
* @param tempPortStatTransmitted
* @param tempPortStatReceived
* @param tempFlowStat
*/
        private void storeSwitchDetails(long datapathId,
            String portStats, String flowStats, String portStatus,
            HashMap<Long, Long> tempPortStatTransmitted,
            HashMap<Long, Long> tempPortStatReceived,
            HashMap<String, Long> tempFlowStat) {

          Object obj = JSONValue.parse(portStats);
          JSONArray jsonArray = (JSONArray) obj;

          for (int i = 0; i < jsonArray.size(); i++) {

            JSONObject jsonObject = (JSONObject) jsonArray.get(i);
            long transmittedPackets = (Long) jsonObject
                .get("transmit_packets");
            long receivedPackets = (Long) jsonObject
                .get("receive_packets");

            long portId = (Long) jsonObject.get("port_id");

            // logger.info("the port is {}", portId);
            // logger.info("{} packets transmitted and {} packets received",
            // receivedPackets,transmittedPackets);

            PreparedStatement prep = null;
            try {
              prep = null;
              if (conn != null) {
                prep = conn
                    .prepareStatement("insert into port_stats values (?,?,?,?,?);");

              } else {

                logger.error("no connection object instantiated aborting .. ");
                return;
              }

              prep.setLong(1, datapathId);
              prep.setLong(2, calendar.getTimeInMillis());

              if (tempPortStatTransmitted.get(portId) != null) {

                long currentTransmittedPackets = transmittedPackets
                    - tempPortStatTransmitted.get(portId);

                if (currentTransmittedPackets < 0) {

                  prep.setLong(5, transmittedPackets);
                } else {

                  prep.setLong(5, currentTransmittedPackets);
                }
              } else {

                prep.setLong(5, transmittedPackets);
              }

              tempPortStatTransmitted.put(portId,
                  transmittedPackets);

              // take care of port received

              if (tempPortStatReceived.get(portId) != null) {

                long currentReceivedPackets = receivedPackets
                    - tempPortStatReceived.get(portId);

                if (currentReceivedPackets < 0) {

                  prep.setLong(4, receivedPackets);
                } else {

                  prep.setLong(4, currentReceivedPackets);
                }
              } else {

                prep.setLong(4, receivedPackets);
              }

              tempPortStatReceived.put(portId, receivedPackets);

              prep.setLong(3, portId);
              prep.addBatch();

              conn.setAutoCommit(false);
              prep.executeBatch();
              conn.setAutoCommit(true);
            }catch(SQLRecoverableException sqlRecoverableException){
             
              logger.error("{}", sqlRecoverableException);
              //exit function since there is a timeout
              return;
            } catch (SQLException e) {

              logger.error("{}", e);
            } finally {
              if (prep != null) {
                try {
                  prep.close();
                } catch (SQLException e) {
                  // TODO Auto-generated catch block
                  logger.error("{}", e);
                }
              }
            }
          }

          Object flowJSONobj = JSONValue.parse(flowStats);
          JSONArray flowJsonArray = (JSONArray) flowJSONobj;

          for (int i = 0; i < flowJsonArray.size(); i++) {

            JSONObject jsonObject = (JSONObject) flowJsonArray
                .get(i);
            long packets = (Long) jsonObject.get("packet_count");
            String matchString = (String) jsonObject.get("match");
            String action = (String) jsonObject.get("actions");
            long priority = (Long) jsonObject.get("priority");
           
            PreparedStatement prep = null;

            try {
              prep = conn
                  .prepareStatement("insert  into flow_stats values (?,?,?,?,?,?);");
              String insertString = datapathId +","+calendar.getTimeInMillis()+","+
              matchString+ "," + action ;
              logger.debug("flow_stat values to insert are {}",insertString);
              prep.setLong(1, datapathId);
              prep.setLong(2, calendar.getTimeInMillis());

              if (tempFlowStat.get(matchString) != null) {

                long packetsReceived = packets
                    - tempFlowStat.get(matchString);

                if (packetsReceived < 0) {

                  prep.setLong(5, packets);
                } else {

                  prep.setLong(5, packetsReceived);
                }
              } else {

                prep.setLong(5, packets);
              }

              tempFlowStat.put(matchString, packets);

              prep.setString(3, matchString);
              prep.setString(4, action);
             

              prep.setShort(6, (short)priority);
              prep.addBatch();

              conn.setAutoCommit(false);
              prep.executeBatch();
              conn.setAutoCommit(true);
            } catch (SQLException e) {
              // TODO Auto-generated catch block
              logger.error("error when insert flow {} in switch {}", matchString,datapathId);
              logger.error("{}", e);
            } finally {
              if (prep != null) {
                try {
                  prep.close();
                } catch (SQLException e) {
                  // TODO Auto-generated catch block
                  logger.error("{}", e);
                }
              }
            }

          }

          Object portStatusJSONobj = JSONValue.parse(portStatus);
          JSONArray portStatusJsonArray = (JSONArray) portStatusJSONobj;

          for (int i = 0; i < portStatusJsonArray.size(); i++) {
            byte portStatusValue = 0;
            JSONObject jsonObject = (JSONObject) portStatusJsonArray
                .get(i);
            long portId = (Long) jsonObject.get("port_id");
            String portAddress = (String) jsonObject
                .get("port_address");
            try {
              portStatusValue = (byte) (Integer
                  .parseInt(jsonObject.get("state")
                      .toString()) % 2);
            } catch (NumberFormatException nfe) {
              logger.error("{}", nfe);
              continue;
            }
            PreparedStatement prep = null;
            try {
              prep = conn
                  .prepareStatement("insert into port_status   values (?,?,?,?,?);");
              prep.setLong(1, datapathId);
              prep.setLong(2, calendar.getTimeInMillis());
              prep.setLong(3, portId);

              prep.setString(4, portAddress);

              prep.setByte(5, portStatusValue);
              prep.addBatch();

              conn.setAutoCommit(false);
              prep.executeBatch();
             
              conn.setAutoCommit(true);
            } catch (SQLException e) {
              // TODO Auto-generated catch block
              logger.error("{}", e);
            } finally {
              if (prep != null) {
                try {
                  prep.close();
                } catch (SQLException e) {
                  // TODO Auto-generated catch block
                  logger.error("{}", e);
                }
              }
            }

          }

        }

      }, "Switch Stat Collector");
      statThread.start();

    }
    }catch(Exception e){
      logger.error("general excecption thrown {}", e);
    }
  }

  public void shutDown() {

    statThread.interrupt();
    statThread = null;
    this.notify();

  }

  public String getName() {
    // TODO Auto-generated method stub
    return "statCollector";
  }
}
TOP

Related Classes of edu.iu.incntre.flowscalestatcollector.StatCollector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.