Sophie

Sophie

distrib > Mageia > 4 > x86_64 > by-pkgid > e5dacb39141c2088e2c30e21fa0b2b06 > files > 55

nagios-check_mk-doc-1.2.3i1-3.mga4.noarch.rpm

package livestatus;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRDataset;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRValueParameter;
import net.sf.jasperreports.engine.query.JRQueryExecuter;


public class LivestatusQueryExecuter implements JRQueryExecuter{
	// Connection parameters
	private HashMap<String, String> parameters;       // Given parameters from iReport
	private String    			jasper_query;     // Query from iReport incl. connection details
	private String    			livestatus_query; // Query send to livestatus
	private String    			server;           // server name
	private int       			server_port;      // server port
	private int 				timeoutInMs = 10*1000;  // 10 seconds
	private String    			fixed_appendix = "\nColumnHeaders: on\nResponseHeader: fixed16\nSeparators: 10 1 44 124\nOutputFormat: csv\n\n";

	// Socket parameters
	private Socket    			socket;           // socket to server
	private OutputStream 		sockOutput;       // socket output stream
	private InputStream 		sockInput;        // socket input stream
	private BufferedReader 		in;               // InputStream reader

	
	public static void main(String[] args){
		try {
			//new LivestatusQueryExecuter("localhost 6561\nGET services\nColumns: host_name check_command").createDatasource();
//			String query = "localhost 6557\n"+
//			"GET statehist\n" +
//			"Columns: host_name service_description\n"+
//			"Filter: time >= 1344195720\n"+
//			"Filter: time <= 1344195776\n"+
//			"Filter: host_name = localhost\n"+
//			"Stats: sum duration_ok\n"+
//			"Stats: sum duration_warning\n"+
//			"Stats: sum duration_critical";
			String query = 	"localhost 6557\n"+
					"GET statehist\n" +
					"Columns: service_description time state duration duration_part log_output\n" +
//					"Filter: service_description ~ /fshome" +
					"Filter: time >= 1351724400";

			
			JRDataSource sourci = new LivestatusQueryExecuter(query, null).createDatasource();
			
			
		} catch (JRException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
	
	@SuppressWarnings("rawtypes")
	public LivestatusQueryExecuter(String query, Map parameters) {
		this.jasper_query = query;
		this.parameters = new HashMap<String,String>();
		if (parameters != null)
			for ( Object key : parameters.keySet() ) {
				if ( parameters.get(key) == null ) {
					continue;
				}
				this.parameters.put(key.toString(), parameters.get(key).toString());
			}
		
//		LivestatusQueryExecuterFactory.logFile(this.jasper_query);
//		for (String key : this.parameters.keySet())
//		{
//			LivestatusQueryExecuterFactory.logFile("key " + key + " " + this.parameters.get(key.toString()));	
//			String value = this.parameters.get(key);
//			LivestatusQueryExecuterFactory.logFile(key +  " = " + value);			
//		}
	}

	public LivestatusQueryExecuter(JRDataset dataset, Map<String,? extends JRValueParameter> parameters) {
		this.jasper_query = dataset.getQuery().getText();
		this.parameters = new HashMap<String,String>();
		for ( Object key : parameters.keySet() ) {
			if ( parameters.get(key) == null || parameters.get(key).getValue() == null ) {
				continue;
			}
			this.parameters.put(key.toString(), parameters.get(key).getValue().toString());
		}
	}

	private void evaluateQuery() throws JRException{
		// check for blank lines
		for( String line : jasper_query.split("\n") ){
			if( line.trim().isEmpty() )
				throw new JRException("LQL Query: Remove blank lines from query");			
		}

		// Replace any parameters within the jasper_query
		String mod_query = jasper_query;
		if ( parameters != null ) {
			for (String key : parameters.keySet())
			{
				String value = parameters.get(key);
				if ( value != null ) {
					mod_query = mod_query.replaceAll("\\$P\\{"+key+"\\}", "\"" + value + "\"");
					mod_query = mod_query.replaceAll("\\$P!\\{"+key+"\\}", value);
				}
			}
		}
		
		String target_info = mod_query.split("\n")[0];
		livestatus_query   = mod_query.substring(target_info.length()+1);
		server      = target_info.split(" ")[0];
		server_port = Integer.parseInt(target_info.split(" ")[1]);
	}

	public boolean cancelQuery() throws JRException {
		try {
			if( socket.isConnected() ){
				socket.close();
				return true;
			}
		}catch (IOException e) {
			throw new JRException(e.getMessage());
		}
		return false;
	}

	public void close() {
	}

	private void setupSocket() throws JRException{
		InetAddress   inteAddress;
		SocketAddress socketAddress;
		
		try {
			inteAddress = InetAddress.getByName(server);
			socketAddress = new InetSocketAddress(inteAddress, server_port);
			socket = new Socket();
			socket.connect(socketAddress, timeoutInMs);
			sockOutput = socket.getOutputStream();
			sockInput  = socket.getInputStream();
			in = new BufferedReader(new InputStreamReader(sockInput));
		} catch (Exception e) {
			throw new JRException("Unable to connect to " + server + " " + server_port + " " + e.getMessage());
		}
	}
	
	
	public LivestatusDatasource createDatasource() throws JRException {
		// conduct query syntax check and determine connection parameters
		evaluateQuery();
		
		// Parameters passed to the LivestatusDatasource
		ArrayList<ArrayList<String>> livestatus_data = new ArrayList<ArrayList<String>>();
		HashMap<String,String> map_fielddesc = new HashMap<String, String>(); // Column descriptions
		HashMap<String,String> map_fieldtype = new HashMap<String, String>(); // Column field classes
		
		try
		{
			// setup socket and in/output streams
			setupSocket();
			
			// query the column types and their descriptions
			String table_name = livestatus_query.split("\n")[0].split(" ")[1];
			String desc_query = String.format("GET columns\nFilter: table = %s\nColumnHeaders: off\nResponseHeader: fixed16\nOutputFormat: csv\nSeparators:  10 1 44 124\nKeepAlive: on\n\n", table_name);
			
			sockOutput.write(desc_query.getBytes(), 0, desc_query.getBytes().length); 
			
			// read description information
			String[] responseHeader = in.readLine().split("\\s");
			int response_size = Integer.parseInt(responseHeader[responseHeader.length-1]);
			int offset = 0;
			String line;
			line = in.readLine(); // Skip column headers
			offset += line.getBytes().length + 1;
			String[] tokens;
			while( offset < response_size ){
				line = in.readLine();				
				if( line == null )
					break;
				offset += line.getBytes().length + 1;
				tokens = line.split("\001");
				map_fielddesc.put(tokens[1],tokens[0]);
				if( tokens[1].startsWith("stats_") )
					map_fieldtype.put(tokens[1],"float");
				else
					map_fieldtype.put(tokens[1],tokens[3]);
			}

			// send livestatus query to socket
			sockOutput.write(livestatus_query.getBytes(), 0, livestatus_query.getBytes().length); 
			sockOutput.write(fixed_appendix.getBytes(), 0, fixed_appendix.getBytes().length); 
		
			// check if response is valid
			responseHeader = in.readLine().split("\\s");
			if( ! responseHeader[0].equals("200") ){
				String error = "";
				while(true){
					line = in.readLine();
					if( line == null )
						break;
					error.concat(line+"\n");
				}
				throw new JRException("Livestatus response: \n" + responseHeader + " \n" + error);
			}
			
			// check if response size not exceeding 10MB
			response_size = Integer.parseInt(responseHeader[responseHeader.length-1]);
			if( response_size > 10 * 1024 * 1024 )
				throw new JRException("Livestatus answer exceeds 10 MB. Aborting..");
		
			// read content
			offset = 0;
			offset += line.getBytes().length + 1;
			while( true ){
				line = in.readLine();
				if( line == null )
					break;
				ArrayList<String> tmp_array = new ArrayList<String>();
				for( String field : line.split("\001",-1) ){
					tmp_array.add(field);
				}
				livestatus_data.add(tmp_array);
			}

			// close sockets
			sockInput.close();
			sockOutput.close();
			socket.close();
		}catch (JRException jre) {
			throw jre;
		}
		catch (Exception e) {
			e.printStackTrace();
			throw new JRException(String.format("Unable to process query: " + e.getMessage()));
		}
		
		// Create and return the LivestatusDatasource
		return new LivestatusDatasource(livestatus_data, map_fieldtype, map_fielddesc);
	}
}