1 5 package com.tc.management; 6 7 import com.tc.exception.TCRuntimeException; 8 import com.tc.logging.TCLogger; 9 import com.tc.logging.TCLogging; 10 import com.tc.management.beans.L1MBeanNames; 11 import com.tc.management.beans.MBeanNames; 12 import com.tc.management.beans.sessions.SessionMonitor; 13 import com.tc.management.beans.sessions.SessionMonitorMBean; 14 import com.tc.management.beans.tx.ClientTxMonitor; 15 import com.tc.management.beans.tx.ClientTxMonitorMBean; 16 import com.tc.management.exposed.SessionsProduct; 17 import com.tc.management.exposed.TerracottaCluster; 18 import com.tc.management.remote.protocol.ProtocolProvider; 19 import com.tc.management.remote.protocol.terracotta.TunnelingEventHandler; 20 import com.tc.management.remote.protocol.terracotta.TunnelingMessageConnectionServer; 21 import com.tc.util.concurrent.SetOnceFlag; 22 import com.tc.util.runtime.Vm; 23 24 import java.io.IOException ; 25 import java.util.HashMap ; 26 import java.util.List ; 27 import java.util.Map ; 28 29 import javax.management.InstanceAlreadyExistsException ; 30 import javax.management.MBeanRegistrationException ; 31 import javax.management.MBeanServer ; 32 import javax.management.MBeanServerFactory ; 33 import javax.management.NotCompliantMBeanException ; 34 import javax.management.ObjectName ; 35 import javax.management.remote.JMXConnectorServer ; 36 import javax.management.remote.JMXConnectorServerFactory ; 37 import javax.management.remote.JMXServiceURL ; 38 39 public final class L1Management extends TerracottaManagement { 40 41 private static final TCLogger logger = TCLogging.getLogger(L1Management.class); 42 private static boolean forceCreate = false; 43 44 private final SetOnceFlag started; 45 private final TunnelingEventHandler tunnelingHandler; 46 private final Object mBeanServerLock; 47 private MBeanServer mBeanServer; 48 private final ClientTxMonitor clientTxBean; 49 private final SessionMonitor internalSessionBean; 50 private final SessionsProduct publicSessionBean; 51 private final TerracottaCluster clusterBean; 52 53 public L1Management(final TunnelingEventHandler tunnelingHandler) { 54 super(); 55 started = new SetOnceFlag(); 56 this.tunnelingHandler = tunnelingHandler; 57 try { 58 clientTxBean = new ClientTxMonitor(); 59 internalSessionBean = new SessionMonitor(); 60 publicSessionBean = new SessionsProduct(internalSessionBean, clientTxBean); 61 clusterBean = new TerracottaCluster(); 62 } catch (NotCompliantMBeanException ncmbe) { 63 throw new TCRuntimeException( 64 "Unable to construct one of the L1 MBeans: this is a programming error in one of those beans", 65 ncmbe); 66 } 67 mBeanServerLock = new Object (); 68 } 69 70 public synchronized void start() { 71 started.set(); 72 Thread registrationThread = new Thread (new Runnable () { 73 74 private final int MAX_ATTEMPTS = 60 * 5; 75 76 public void run() { 77 boolean registered = false; 78 int attemptCounter = 0; 79 while (!registered && attemptCounter++ < MAX_ATTEMPTS) { 80 try { 81 attemptToRegister(); 82 registered = true; 83 } catch (Exception e) { 84 try { 86 Thread.sleep(1000); 87 } catch (InterruptedException ie) { 88 new Exception ("JMX registration thread interrupted, management beans will not be available", ie) 89 .printStackTrace(); 90 } 91 } 92 } 93 if (registered) { 94 tunnelingHandler.jmxIsReady(); 95 } else { 96 logger.error("Aborted attempts to register management" + " beans after " + (MAX_ATTEMPTS / 60) 97 + " min of trying."); 98 } 99 } 100 }, "L1Management JMX registration"); 101 registrationThread.setDaemon(true); 102 registrationThread.start(); 103 } 104 105 public Object findMBean(final ObjectName objectName, final Class mBeanInterface) throws IOException { 106 if (objectName.equals(MBeanNames.CLIENT_TX_INTERNAL)) return clientTxBean; 107 else if (objectName.equals(MBeanNames.SESSION_INTERNAL)) return internalSessionBean; 108 else if (objectName.equals(L1MBeanNames.SESSION_PRODUCT_PUBLIC)) return publicSessionBean; 109 else { 110 synchronized (mBeanServerLock) { 111 if (mBeanServer != null) { return findMBean(objectName, mBeanInterface, mBeanServer); } 112 } 113 } 114 return null; 115 } 116 117 public ClientTxMonitorMBean findClientTxMonitorMBean() { 118 return clientTxBean; 119 } 120 121 public SessionMonitorMBean findSessionMonitorMBean() { 122 return internalSessionBean; 123 } 124 125 public synchronized static void forceCreateMBeanServer() { 126 forceCreate = true; 127 } 128 129 public TerracottaCluster getTerracottaCluster() { 130 return clusterBean; 131 } 132 133 private void attemptToRegister() throws InstanceAlreadyExistsException , MBeanRegistrationException , 134 NotCompliantMBeanException { 135 synchronized (mBeanServerLock) { 136 if (mBeanServer == null) { 137 if (shouldCreateMBeanServer()) { 138 mBeanServer = MBeanServerFactory.createMBeanServer(); 139 } else { 140 List mBeanServers = MBeanServerFactory.findMBeanServer(null); 141 if (!mBeanServers.isEmpty()) { 142 mBeanServer = (MBeanServer ) mBeanServers.get(0); 143 } else { 144 throw new MBeanRegistrationException (new Exception ("Waiting for default MBeanServer")); 145 } 146 } 147 addJMXConnectors(); 148 } 149 } 150 mBeanServer.registerMBean(clientTxBean, MBeanNames.CLIENT_TX_INTERNAL); 151 mBeanServer.registerMBean(internalSessionBean, MBeanNames.SESSION_INTERNAL); 152 mBeanServer.registerMBean(publicSessionBean, L1MBeanNames.SESSION_PRODUCT_PUBLIC); 153 mBeanServer.registerMBean(clusterBean, L1MBeanNames.CLUSTER_BEAN_PUBLIC); 154 } 155 156 private void addJMXConnectors() { 157 JMXServiceURL url = null; 158 try { 159 java.util.logging.Logger jmxLogger = java.util.logging.Logger.getLogger("javax.management.remote.generic"); 161 jmxLogger.setLevel(java.util.logging.Level.OFF); 162 } catch (Throwable t) { 163 logger.warn("Unable to disable default logging in Sun's JMX package; when Terracotta clients go" 164 + " up/down you may see stack traces printed to the log"); 165 } 166 try { 167 final Map environment = new HashMap (); 168 ProtocolProvider.addTerracottaJmxProvider(environment); 169 environment.put(TunnelingMessageConnectionServer.TUNNELING_HANDLER, tunnelingHandler); 170 url = new JMXServiceURL ("terracotta", "localhost", 0); 171 final JMXConnectorServer connServer = JMXConnectorServerFactory.newJMXConnectorServer(url, environment, 174 mBeanServer); 175 connServer.start(); 176 logger.info("Terracotta JMX connector available at[" + url + "]"); 177 } catch (Exception e) { 178 if (url != null) { 179 logger.warn("Unable to start embedded JMX connector for url[" + url + "]", e); 180 } else { 181 logger.warn("Unable to construct embedded JMX connector URL with params (terracotta, localhost, 0)"); 182 } 183 } 184 } 185 186 private synchronized static boolean shouldCreateMBeanServer() { 187 return forceCreate || Vm.isJDK14() || (Vm.getMajorVersion() > 4 && System.getProperty("com.sun.management.jmxremote") == null); 191 } 192 193 } 194 | Popular Tags |