package com.topsy.jmxproxy.jmx;

import com.topsy.jmxproxy.core.Attribute;
import com.topsy.jmxproxy.core.Host;
import com.topsy.jmxproxy.core.MBean;

import java.io.IOException;

import javax.management.MBeanAttributeInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConnectionWorker {
    private static final Logger LOG = LoggerFactory.getLogger(ConnectionWorker.class);

    private Host host;
    private JMXServiceURL url;
    private long cacheTime;
    private long accessTime;

    public ConnectionWorker(String hostName) throws Exception {
        url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + hostName + "/jmxrmi");
    }

    public Host getHost() {
        return getHost(5);
    }

    public synchronized Host getHost(int cacheDuration) {
        if (host == null || System.currentTimeMillis() - cacheTime * 60 * 1000 > cacheDuration) {
            LOG.debug("fetching new values for " + url);
            fetchJMXValues();
        }

        accessTime = System.currentTimeMillis();
        return host;
    }

    public boolean isExpired() {
        return isExpired(5);
    }

    public boolean isExpired(int accessDuration) {
        return System.currentTimeMillis() - accessTime * 60 * 1000 > accessDuration;
    }

    private void fetchJMXValues() {
        JMXConnector connection = null;
        MBeanServerConnection server = null;

        try {
            connection = JMXConnectorFactory.connect(url, null);
            server = connection.getMBeanServerConnection();
            LOG.debug("connected to mbean server " + url);

            host = new Host();
            for (String domainName : server.getDomains()) {
                LOG.debug("discovered domain " + domainName);

                for (ObjectName mbeanName : server.queryNames(new ObjectName(domainName + ":*"), null)) {
                    LOG.debug("discovered mbean " + mbeanName);

                    MBean mbean = host.addMBean(domainName, mbeanName.toString());
                    for (MBeanAttributeInfo attributeObject : server.getMBeanInfo(mbeanName).getAttributes()) {
                        if (attributeObject.isReadable()) {
                            try {
                                Attribute attribute = mbean.addAttribute(attributeObject.getName());
                                attribute.setAttributeValue(server.getAttribute(mbeanName, attributeObject.getName()));
                            } catch (java.rmi.UnmarshalException e) {
                                LOG.error("failed to add attribute " + attributeObject.toString() + ": " + e);
                            } catch (javax.management.AttributeNotFoundException e) {
                                LOG.error("failed to add attribute " + attributeObject.toString() + ": " + e);
                            } catch (javax.management.RuntimeMBeanException e) {
                                LOG.error("failed to add attribute " + attributeObject.toString() + ": " + e);
                            } catch (java.lang.NullPointerException e) {
                                LOG.error("failed to add attribute " + attributeObject.toString() + ": " + e);
                            }
                        }
                    }
                }
            }

            cacheTime = System.currentTimeMillis();
        } catch (Exception e) {
            LOG.error("failed to connect to " + url, e);
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                    LOG.debug("disconnected from " + url);
                } catch (IOException e) {
                    LOG.error("failed to disconnect from " + url, e);
                } finally {
                    connection = null;
                }
            }
        }
    }
}

@@ -1083,28 +1083,16 @@
 cheTime 
-* 60 * 1000 
 %3E cacheD
@@ -1090,32 +1090,44 @@
  %3E cacheDuration
+ * 60 * 1000
 ) %7B%0A            
@@ -1468,20 +1468,8 @@
 ime 
-* 60 * 1000 
 %3E ac
@@ -1480,16 +1480,28 @@
 Duration
+ * 60 * 1000
 ;%0A    %7D%0A

Fix confusion with cache timings properly this time.