001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.management;
005:
006: import com.tc.management.beans.MBeanNames;
007: import com.tc.management.beans.sessions.SessionMonitorMBean;
008: import com.tc.net.TCSocketAddress;
009:
010: import java.io.IOException;
011: import java.util.Collections;
012: import java.util.HashMap;
013: import java.util.Iterator;
014: import java.util.Map;
015: import java.util.Set;
016:
017: import javax.management.MBeanServerConnection;
018: import javax.management.MBeanServerInvocationHandler;
019: import javax.management.MalformedObjectNameException;
020: import javax.management.ObjectName;
021: import javax.management.Query;
022: import javax.management.QueryExp;
023:
024: public abstract class TerracottaManagement {
025:
026: private static final ManagementResources MANAGEMENT_RESOURCES = new ManagementResources();
027:
028: public static class Type {
029:
030: private static final Map typesByName = Collections
031: .synchronizedMap(new HashMap());
032: public static final Type DsoClient = new Type(
033: MANAGEMENT_RESOURCES.getDsoClientType());
034: public static final Type Sessions = new Type(
035: MANAGEMENT_RESOURCES.getSessionsType());
036: public static final Type Server = new Type(MANAGEMENT_RESOURCES
037: .getTerracottaServerType());
038: public static final Type Cluster = new Type(
039: MANAGEMENT_RESOURCES.getTerracottaClusterType());
040:
041: private final String type;
042:
043: private Type(final String type) {
044: this .type = type;
045: typesByName.put(type, this );
046: }
047:
048: public String toString() {
049: return type;
050: }
051:
052: static Type getType(String name) {
053: return (Type) typesByName.get(name);
054: }
055: }
056:
057: public static class Subsystem {
058:
059: private static final Map subsystemByName = Collections
060: .synchronizedMap(new HashMap());
061: public static final Subsystem Tx = new Subsystem(
062: MANAGEMENT_RESOURCES.getTransactionSubsystem());
063: public static final Subsystem Locking = new Subsystem(
064: MANAGEMENT_RESOURCES.getLockingSubsystem());
065: public static final Subsystem ObjectManagement = new Subsystem(
066: MANAGEMENT_RESOURCES.getObjectManagementSubsystem());
067: public static final Subsystem None = new Subsystem(
068: MANAGEMENT_RESOURCES.getNoneSubsystem());
069:
070: private final String subsystem;
071:
072: private Subsystem(final String subsystem) {
073: this .subsystem = subsystem;
074: subsystemByName.put(subsystem, this );
075: }
076:
077: public String toString() {
078: return subsystem;
079: }
080:
081: static Subsystem getSubsystem(String name) {
082: return (Subsystem) subsystemByName.get(name);
083: }
084: }
085:
086: public static interface MBeanKeys {
087: public static final String TYPE = "type";
088: public static final String NODE = "node";
089: public static final String SUBSYSTEM = "subsystem";
090: public static final String NAME = "name";
091: }
092:
093: public static final String PUBLIC_DOMAIN = MANAGEMENT_RESOURCES
094: .getPublicMBeanDomain();
095: public static final String INTERNAL_DOMAIN = MANAGEMENT_RESOURCES
096: .getInternalMBeanDomain();
097:
098: private static final String COMMA = ",";
099: private static final String COLON = ":";
100: private static final String EQUALS = "=";
101: private static final String SLASH = "/";
102:
103: private static final String NODE_PREFIX = "clients" + EQUALS
104: + "Clients";
105:
106: private static final String NODE = System
107: .getProperty(MANAGEMENT_RESOURCES
108: .getNodeNameSystemProperty());
109:
110: public static ObjectName createObjectName(final Type type,
111: final Subsystem subsystem,
112: final TCSocketAddress remoteBeanHome,
113: final String uiFriendlyName, final boolean isPublic)
114: throws MalformedObjectNameException {
115: final StringBuffer objName = new StringBuffer(
116: isPublic ? PUBLIC_DOMAIN : INTERNAL_DOMAIN);
117: objName.append(COLON);
118: if (NODE != null) {
119: objName.append(NODE_PREFIX).append(COMMA).append(
120: MBeanKeys.NODE).append(EQUALS).append(NODE).append(
121: COMMA);
122: } else if (remoteBeanHome != null) {
123: objName.append(NODE_PREFIX).append(COMMA).append(
124: MBeanKeys.NODE).append(EQUALS).append(
125: remoteBeanHome.getAddress().getCanonicalHostName())
126: .append(SLASH).append(remoteBeanHome.getPort())
127: .append(COMMA);
128: }
129: objName.append(MBeanKeys.TYPE).append(EQUALS).append(type);
130: if (subsystem != Subsystem.None) {
131: objName.append(COMMA).append(MBeanKeys.SUBSYSTEM).append(
132: EQUALS).append(subsystem);
133: }
134: objName.append(COMMA).append(MBeanKeys.NAME).append(EQUALS)
135: .append(uiFriendlyName);
136: return new ObjectName(objName.toString());
137: }
138:
139: public static ObjectName addNodeInfo(ObjectName objName,
140: TCSocketAddress addr) throws MalformedObjectNameException {
141: if (objName.getKeyProperty(MBeanKeys.NODE) != null) {
142: return objName;
143: }
144:
145: String keyProperty = objName
146: .getKeyProperty(MBeanKeys.SUBSYSTEM);
147: Subsystem subsystem = keyProperty != null ? Subsystem
148: .getSubsystem(keyProperty) : Subsystem.None;
149: return createObjectName(Type.getType(objName
150: .getKeyProperty(MBeanKeys.TYPE)),
151: (subsystem != null ? subsystem : Subsystem.None), addr,
152: objName.getKeyProperty(MBeanKeys.NAME), objName
153: .getDomain().equals(PUBLIC_DOMAIN));
154: }
155:
156: public abstract Object findMBean(final ObjectName objectName,
157: final Class mBeanInterface) throws Exception;
158:
159: public static final Object findMBean(final ObjectName objectName,
160: final Class mBeanInterface,
161: MBeanServerConnection mBeanServer) throws IOException {
162: final Set matchingBeans = mBeanServer.queryMBeans(objectName,
163: null);
164: final Iterator beanPos = matchingBeans.iterator();
165: if (beanPos.hasNext()) {
166: return MBeanServerInvocationHandler.newProxyInstance(
167: mBeanServer, objectName, mBeanInterface, false);
168: }
169: return null;
170: }
171:
172: public static final QueryExp matchAllTerracottaMBeans() {
173: try {
174: return Query.or(new ObjectName(PUBLIC_DOMAIN + ":*"),
175: new ObjectName(INTERNAL_DOMAIN + ":*"));
176: } catch (MalformedObjectNameException e) {
177: throw new RuntimeException(e);
178: }
179: }
180:
181: public static final String quoteIfNecessary(String objectNamePart) {
182: if (objectNamePart.matches("[,=:*?\"']")) {
183: return ObjectName.quote(objectNamePart);
184: }
185: return objectNamePart;
186: }
187:
188: public static final Set getAllSessionMonitorMBeans(
189: MBeanServerConnection mbs)
190: throws MalformedObjectNameException, NullPointerException,
191: IOException {
192: return mbs.queryNames(new ObjectName(
193: MBeanNames.SESSION_INTERNAL.getCanonicalName() + ",*"),
194: null);
195: }
196:
197: public static final SessionMonitorMBean getClientSessionMonitorMBean(
198: MBeanServerConnection mbs, Set sessionMonitorMBeans,
199: String nodeName) throws IOException {
200: for (Iterator iter = sessionMonitorMBeans.iterator(); iter
201: .hasNext();) {
202: ObjectName smObjectName = (ObjectName) iter.next();
203: if (nodeName.equals(smObjectName
204: .getKeyProperty(MBeanKeys.NODE))) {
205: return (SessionMonitorMBean) TerracottaManagement
206: .findMBean(smObjectName,
207: SessionMonitorMBean.class, mbs);
208: }
209: }
210: throw new AssertionError("No SessionMonitorMBean found for "
211: + nodeName);
212: }
213: }
|