All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.collectd.protocol.UdpReceiver Maven / Gradle / Ivy

Go to download

The jcollectd package implements the collectd protocol in Java, making it possible for Java applications to push data into collectd over the wire.

The newest version!
/*
 * jcollectd
 * Copyright (C) 2009 Hyperic, Inc.
 * 
 * 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; only version 2 of the License is applicable.
 * 
 * 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.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

package org.collectd.protocol;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.logging.Logger;

import org.collectd.api.PluginData;
import org.collectd.api.ValueList;
import org.collectd.api.Notification;

/**
 * collectd UDP protocol receiver.
 * See collectd/src/network.c:parse_packet
 */
public class UdpReceiver {

    private static final Logger _log =
        Logger.getLogger(UdpReceiver.class.getName());
    private Dispatcher _dispatcher;
    private DatagramSocket _socket;
    private int _port = Network.DEFAULT_PORT;
    private String _bindAddress;
    private String _ifAddress;
    private boolean _isShutdown = false;

    protected UdpReceiver() {
        String addr = Network.getProperty(PropertyNames.LOCAL_ADDRESS, Network.DEFAULT_V4_ADDR);
        if (addr != null) {
            int ix = addr.indexOf(':'); //XXX ipv6
            if (ix == -1) {
                _bindAddress = addr;
            }
            else {
                _bindAddress = addr.substring(0, ix);
                _port = Integer.parseInt(addr.substring(ix+1));
            }
        }
        addr = Network.getProperty(PropertyNames.INTERFACE_ADDRESS);
        if (addr != null) {
            try {
                //-Djcd.ifaddr=tun0
                _ifAddress =
                    NetworkInterface.getByName(addr).getInetAddresses().
                        nextElement().getHostAddress();
            } catch (Exception e) {
                //-Djcd.ifaddr=10.2.0.43
                _ifAddress = addr;
            }
            _log.fine("Using interface address=" + _ifAddress);
        }
    }

    public UdpReceiver(Dispatcher dispatcher) {
        this();
        setDispatcher(dispatcher);
    }

    public void setDispatcher(Dispatcher dispatcher) {
        _dispatcher = dispatcher;       
    }

    public int getPort() {
        return _port;
    }

    public void setPort(int port) {
        _port = port;
    }

    public String getListenAddress() {
        return _bindAddress;
    }

    public void setListenAddress(String address) {
        _bindAddress = address;
    }

    public String getInterfaceAddress() {
        return _ifAddress;
    }

    public void setInterfaceAddress(String address) {
        _ifAddress = address;
    }

    public DatagramSocket getSocket() throws IOException {
        if (_socket == null) {
            if (_bindAddress == null) {
                _socket = new DatagramSocket(_port);
            }
            else {
                InetAddress addr = InetAddress.getByName(_bindAddress);
                if (addr.isMulticastAddress()) {
                    MulticastSocket mcast = new MulticastSocket(_port);
                    if (_ifAddress != null) {
                        mcast.setInterface(InetAddress.getByName(_ifAddress));
                    }
                    mcast.joinGroup(addr);
                    _socket = mcast;
                }
                else {
                    _socket = new DatagramSocket(_port, addr);
                }
            }
        }
        return _socket;
    }

    public void setSocket(DatagramSocket socket) {
        _socket = socket;
    }

    private String readString(DataInputStream is, int len)
        throws IOException {
        byte[] buf = new byte[len];
        is.read(buf, 0, len);
        return new String(buf, 0, len-1); //-1 -> skip \0
    }

    private void readValues(DataInputStream is, ValueList vl)
        throws IOException {
        byte[] dbuff = new byte[8];
        int nvalues = is.readUnsignedShort();
        int[] types = new int[nvalues];
        for (int i=0; i Network.HEADER_LEN)) {
            int type = is.readUnsignedShort();
            int len = is.readUnsignedShort();

            if (len < Network.HEADER_LEN) {
                break; //packet was filled to the brim
            }

            total -= len;
            len -= Network.HEADER_LEN;

            if (type == Network.TYPE_VALUES) {
                readValues(is, obj.getValueList());
            }
            else if (type == Network.TYPE_TIME) {
                obj.pd.setTime (is.readLong() * 1000);
            }
            else if (type == Network.TYPE_INTERVAL) {
                obj.getValueList ().setInterval (is.readLong ());
            }
            else if (type == Network.TYPE_HOST) {
                obj.pd.setHost (readString (is, len));
            }
            else if (type == Network.TYPE_PLUGIN) {
                obj.pd.setPlugin (readString (is, len));
            }
            else if (type == Network.TYPE_PLUGIN_INSTANCE) {
                obj.pd.setPluginInstance (readString (is, len));
            }
            else if (type == Network.TYPE_TYPE) {
                obj.pd.setType (readString (is, len));
            }
            else if (type == Network.TYPE_TYPE_INSTANCE) {
                obj.pd.setTypeInstance (readString (is, len));
            }
            else if (type == Network.TYPE_MESSAGE) {
                Notification notif = obj.getNotification();
                notif.setMessage (readString(is, len));
                if (_dispatcher != null) {
                    _dispatcher.dispatch(notif);
                }
            }
            else if (type == Network.TYPE_SEVERITY) {
                obj.getNotification ().setSeverity ((int) is.readLong ());
            }
            else {
                break;
            }
        }
    }

    public void listen() throws Exception {
        listen(getSocket());
    }

    public void listen(DatagramSocket socket) throws IOException { 
        while (true) {
            byte[] buf = new byte[Network.BUFFER_SIZE];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            try {
                socket.receive(packet);
            } catch (SocketException e) {
                if (_isShutdown) {
                    break;
                }
                else {
                    throw e;
                }
            }
            parse(packet.getData());
        }        
    }

    public void shutdown() {
        if (_socket != null) {
            _isShutdown = true;
            _socket.close();
            _socket = null;
        }
    }

    public static void main(String[] args) throws Exception {
        new UdpReceiver(new StdoutDispatcher()).listen();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy