001 /*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements. See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership. The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied. See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 *
020 */
021 package org.apache.qpid.management.web.action;
022
023 import java.io.IOException;
024 import java.lang.management.ManagementFactory;
025 import java.util.HashMap;
026 import java.util.Hashtable;
027 import java.util.Map;
028 import java.util.Properties;
029 import java.util.Map.Entry;
030
031 import javax.management.MBeanAttributeInfo;
032 import javax.management.MBeanInfo;
033 import javax.management.MBeanServer;
034 import javax.management.MalformedObjectNameException;
035 import javax.management.ObjectName;
036 import javax.servlet.RequestDispatcher;
037 import javax.servlet.ServletException;
038 import javax.servlet.http.HttpServlet;
039 import javax.servlet.http.HttpServletRequest;
040 import javax.servlet.http.HttpServletResponse;
041
042 /**
043 * This controller is responsible to provide a jmx perspective of a specific resource.
044 * That means that this controller is querying the Platform MBean server in order to
045 * get metadata for the requested mbean.
046 *
047 * After that metadata will be forwarded to the appropriate view page and therefore
048 * will be shown on the Admin console.
049 *
050 * @author Andrea Gazzarini
051 */
052 public class JmxPerspectiveAction extends HttpServlet
053 {
054 private static final long serialVersionUID = -2411413147821629363L;
055
056 /**
057 * Adapter interface for converting objects on html strings.
058 *
059 * @author Andrea Gazzarini.
060 */
061 interface JavaToHtmlAdapter
062 {
063 /**
064 * Returns an HTML string representation of the given object.
065 *
066 * @param javaObject the object that needs to be converted.
067 * @return an html string containing value of the given object.
068 */
069 String toHtml(Object javaObject);
070 }
071
072 /**
073 * Adapter implementation for Map (and subclasses).
074 */
075 private JavaToHtmlAdapter mapAdapter = new JavaToHtmlAdapter()
076 {
077 @SuppressWarnings("unchecked")
078 public String toHtml(Object javaObject)
079 {
080 Map<String,Object> value = (Map<String, Object>) javaObject;
081
082 // Sanity check : if the map is empty or null there's no need to
083 // do any convertion
084 if (value == null || value.isEmpty())
085 {
086 return "(empty)";
087 }
088
089 StringBuilder builder = new StringBuilder("<ul>");
090 for (Entry<String, Object> entry : value.entrySet())
091 {
092 builder
093 .append("<li>")
094 .append(entry.getKey())
095 .append(" = ")
096 .append(entry.getValue());
097 }
098 builder.append("</ul>");
099 return builder.toString();
100 }
101 };
102
103 private Map<String, JavaToHtmlAdapter> _adapters = new HashMap<String, JavaToHtmlAdapter>();
104
105 @Override
106 public void init() throws ServletException
107 {
108 _adapters.put(Map.class.getName(), mapAdapter);
109 _adapters.put(HashMap.class.getName(),mapAdapter);
110 _adapters.put(Properties.class.getName(),mapAdapter);
111 _adapters.put(Hashtable.class.getName(),mapAdapter);
112 }
113
114 @SuppressWarnings("unchecked")
115 @Override
116 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
117 {
118 String resourceId = null;
119 try
120 {
121 resourceId = request.getParameter("resourceId");
122
123 ObjectName objectName = new ObjectName(resourceId);
124 String [] keyProperties = objectName.getKeyPropertyListString().split(",");
125
126 MBeanServer server = ManagementFactory.getPlatformMBeanServer();
127
128 MBeanInfo metadata = server.getMBeanInfo(objectName);
129
130 Map<String, String> attributes = getAttributes(server, objectName,metadata.getAttributes());
131
132 request.setAttribute("resourceId", objectName);
133 request.setAttribute("metadata",metadata);
134 request.setAttribute("nameAttributes",keyProperties);
135 request.setAttribute("attributes",attributes);
136
137 RequestDispatcher dispatcher = request.getRequestDispatcher("/jmx_perspective.jsp");
138 dispatcher.forward(request,response);
139 } catch(MalformedObjectNameException exception)
140 {
141 request.setAttribute("errorMessage","Malformed Resource ID : supplied value is "+resourceId);
142 request.setAttribute("exception",exception);
143 RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
144 dispatcher.forward(request,response);
145
146 }
147 catch(Exception exception)
148 {
149 request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
150 request.setAttribute("exception",exception);
151 RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
152 dispatcher.forward(request,response);
153 }
154 }
155
156 /**
157 * Starting from an mbean metadata, this method retrieves all the attributes
158 * from the corresponding MBean Server.
159 *
160 * @param server the mbean server where the target mbean is registered.
161 * @param name the name of the target mbean.
162 * @param metadata the metadata of mbean.
163 * @return a map containing all attributes of the given mbean.
164 * @throws Exception when it's not possible to retrieve attributes.
165 */
166 private Map<String, String> getAttributes(MBeanServer server, ObjectName name, MBeanAttributeInfo [] metadata) throws Exception
167 {
168 Map<String,String> result = new HashMap<String, String>(metadata.length);
169 for (MBeanAttributeInfo attribute : metadata)
170 {
171 Object value = server.getAttribute(name, attribute.getName());
172 result.put(attribute.getName(),getAdaptedValue(attribute.getType(), value));
173 }
174 return result;
175 }
176
177 /**
178 * Converts the given attribute value in a html string format.
179 *
180 * @param type the java type of the given attribute value.
181 * @param value the attribute value.
182 * @return a html string format of the given value.
183 */
184 private String getAdaptedValue(String type, Object value)
185 {
186 JavaToHtmlAdapter adapter = _adapters.get(type);
187 return (adapter != null) ? adapter.toHtml(value) : String.valueOf(value);
188 }
189 }
|