001    package org.shiftone.jrat.core.jmx;
002    
003    
004    import org.shiftone.jrat.core.Environment;
005    import org.shiftone.jrat.util.log.Logger;
006    
007    import javax.management.MBeanServer;
008    import javax.management.MBeanServerFactory;
009    import javax.management.ObjectName;
010    import javax.management.remote.JMXConnectorServer;
011    import javax.management.remote.JMXConnectorServerFactory;
012    import javax.management.remote.JMXServiceURL;
013    import java.rmi.registry.LocateRegistry;
014    import java.rmi.registry.Registry;
015    import java.util.ArrayList;
016    import java.util.Hashtable;
017    
018    
019    /**
020     * @author jeff@shiftone.org (Jeff Drost)
021     */
022    public class ServerJmxRegistry implements JmxRegistry {
023    
024        private static final Logger LOG = Logger.getLogger(ServerJmxRegistry.class);
025        private MBeanServer mBeanServer;
026        private String agentId = Environment.getSettings().getMBeanServerAgentId();
027    
028        // see com.sun.jmx.defaults.JmxProperties
029        public static final String JMX_INITIAL_BUILDER = "javax.management.builder.initial";
030    
031        public ServerJmxRegistry(boolean create) throws Exception {
032    
033            if (create) {
034                this.mBeanServer = createMBeanServer();
035            }
036        }
037    
038    
039        private static MBeanServer createMBeanServer() throws Exception {
040    
041            if (Environment.getSettings().isRmiRegistryCreationEnabled()) {
042    
043                int port = Environment.getSettings().getRmiRegistryPort();
044    
045                LOG.info("Creating local RMI jmx on port " + port + ".");
046    
047                Registry registry = LocateRegistry.createRegistry(port);
048            }
049    
050            LOG.info("Creating MBeanServer (MBeanServerFactory will refer to property '" + JMX_INITIAL_BUILDER + "').");
051    
052            MBeanServer mBeanServer = MBeanServerFactory.createMBeanServer();
053            String urlText = Environment.getSettings().getMBeanServerServerUrl();
054    
055            if (urlText != null) {
056    
057                // column a URL
058                JMXServiceURL url = new JMXServiceURL(urlText);
059    
060                LOG.info("Binding JMXConnectorServer to RMI jmx.");
061    
062                JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null,
063                        mBeanServer);
064    
065                LOG.info("Starting JMXConnectorServer.");
066                connectorServer.start();
067            }
068    
069            return mBeanServer;
070        }
071    
072    
073        protected synchronized MBeanServer getMBeanServer() {
074    
075            if (mBeanServer == null) {
076                ArrayList servers = MBeanServerFactory.findMBeanServer(agentId);
077    
078                if (servers.size() == 0) {
079                    LOG.debug("No MBeanServers were found.");
080    
081                    return null;
082                } else if (servers.size() > 1) {
083                    LOG.warn("More than one MBeanServers (" + servers.size() + ") was found with agentId='" + agentId
084                            + "'.  Returning first.");
085                }
086    
087                mBeanServer = (MBeanServer) servers.get(0);
088            }
089    
090            return mBeanServer;
091        }
092    
093    
094        public boolean isReady() {
095            return (getMBeanServer() != null);
096        }
097    
098    
099        public void registerMBean(Object object, String objectNameText) {
100    
101            LOG.debug("registerMBean...");
102    
103            MBeanServer server = getMBeanServer();
104    
105            if (server == null) {
106                LOG.info("MBeanServer is not available");
107    
108                return;
109            }
110    
111            if (objectNameText == null) {
112                objectNameText = "shiftone.jrat:service=" + object.getClass().getName();
113            }
114    
115            try {
116                LOG.info("registerMBean " + object + " " + objectNameText);
117    
118                ObjectName objectName = new ObjectName(objectNameText);
119                String domain = objectName.getDomain();
120                Hashtable properties = objectName.getKeyPropertyList();
121                int index = 0;
122    
123                // this will loop until an avalible objectName is found
124                while (server.isRegistered(objectName)) {
125                    properties.put("index", String.valueOf(++index));
126    
127                    objectName = new ObjectName(domain, properties);
128                }
129    
130                server.registerMBean(object, objectName);
131            }
132            catch (Exception e) {
133                LOG.warn("MBean registration failed", e);
134            }
135        }
136    }