Package nz.co.abrahams.asithappens.response

Source Code of nz.co.abrahams.asithappens.response.ResponseWindowsCollector$ResponseResult

/*
* ResponseWindowsCollector.java
*
* Created on 11 November 2003, 17:07
*
* AsItHappens - real-time network monitor
* Copyright (C) 2006  Mark Abrahams
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

package nz.co.abrahams.asithappens.response;

import nz.co.abrahams.asithappens.core.DataType;
import nz.co.abrahams.asithappens.storage.DataHeadings;
import nz.co.abrahams.asithappens.storage.DataPoint;
import nz.co.abrahams.asithappens.storage.Device;
import nz.co.abrahams.asithappens.collectors.DataCollectorResponse;
import nz.co.abrahams.asithappens.collectors.DataCollector;
import nz.co.abrahams.asithappens.snmputil.SNMPException;
import nz.co.abrahams.asithappens.core.DBException;
import org.apache.log4j.Logger;
import estadisticas.icmp.PingICMP;
import java.net.*;
import java.util.*;

/**
* Collects response data from a device using ICMP.  This class only works when
* the collector is running under Windows, as it uses a Windows native library.
* <p>
* This class uses a separate thread to listen to all responses, and store each
* response in a list for the sender threads to interrogate for their particular
* response.
*
* @author  mark
*/
public class ResponseWindowsCollector extends DataCollector implements Runnable {
   
    /**
     * Response result inner class for this collector.  Used to pass response
     * results from listening thread to sender thread.
     */
    public class ResponseResult {
       
        /** name of target device */
        String device;
        /** ID of ICMP packet required by library */
        int id;
        /** sequence of ICMP packet required by library */
        int sequence;
        /** response value */
        double value;
       
        public ResponseResult(String device, int id, int sequence, double value) {
            this.device = device;
            this.id = id;
            this.sequence = sequence;
            this.value = value;
        }
    }
   
    /** Maximum timeout interval in milliseconds */
    public static final long MAX_TIMEOUT = 5000;

    /** Logging provider */
    private static Logger logger = Logger.getLogger(ResponseWindowsCollector.class);

    /** time to wait for each poll response before giving up */
    private long timeout;
    /** address of target device */
    private InetAddress deviceAddress;
    /** name of device */
    private String deviceString;
   
    // BEGIN PingICMP variables
    /** Indication that listener thread should stop */
    private static boolean stopListening;
    /** number of these collectors started, each of which will be sending ICMP */
    private static int collectorCount;
   
    /** ICMP library object */
    private PingICMP ping;
    /** ID of ICMP packet required by library */
    private int id;
    /** sequence number of ICMP packet required by library */
    private int sequence;
    //private Double response;
    //private HashMap<Integer,Double> responseMap;
   
    //private Integer indexInteger;
    /** thread that listens to and stores ICMP responses */
    private static Thread listener;
    /** the list of results observed by the listener thread */
    private static Vector<ResponseResult> resultList;
    // END PingICMP variables
   
    static {
        collectorCount = 0;
        stopListening = true;
    }
   
    /** Creates a new instance of ResponseCollector */
    public ResponseWindowsCollector(Device device, long pollInterval) throws UnknownHostException {
        super(device, pollInterval, DataType.RESPONSE);
       
        deviceAddress = device.getResolvedAddress();
        timeout = pollInterval / 2;
       
        // PingICMP initializer
        initCollector();
    }
   
    /** Initializes the collector. */
    public void initCollector() {
       
        deviceString = deviceAddress.getHostAddress();
        //deviceAddress = InetAddress.getByName(device).getHostAddress();
        if ( ping == null ) {
            ping = new PingICMP();
            ping.begin();
        }
        timeout = Math.min(pollInterval / 2, MAX_TIMEOUT);
        // Bug note: small chance of picking an id already assigned to another PingICMP object
        // In this case, the response times of both PingICMP objects seem to grow without bound
        id = (int)(Math.random() * 65535);
        sequence = 1;
        //responseMap = new HashMap();
        collectorCount++;
       
        if ( stopListening == true ) {
            stopListening = false;
            listener = new Thread(this);
            listener.start();
        }
        if ( resultList == null )
            resultList = new Vector();
    }
   
    /**
     * Returns an array containing a single data point - the round-trip response
     * in milliseconds to the destination device.
     *
     * @return an array containing the single response data point
     */
    public DataCollectorResponse getNextValues(DataHeadings headings) {
        Thread listener;
        DataPoint[] point;
        ResponseResult responseItem;
        long currentTime;
       
        point = new DataPoint[1];
        point[0] = null;
       
        currentTime = System.currentTimeMillis();
       
        try {
           
            //response = null;
            //indexInteger = new Integer(sequence);
            //ping.ping(deviceAddress, id, sequence);
            logger.debug("Request for id " + id + " seq " + sequence);
            ping.ping(deviceString, id, sequence);
            Thread.sleep(timeout);
           
            for (int i = 0; i < resultList.size(); i++) {
                responseItem = resultList.elementAt(i);
                if ( id == responseItem.id && sequence == responseItem.sequence ) {
                    point[0] = new DataPoint(currentTime, responseItem.value);
                    resultList.removeElementAt(i);
                    i = resultList.size() + 1;
                }
            }
            if ( point[0] == null )
                point[0] = new DataPoint(currentTime, timeout);
            sequence++;
            return new DataCollectorResponse(point, new String[0], dataType.initialSetCount());
        } catch (InterruptedException e) {
            e.printStackTrace();
            point[0] = new DataPoint(currentTime, 0);
            return new DataCollectorResponse(point, new String[0], dataType.initialSetCount());
        }
    }
   
    /**
     * Starts the listener thread.  This listens for all ICMP packets received
     * by the PingICMP library and add the results to a static vector that
     * is shared by all response collectors.  The collectors can then examine
     * the vector for their particular response packet.
     */
    public void run() {
        int resultID;
        int resultSequence;
        double resultValue;
        String[] result;
       
        result = new String[4];
        result[1] = "-1";
        result[2] = "-1";
        resultID = -1;
        resultSequence = -1;
        resultValue = -1;
       
        while ( stopListening == false ) {
            ping.pong(result);
            //resultDevice = result[0];
           
            try {
                resultID = Integer.parseInt(result[1]);
                resultSequence = Integer.parseInt(result[2]);
                resultValue = Double.parseDouble(result[3]);
                resultList.add(0, new ResponseResult(result[0], resultID, resultSequence, resultValue));
                logger.debug("Reply for device " + result[0] + " id " + resultID + " seq " + resultSequence + ": "  + resultValue + " ms");
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("Unable to parse ICMP response: device=" + result[0] + ",id=" + resultID + ",seq=" + resultSequence + ",value(ms)=" + resultValue);
            }
            result = new String[4];
            result[1] = "-1";
            result[2] = "-1";
            resultID = -1;
            resultSequence = -1;
            resultValue = -1;
        }
       
    }
   
   
    /*
    public DataPoint[] getNextValues() {
        long startTime;
        long responseTime;
        DataPoint[] point;
    
        point = new DataPoint[1];
        startTime = System.currentTimeMillis();
    
        try {
            if ( deviceAddress.isReachable((int)timeout) ) {
                responseTime = System.currentTimeMillis() - startTime;
                //System.out.println("Response" + responseTime);
            }
            else {
                responseTime = timeout;
                //responseTime = System.currentTimeMillis() - startTime;
                //System.out.println("Timeout " + responseTime);
            }
            point[0] = new DataPoint(startTime, (double)responseTime);
    
            return point;
        }
        catch (IOException e) {
            point[0] = new DataPoint(startTime, timeout);
        }
        return point;
    }
     */

    /**
     * Decreases the collector count and stops the listener thread if there
     * are no more active collectors.
     */
    public void releaseCollector() {
        collectorCount--;
        if ( collectorCount == 0 ) {
            stopListening = true;
        }
    }
   
}
TOP

Related Classes of nz.co.abrahams.asithappens.response.ResponseWindowsCollector$ResponseResult

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.