KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > management > L1Management


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

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 JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import javax.management.InstanceAlreadyExistsException JavaDoc;
30 import javax.management.MBeanRegistrationException JavaDoc;
31 import javax.management.MBeanServer JavaDoc;
32 import javax.management.MBeanServerFactory JavaDoc;
33 import javax.management.NotCompliantMBeanException JavaDoc;
34 import javax.management.ObjectName JavaDoc;
35 import javax.management.remote.JMXConnectorServer JavaDoc;
36 import javax.management.remote.JMXConnectorServerFactory JavaDoc;
37 import javax.management.remote.JMXServiceURL JavaDoc;
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 JavaDoc mBeanServerLock;
47   private MBeanServer JavaDoc 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 JavaDoc 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 JavaDoc();
68   }
69
70   public synchronized void start() {
71     started.set();
72     Thread JavaDoc registrationThread = new Thread JavaDoc(new Runnable JavaDoc() {
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 JavaDoc e) {
84             // Ignore and try again after 1 second, give the VM a chance to get started
85
try {
86               Thread.sleep(1000);
87             } catch (InterruptedException JavaDoc ie) {
88               new Exception JavaDoc("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 JavaDoc findMBean(final ObjectName JavaDoc objectName, final Class JavaDoc mBeanInterface) throws IOException JavaDoc {
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 JavaDoc, MBeanRegistrationException JavaDoc,
134       NotCompliantMBeanException JavaDoc {
135     synchronized (mBeanServerLock) {
136       if (mBeanServer == null) {
137         if (shouldCreateMBeanServer()) {
138           mBeanServer = MBeanServerFactory.createMBeanServer();
139         } else {
140           List JavaDoc mBeanServers = MBeanServerFactory.findMBeanServer(null);
141           if (!mBeanServers.isEmpty()) {
142             mBeanServer = (MBeanServer JavaDoc) mBeanServers.get(0);
143           } else {
144             throw new MBeanRegistrationException JavaDoc(new Exception JavaDoc("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 JavaDoc url = null;
158     try {
159       // LKC-2990 and LKC-3171: Remove the JMX generic optional logging
160
java.util.logging.Logger JavaDoc jmxLogger = java.util.logging.Logger.getLogger("javax.management.remote.generic");
161       jmxLogger.setLevel(java.util.logging.Level.OFF);
162     } catch (Throwable JavaDoc 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 JavaDoc environment = new HashMap JavaDoc();
168       ProtocolProvider.addTerracottaJmxProvider(environment);
169       environment.put(TunnelingMessageConnectionServer.TUNNELING_HANDLER, tunnelingHandler);
170       url = new JMXServiceURL JavaDoc("terracotta", "localhost", 0);
171       // Normally you should NOT do this in the client, but we have a modified version of jmxremote_optional.jar that
172
// uses a daemon thread to wait for connections so we don't hang the client
173
final JMXConnectorServer JavaDoc connServer = JMXConnectorServerFactory.newJMXConnectorServer(url, environment,
174                                                                                             mBeanServer);
175       connServer.start();
176       logger.info("Terracotta JMX connector available at[" + url + "]");
177     } catch (Exception JavaDoc 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     // We get called very early in the bootstrap process, and can outrun the creation of the default mbean server that
188
// the 1.5 JDK and jconsole uses. If it looks like the default server should start up then return false, otherwise
189
// (1.4 JDK or the com.sun.management.jmxremote property is not set) return true.
190
return forceCreate || Vm.isJDK14() || (Vm.getMajorVersion() > 4 && System.getProperty("com.sun.management.jmxremote") == null);
191   }
192
193 }
194
Popular Tags