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.ui.jmx;
022
023 import java.math.BigInteger;
024 import java.util.ArrayList;
025 import java.util.Arrays;
026 import java.util.Iterator;
027 import java.util.List;
028 import java.util.Set;
029
030 import javax.management.Attribute;
031 import javax.management.AttributeList;
032 import javax.management.InstanceNotFoundException;
033 import javax.management.JMException;
034 import javax.management.MBeanAttributeInfo;
035 import javax.management.MBeanException;
036 import javax.management.MBeanInfo;
037 import javax.management.MBeanNotificationInfo;
038 import javax.management.MBeanOperationInfo;
039 import javax.management.MBeanServerConnection;
040 import javax.management.ObjectInstance;
041 import javax.management.ObjectName;
042 import javax.management.ReflectionException;
043
044 import org.apache.qpid.management.ui.ApplicationRegistry;
045 import org.apache.qpid.management.ui.ManagedBean;
046 import org.apache.qpid.management.ui.ManagedServer;
047 import org.apache.qpid.management.ui.exceptions.ManagementConsoleException;
048 import org.apache.qpid.management.ui.model.AttributeData;
049 import org.apache.qpid.management.ui.model.ManagedAttributeModel;
050 import org.apache.qpid.management.ui.model.NotificationInfoModel;
051 import org.apache.qpid.management.ui.model.OperationData;
052 import org.apache.qpid.management.ui.model.OperationDataModel;
053 import org.apache.qpid.management.ui.model.ParameterData;
054 import org.apache.qpid.management.ui.views.ViewUtility;
055
056 /**
057 * Utility class for all mbeanserver related operations. Keeps all JMX code out from view and model classes
058 * @author Bhupendra Bhardwaj
059 */
060 public class MBeanUtility
061 {
062 public static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE);
063 public static final BigInteger MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE);
064 /**
065 * Retrieves the MBeanInfo from MBeanServer and stores in the application registry
066 * @param mbean managed bean
067 * @return MBeanInfo
068 * @throws Exception, if server connection is null or if server throws Exception
069 */
070 public static MBeanInfo getMBeanInfo(ManagedBean mbean) throws Exception
071 {
072 ManagedServer server = mbean.getServer();
073 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
074
075 MBeanServerConnection mbsc = serverRegistry.getServerConnection();
076 if (mbsc == null)
077 {
078 throw new ManagementConsoleException("Server connection is broken");
079 }
080
081 JMXManagedObject jmxbean = (JMXManagedObject)mbean;
082 MBeanInfo mbeanInfo = mbsc.getMBeanInfo(jmxbean.getObjectName());
083 serverRegistry.putMBeanInfo(mbean, mbeanInfo);
084
085 // populate the server registry with attribute and operation info
086 getAttributes(mbean);
087 getOperations(mbean);
088
089 return mbeanInfo;
090 }
091
092 /**
093 * executes the MBean operation
094 * @param mbean
095 * @param opData
096 * @return MBean operation return value
097 * @throws Exception if server connection is broken or if operation execution fails on the mbean server
098 */
099 public static Object execute(ManagedBean mbean, OperationData opData) throws Exception
100 {
101 String opName = opData.getName();
102 Object[] values = null;
103 String[] signature = null;
104
105 List<ParameterData> params = opData.getParameters();
106 if (params != null && !params.isEmpty())
107 {
108 signature = new String[params.size()];;
109 values = new Object[params.size()];
110 for (int i = 0; i < params.size(); i++)
111 {
112 signature[i] = params.get(i).getType();
113 values[i] = params.get(i).getValue();
114 }
115 }
116
117 ManagedServer server = mbean.getServer();
118 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
119
120 MBeanServerConnection mbsc = serverRegistry.getServerConnection();
121 if (mbsc == null)
122 {
123 throw new ManagementConsoleException("Server connection is broken");
124 // TODO
125 // try and get the connection again if it was disconnected
126 }
127 JMXManagedObject jmxbean = (JMXManagedObject)mbean;
128 return mbsc.invoke(jmxbean.getObjectName(), opName, values, signature);
129 }
130
131 /**
132 * @see MBeanUtility#handleException(ManagedBean, Exception)
133 */
134 public static void handleException(Exception ex)
135 {
136 handleException(null, ex);
137 }
138
139 /**
140 * handels the exception received. Shows the exception to the user in best suitable way
141 * @param mbean managed bean
142 * @param ex Exception
143 */
144 public static void handleException(ManagedBean mbean, Throwable ex)
145 {
146 if (mbean == null)
147 {
148 ViewUtility.popupErrorMessage("Error", "Managed Object is null \n" + ex.toString());
149 printStackTrace(ex);
150 }
151 else if (ex instanceof ReflectionException)
152 {
153 ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Server has thrown error \n" + ex.toString());
154 printStackTrace(ex);
155 }
156 else if (ex instanceof InstanceNotFoundException)
157 {
158 ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Managed Object Not Found \n" + ex.toString());
159 printStackTrace(ex);
160 }
161 else if (ex instanceof MBeanException)
162 {
163 String cause = ((MBeanException)ex).getTargetException().getMessage();
164 if (cause == null)
165 cause = ex.toString();
166 ViewUtility.popupInfoMessage(mbean.getInstanceName(), cause);
167 }
168 else if (ex instanceof JMException)
169 {
170 ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Management Exception occured \n" + ex.toString());
171 }
172 else if (ex instanceof ManagementConsoleException)
173 {
174 ViewUtility.popupErrorMessage(mbean.getInstanceName(), ex.getMessage());
175 }
176 else if (ex instanceof SecurityException)
177 {
178 ViewUtility.popupErrorMessage(mbean.getInstanceName(), ex.getMessage());
179 }
180 else
181 {
182 if (ex.getCause() != null)
183 {
184 handleException(mbean, ex.getCause());
185 }
186 else
187 {
188 String msg = ex.getMessage();
189 if (msg == null)
190 {
191 msg = ex.toString();
192 }
193 ViewUtility.popupErrorMessage(mbean.getInstanceName(), msg);
194 printStackTrace(ex);
195 }
196 }
197
198 }
199
200 /**
201 * Registers the notification listener with the MBeanServer
202 * @param mbean managed bean
203 * @param name notification name
204 * @param type notification type
205 * @throws Exception if server connection is broken or if listener could not be created
206 */
207 public static void createNotificationlistener(ManagedBean mbean, String name, String type)
208 throws Exception
209 {
210 JMXManagedObject jmxbean = (JMXManagedObject)mbean;
211 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
212 serverRegistry.addNotificationListener(mbean, name, type);
213 MBeanServerConnection mbsc = serverRegistry.getServerConnection();
214
215 if (mbsc == null)
216 {
217 throw new ManagementConsoleException("Server connection is broken");
218 }
219 mbsc.addNotificationListener(jmxbean.getObjectName(), serverRegistry.getNotificationListener(), null, null);
220 }
221
222 public static void removeNotificationListener(ManagedBean mbean, String name, String type) throws Exception
223 {
224 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
225 serverRegistry.removeNotificationListener(mbean, name, type);
226 }
227
228 /**
229 * Checks if the server registry contains attribute information for this mbean. If not then it queries the
230 * mbean server for complete mbean information, else it gets the latest value of the given attribute
231 * from mbean server.
232 * @return attribute data for the given mbean attribute
233 */
234 public static AttributeData getAttributeData(ManagedBean mbean, String attribute) throws Exception
235 {
236 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
237 ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
238 if (attributeModel == null)
239 {
240 // If process is here, it means the mbeanInfo is not retrieved from mbean server even once for this mbean
241 getMBeanInfo(mbean);
242 }
243 else
244 {
245 // refresh attribute value from mbean server
246 refreshAttribute(mbean, attribute);
247 }
248 attributeModel = serverRegistry.getAttributeModel(mbean);
249 return attributeModel.getAttribute(attribute);
250 }
251
252 /**
253 * Retrieves the latest attribute value from mbean server for the given mbean attribute
254 * and also sets that value in the attribute model in the server registry
255 * @return latest attribute value for the given mbean attribute
256 */
257 public static Object refreshAttribute(ManagedBean mbean, String attribute) throws Exception
258 {
259 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
260 MBeanServerConnection mbsc = serverRegistry.getServerConnection();
261
262 if (mbsc == null)
263 {
264 throw new ManagementConsoleException("Server connection is broken");
265 }
266
267 Object value = mbsc.getAttribute(((JMXManagedObject)mbean).getObjectName(), attribute);
268 // update the attribute data in server registry for this attribute
269 ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
270 attributeModel.setAttributeValue(attribute, value);
271 return value;
272 }
273
274 /**
275 * Retrieves the attribute values from MBeanSever and stores in the server registry.
276 * @param mbean
277 * @return the attribute model
278 * @throws Exception if attributes can not be retrieved from MBeanServer
279 */
280 public static ManagedAttributeModel getAttributes(ManagedBean mbean) throws Exception
281 {
282 ObjectName objName = ((JMXManagedObject)mbean).getObjectName();
283 String[] attributes = null;
284 AttributeList list = null;
285
286 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
287 MBeanServerConnection mbsc = serverRegistry.getServerConnection();
288 MBeanAttributeInfo[] attributesInfo = null;
289 ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
290
291 if (attributeModel == null)
292 {
293 // If the process is here, then it means the attribute values are not retrieved from mbean server
294 // even once for this mbean. Create attribute model, retrieve values from mbean server and
295 // set the attribute model in server registry for this mbean
296 attributeModel = new ManagedAttributeModel();
297 attributesInfo = serverRegistry.getMBeanInfo(mbean).getAttributes();
298 attributes = new String[attributesInfo.length];
299 for (int i = 0; i< attributesInfo.length ; i++)
300 {
301 attributes[i] = attributesInfo[i].getName();
302 attributeModel.setAttributeDescription(attributes[i], attributesInfo[i].getDescription());
303 attributeModel.setAttributeWritable(attributes[i], attributesInfo[i].isWritable());
304 attributeModel.setAttributeReadable(attributes[i], attributesInfo[i].isReadable());
305 }
306 }
307 else
308 {
309 attributes = attributeModel.getAttributeNames().toArray(new String[0]);
310 }
311
312 if (attributes.length != 0)
313 {
314 list = mbsc.getAttributes(objName, attributes);
315 for (Iterator itr = list.iterator(); itr.hasNext();)
316 {
317 Attribute attrib = (Attribute)itr.next();
318 attributeModel.setAttributeValue(attrib.getName(), attrib.getValue());
319 }
320 }
321
322 serverRegistry.setAttributeModel(mbean, attributeModel);
323 return attributeModel;
324 }
325
326 /**
327 * Updates the attribute value of an MBean
328 * @param mbean
329 * @param attribute
330 * @param value
331 * @throws Exception if MBeanServer throws exception in updating the attribute value
332 */
333 public static void updateAttribute(ManagedBean mbean, AttributeData attribute, String value) throws Exception
334 {
335 JMXManagedObject jmxbean = (JMXManagedObject)mbean;
336 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
337
338 MBeanServerConnection mbsc = serverRegistry.getServerConnection();
339
340 Object newValue = value;
341 if (attribute.getDataType().equals(Long.class.getName()))
342 {
343 if (MAX_LONG.compareTo(new BigInteger(value)) == -1)
344 {
345 throw new ManagementConsoleException("Entered value is too big for \"" +
346 ViewUtility.getDisplayText(attribute.getName()) + "\"");
347 }
348 newValue = new Long(Long.parseLong(value));
349 }
350 else if (attribute.getDataType().equals(Integer.class.getName()))
351 {
352 if (MAX_INT.compareTo(new BigInteger(value)) == -1)
353 {
354 throw new ManagementConsoleException("Entered value is too big for " + attribute.getName());
355 }
356 newValue = new Integer(Integer.parseInt(value));
357 }
358
359 mbsc.setAttribute(jmxbean.getObjectName(), new Attribute(attribute.getName(), newValue));
360 // Update the value in the registry, to avoid refreshing from mbsc
361 ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
362 attributeModel.setAttributeValue(attribute.getName(), newValue);
363 }
364
365 /**
366 * populates the operation data model in server registry for given mbean
367 * @param mbean
368 * @return operation data model
369 */
370 public static OperationDataModel getOperations(ManagedBean mbean)
371 {
372 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
373 OperationDataModel dataModel = serverRegistry.getOperationModel(mbean);
374 if (dataModel == null)
375 {
376 // Create operation model and set it in server registry for this mbean
377 MBeanOperationInfo[] operationsInfo = serverRegistry.getMBeanInfo(mbean).getOperations();
378 dataModel = new OperationDataModel();
379
380 for (int i = 0; i < operationsInfo.length; i++)
381 {
382 dataModel.addOperation(operationsInfo[i]);
383 }
384
385 serverRegistry.setOperationModel(mbean, dataModel);
386 }
387 return dataModel;
388 }
389
390 /**
391 * populates the notification in the server registry for given mbean
392 * @param mbean
393 * @return notification info model
394 */
395 public static NotificationInfoModel[] getNotificationInfo(ManagedBean mbean)
396 {
397 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
398 MBeanNotificationInfo[] info = serverRegistry.getMBeanInfo(mbean).getNotifications();
399
400 // Check if this mbean sends any notification
401 if (info == null || info.length == 0)
402 return null;
403
404 // Create notification model if not already set in the server registry for this mbean
405 List<NotificationInfoModel> list = serverRegistry.getNotificationInfo(mbean);
406 if (list != null)
407 return list.toArray(new NotificationInfoModel[0]);
408 else
409 list = new ArrayList<NotificationInfoModel>();
410
411 for (int i = 0; i < info.length; i++)
412 {
413 list.add(new NotificationInfoModel(info[i].getName(), info[i].getDescription(), info[i].getNotifTypes()));
414 }
415
416 // Set the notification model in the server registry for this mbean
417 serverRegistry.setNotificationInfo(mbean, list);
418 return list.toArray(new NotificationInfoModel[0]);
419 }
420
421 /**
422 * Retrieves all the MBeans from mbean server for a given domain
423 * @return list of ManagedBeans
424 */
425 public static List<ManagedBean> getManagedObjectsForDomain(ManagedServer server, String domain) throws Exception
426 {
427 List<ManagedBean> mbeans = new ArrayList<ManagedBean>();
428 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
429 MBeanServerConnection mbsc = serverRegistry.getServerConnection();
430 ObjectName objName = new ObjectName(domain + ":*");
431 Set objectInstances = mbsc.queryMBeans(objName, null);
432
433 for (Iterator itr = objectInstances.iterator(); itr.hasNext();)
434 {
435 ObjectInstance instance = (ObjectInstance)itr.next();
436 ManagedBean obj = new JMXManagedObject(instance.getObjectName());
437 mbeans.add(obj);
438 }
439
440 return mbeans;
441 }
442
443 /**
444 * Returns all the domains for the given server. This method can be removed as now this RCP is specific to
445 * Qpid and domain is also fixed
446 */
447 public static List<String> getAllDomains(ManagedServer server) throws Exception
448 {
449 JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
450 MBeanServerConnection mbsc = serverRegistry.getServerConnection();
451 String[] domains = mbsc.getDomains();
452 return Arrays.asList(domains);
453 }
454
455 public static void printOutput(String statement)
456 {
457 if (ApplicationRegistry.debug)
458 {
459 System.out.println(statement);
460 }
461 }
462
463 public static void printStackTrace(Throwable ex)
464 {
465 if (ApplicationRegistry.debug)
466 {
467 ex.printStackTrace();
468 }
469 }
470 }
|