001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.catalina.manager;
019:
020: import java.io.IOException;
021: import java.io.PrintWriter;
022: import java.util.Iterator;
023: import java.util.Set;
024: import javax.management.MBeanServer;
025: import javax.management.ObjectName;
026: import javax.management.MBeanInfo;
027: import javax.management.MBeanAttributeInfo;
028: import javax.management.Attribute;
029: import javax.servlet.ServletException;
030: import javax.servlet.http.HttpServlet;
031: import javax.servlet.http.HttpServletRequest;
032: import javax.servlet.http.HttpServletResponse;
033:
034: import org.apache.tomcat.util.modeler.Registry;
035:
036: /**
037: * This servlet will dump JMX attributes in a simple format
038: * and implement proxy services for modeler.
039: *
040: * @author Costin Manolache
041: */
042: public class JMXProxyServlet extends HttpServlet {
043: // ----------------------------------------------------- Instance Variables
044:
045: /**
046: * MBean server.
047: */
048: protected MBeanServer mBeanServer = null;
049: protected Registry registry;
050:
051: // --------------------------------------------------------- Public Methods
052:
053: /**
054: * Initialize this servlet.
055: */
056: public void init() throws ServletException {
057: // Retrieve the MBean server
058: registry = Registry.getRegistry(null, null);
059: mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
060: }
061:
062: /**
063: * Process a GET request for the specified resource.
064: *
065: * @param request The servlet request we are processing
066: * @param response The servlet response we are creating
067: *
068: * @exception IOException if an input/output error occurs
069: * @exception ServletException if a servlet-specified error occurs
070: */
071: public void doGet(HttpServletRequest request,
072: HttpServletResponse response) throws IOException,
073: ServletException {
074:
075: response.setContentType("text/plain");
076:
077: PrintWriter writer = response.getWriter();
078:
079: if (mBeanServer == null) {
080: writer.println("Error - No mbean server");
081: return;
082: }
083:
084: String qry = request.getParameter("set");
085: if (qry != null) {
086: String name = request.getParameter("att");
087: String val = request.getParameter("val");
088:
089: setAttribute(writer, qry, name, val);
090: return;
091: }
092: qry = request.getParameter("get");
093: if (qry != null) {
094: String name = request.getParameter("att");
095: getAttribute(writer, qry, name);
096: return;
097: }
098: qry = request.getParameter("qry");
099: if (qry == null) {
100: qry = "*:*";
101: }
102:
103: listBeans(writer, qry);
104:
105: }
106:
107: public void getAttribute(PrintWriter writer, String onameStr,
108: String att) {
109: try {
110: ObjectName oname = new ObjectName(onameStr);
111: Object value = mBeanServer.getAttribute(oname, att);
112: writer.println("OK - Attribute get '" + onameStr + "' - "
113: + att + "= " + escape(value.toString()));
114: } catch (Exception ex) {
115: writer.println("Error - " + ex.toString());
116: }
117: }
118:
119: public void setAttribute(PrintWriter writer, String onameStr,
120: String att, String val) {
121: try {
122: ObjectName oname = new ObjectName(onameStr);
123: String type = registry.getType(oname, att);
124: Object valueObj = registry.convertValue(type, val);
125: mBeanServer.setAttribute(oname,
126: new Attribute(att, valueObj));
127: writer.println("OK - Attribute set");
128: } catch (Exception ex) {
129: writer.println("Error - " + ex.toString());
130: }
131: }
132:
133: public void listBeans(PrintWriter writer, String qry) {
134:
135: Set names = null;
136: try {
137: names = mBeanServer.queryNames(new ObjectName(qry), null);
138: writer.println("OK - Number of results: " + names.size());
139: writer.println();
140: } catch (Exception e) {
141: writer.println("Error - " + e.toString());
142: return;
143: }
144:
145: Iterator it = names.iterator();
146: while (it.hasNext()) {
147: ObjectName oname = (ObjectName) it.next();
148: writer.println("Name: " + oname.toString());
149:
150: try {
151: MBeanInfo minfo = mBeanServer.getMBeanInfo(oname);
152: // can't be null - I thinl
153: String code = minfo.getClassName();
154: if ("org.apache.commons.modeler.BaseModelMBean"
155: .equals(code)) {
156: code = (String) mBeanServer.getAttribute(oname,
157: "modelerType");
158: }
159: writer.println("modelerType: " + code);
160:
161: MBeanAttributeInfo attrs[] = minfo.getAttributes();
162: Object value = null;
163:
164: for (int i = 0; i < attrs.length; i++) {
165: if (!attrs[i].isReadable())
166: continue;
167: if (!isSupported(attrs[i].getType()))
168: continue;
169: String attName = attrs[i].getName();
170: if (attName.indexOf("=") >= 0
171: || attName.indexOf(":") >= 0
172: || attName.indexOf(" ") >= 0) {
173: continue;
174: }
175:
176: try {
177: value = mBeanServer
178: .getAttribute(oname, attName);
179: } catch (Throwable t) {
180: log("Error getting attribute " + oname + " "
181: + attName + " " + t.toString());
182: continue;
183: }
184: if (value == null)
185: continue;
186: if ("modelerType".equals(attName))
187: continue;
188: String valueString = value.toString();
189: writer
190: .println(attName + ": "
191: + escape(valueString));
192: }
193: } catch (Exception e) {
194: // Ignore
195: }
196: writer.println();
197: }
198:
199: }
200:
201: public String escape(String value) {
202: // The only invalid char is \n
203: // We also need to keep the string short and split it with \nSPACE
204: // XXX TODO
205: int idx = value.indexOf("\n");
206: if (idx < 0)
207: return value;
208:
209: int prev = 0;
210: StringBuffer sb = new StringBuffer();
211: while (idx >= 0) {
212: appendHead(sb, value, prev, idx);
213:
214: sb.append("\\n\n ");
215: prev = idx + 1;
216: if (idx == value.length() - 1)
217: break;
218: idx = value.indexOf('\n', idx + 1);
219: }
220: if (prev < value.length())
221: appendHead(sb, value, prev, value.length());
222: return sb.toString();
223: }
224:
225: private void appendHead(StringBuffer sb, String value, int start,
226: int end) {
227: if (end < 1)
228: return;
229:
230: int pos = start;
231: while (end - pos > 78) {
232: sb.append(value.substring(pos, pos + 78));
233: sb.append("\n ");
234: pos = pos + 78;
235: }
236: sb.append(value.substring(pos, end));
237: }
238:
239: public boolean isSupported(String type) {
240: return true;
241: }
242: }
|