package com.tivoli.jmx.tutorial.managedserver;

import javax.management.AttributeList;
import javax.management.Attribute;
import javax.management.monitor.GaugeMonitor;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import java.util.TreeSet;
import java.util.SortedSet;

public class Httpd {
    public static LogFile logfile;
    /**
     * Httpd constructor comment.
     */
    public Httpd() {
	super();
    }

    public static void main(java.lang.String[] args) throws Exception {
	MBeanServer mbs = MBeanServerFactory.createMBeanServer();
	
	SortedSet requestQueue = new TreeSet();
	HandlerPool handlers = new HandlerPool();
	logfile = new LogFile("httpd.log");
	
	ObjectName listenerObjectName = new ObjectName("tutorial:type=Listener");
	ObjectName handlersObjectName = new ObjectName("tutorial:type=HandlerPool");
	ObjectName requestQueueObjectName = new ObjectName("tutorial:type=RequestQueueMBean");
	ObjectName logfileObjectName = new ObjectName("tutorial:type=LogFile,name=Httpd.log");
	
	Object[] listenerParams = {requestQueue};
	String[] listenerSig = {"java.util.SortedSet"};
	mbs.createMBean("com.tivoli.jmx.tutorial.managedserver.Listener", 
			listenerObjectName, 
            null,
			listenerParams, 
			listenerSig);
	
	Object[] requestQueueParams = {requestQueue, new Integer(8)};
	String[] requestQueueSig = {"java.util.SortedSet", "int"};
	mbs.createMBean("com.tivoli.jmx.tutorial.managedserver.RequestQueueMBean", 
			requestQueueObjectName, 
			null,
            requestQueueParams, 
			requestQueueSig);
	
	mbs.registerMBean(handlers, handlersObjectName);
	mbs.registerMBean(logfile, logfileObjectName);

	GaugeMonitor handlerPoolGauge = new GaugeMonitor();
	handlerPoolGauge.setObservedObject(handlersObjectName);
	handlerPoolGauge.setObservedAttribute("Size");
	handlerPoolGauge.setGranularityPeriod(1000);
	handlerPoolGauge.setThresholds(new Integer(4), new Integer(2));
	ObjectName handlerPoolGaugeObjectName = new ObjectName("tutorial:type=GaugeMonitor, target=handlerPool");
	mbs.registerMBean(handlerPoolGauge, handlerPoolGaugeObjectName);

	ObjectName logfileCounterObjectName = new ObjectName("tutorial:type=CounterMonitor, targe=logfile");
	mbs.createMBean("javax.management.monitor.CounterMonitor",
			logfileCounterObjectName,
			null,
			null);
	AttributeList logfileCounterAttributes = new AttributeList();
	logfileCounterAttributes.add(new Attribute("ObservedObject", logfileObjectName));
	logfileCounterAttributes.add(new Attribute("ObservedAttribute", "Size"));
	logfileCounterAttributes.add(new Attribute("GranularityPeriod", new Integer(60000)));
	logfileCounterAttributes.add(new Attribute("Threshold", new Integer(10240)));
	mbs.setAttributes(logfileCounterObjectName, logfileCounterAttributes);
	
	mbs.invoke(listenerObjectName, "startListening", null, null);
	mbs.invoke(handlerPoolGaugeObjectName, "start", null, null);
	mbs.invoke(logfileCounterObjectName, "start", null, null);
	
	while (((Boolean) mbs.getAttribute(listenerObjectName, "Listening")).booleanValue()) {
	    Request r = null;
	    synchronized (requestQueue) {
		while (requestQueue.isEmpty()) {
		    try {
			requestQueue.wait();
		    } catch (InterruptedException x) {
		    }
		}
		r = (Request) requestQueue.first();
		requestQueue.remove(r);
	    }
		
	    Handler h = null;
	    synchronized (handlers) {
		while ((h = handlers.reserve()) == null) {
		    try {
			handlers.wait();
		    } catch (InterruptedException x) {
		    }
		}
	    }
	    h.activate(r);
	}
    }
}