summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/dnbd3/status/StatisticsGenerator.java
blob: 777ce7a81664cb5e817b19da428eef5427487daf (plain) (tree)

















































































































































                                                                                                                                          
package org.openslx.dnbd3.status;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.openslx.dnbd3.status.output.EdgeSerializer;
import org.openslx.dnbd3.status.output.OutputMain;
import org.openslx.dnbd3.status.output.ServerStats;
import org.openslx.dnbd3.status.poller.ServerPoller;
import org.openslx.dnbd3.status.rpc.Client;
import org.openslx.dnbd3.status.rpc.Status;
import org.openslx.graph.ClientNode;
import org.openslx.graph.Edge;
import org.openslx.graph.Graph;
import org.openslx.graph.Node;
import org.openslx.graph.ServerNode;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class StatisticsGenerator
{
	private final List<ServerPoller> pollers;
	private volatile long lastUpdate = 0;
	private ExecutorService threadPool = new ThreadPoolExecutor( 1, 6, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>( 100 ) );
	private List<Future<Status>> futureStatusList = new ArrayList<>();
	private List<Status> statusList = new ArrayList<>();
	private final Gson jsonBuilder;

	private final Graph graph = new Graph( "DNBD 3  Status" );
	private byte[] imgData = null;
	private final OutputMain output = new OutputMain();

	public StatisticsGenerator( List<ServerPoller> pollers )
	{
		this.pollers = pollers;
		for ( ServerPoller poller : pollers ) {
			Node server = new ServerNode( poller.getAddress() );
			server.activate();
			graph.addNode( server );
		}
		// Prepare json serializer for graph
		final GsonBuilder gsonBuilder = new GsonBuilder();
		gsonBuilder.excludeFieldsWithoutExposeAnnotation();
		gsonBuilder.registerTypeHierarchyAdapter( Edge.class, new EdgeSerializer() );
		jsonBuilder = gsonBuilder.create();
		output.graph = graph;
		output.servers = new ArrayList<>();
		output.timestamp = 0;
	}

	private synchronized void updateAll()
	{
		futureStatusList.clear();
		for ( final ServerPoller p : pollers ) {
			Future<Status> ret = threadPool.submit( new Callable<Status>() {
				@Override
				public Status call() throws Exception
				{
					return p.update();
				}
			} );
			futureStatusList.add( ret );
		}
		statusList.clear();
		output.servers.clear();
		for ( Future<Status> future : futureStatusList ) {
			Status status;
			try {
				status = future.get();
			} catch ( Exception e ) {
				continue;
			}
			if ( status == null )
				continue;
			statusList.add( status );
			ServerStats srv = new ServerStats();
			srv.address = status.getAddress();
			srv.bytesReceived = status.getBytesReceived();
			srv.bytesSent = status.getBytesSent();
			for ( Client c : status.getClients() ) {
				srv.bytesSent += c.getBytesSent();
			}
			srv.clientCount = status.getClients().size();
			srv.uptime = status.getUptime();
			output.servers.add( srv );
		}
		output.timestamp = System.currentTimeMillis();
		synchronized ( graph ) {
			graph.decay();
			for ( Status status : statusList ) {
				String serverIp = status.getAddress();
				Node server = graph.getNode( serverIp );
				if ( server == null )
					server = new ServerNode( serverIp );
				server.activate();
				for ( Client client : status.getClients() ) {
					if ( client.getAddress() == null )
						continue;
					String ip = client.getAddress().replaceFirst( "\\:\\d+$", "" );
					Node n = graph.getNode( ip );
					if ( n == null )
						n = new ClientNode( ip );
					n.activate();
					graph.setEdge( server, n, ( client.getBytesSent() >> 12 ) + 1 );
				}
			}
			imgData = null;
		}
	}

	private synchronized void ensureUpToDate()
	{
		final long now = System.currentTimeMillis();
		if ( now - lastUpdate > 1900 ) {
			lastUpdate = now;
			updateAll();
		}
	}

	public byte[] getImagePng()
	{
		ensureUpToDate();
		synchronized ( graph ) {
			if ( imgData == null ) {
				imgData = graph.makeNextImage();
			}
		}
		return imgData;
	}

	public String getJson()
	{
		ensureUpToDate();
		synchronized ( graph ) {
			return jsonBuilder.toJson( output );
		}
	}

}