KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jmanage > core > services > MBeanServiceImpl


1 /**
2  * Copyright 2004-2005 jManage.org
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.jmanage.core.services;
17
18 import org.apache.commons.beanutils.ConvertUtils;
19 import org.jmanage.core.config.ApplicationConfig;
20 import org.jmanage.core.config.MBeanConfig;
21 import org.jmanage.core.data.AttributeListData;
22 import org.jmanage.core.data.MBeanData;
23 import org.jmanage.core.data.OperationResultData;
24 import org.jmanage.core.management.*;
25 import org.jmanage.core.util.*;
26 import org.jmanage.util.StringUtils;
27
28 import javax.management.openmbean.CompositeData JavaDoc;
29 import javax.management.openmbean.CompositeType JavaDoc;
30 import javax.management.openmbean.OpenType JavaDoc;
31 import java.lang.reflect.Constructor JavaDoc;
32 import java.util.*;
33 import java.util.logging.Level JavaDoc;
34 import java.util.logging.Logger JavaDoc;
35
36 /**
37  *
38  * date: Feb 21, 2005
39  * @author Rakesh Kalra, Shashank Bellary
40  */

41 public class MBeanServiceImpl implements MBeanService {
42
43     private static final Logger JavaDoc logger = Loggers.getLogger(MBeanService.class);
44
45     private static final String JavaDoc DEFAULT_FILTER = "*:*";
46     private static final char COMPOSITE_ATTR_SEPARATOR = '.';
47
48     private static final ObjectName DEFAULT_FILTER_OBJECT_NAME =
49             new ObjectName(DEFAULT_FILTER);
50
51     public List queryMBeans(ServiceContext context,
52                           String JavaDoc filter)
53             throws ServiceException {
54
55         ServerConnection serverConnection =
56                 context.getServerConnection();
57
58         ObjectName filterObjectName = null;
59         if(filter == null){
60             filterObjectName = DEFAULT_FILTER_OBJECT_NAME;
61         }else{
62             filterObjectName = new ObjectName(filter);
63         }
64
65         Set mbeans =
66                 serverConnection.queryNames(filterObjectName);
67         ArrayList mbeanDataList = new ArrayList(mbeans.size());
68         for(Iterator it=mbeans.iterator();it.hasNext(); ){
69             ObjectName objName = (ObjectName)it.next();
70             mbeanDataList.add(new MBeanData(objName.getDisplayName()));
71         }
72         return mbeanDataList;
73     }
74
75     public Map queryMBeansOutputMap(ServiceContext context, String JavaDoc filter,
76                                     String JavaDoc[] dataTypes, String JavaDoc applyAttribFilter){
77         List mbeanDataList = null;
78         if("false".equals(applyAttribFilter)){
79             mbeanDataList = queryMBeans(context, filter);
80         }else{
81             mbeanDataList = queryMBeansWithAttributes(context,filter,dataTypes);
82         }
83
84         Map domainToObjectNameListMap = new TreeMap();
85         ObjectNameTuple tuple = new ObjectNameTuple();
86         for(Iterator it=mbeanDataList.iterator(); it.hasNext();){
87             MBeanData mbeanData = (MBeanData)it.next();
88             tuple.setObjectName(mbeanData.getName());
89             String JavaDoc domain = tuple.getDomain();
90             String JavaDoc name = tuple.getName();
91             Set objectNameList = (Set)domainToObjectNameListMap.get(domain);
92             if(objectNameList == null){
93                 objectNameList = new TreeSet();
94                 domainToObjectNameListMap.put(domain, objectNameList);
95             }
96             objectNameList.add(name);
97         }
98         return domainToObjectNameListMap;
99     }
100
101      private List queryMBeansWithAttributes(ServiceContext context, String JavaDoc filter,
102                                          String JavaDoc[] dataTypes)
103             throws ServiceException{
104         ServerConnection serverConnection = context.getServerConnection();
105         List mbeans = queryMBeans(context, filter);
106         List mbeanToAttributesList = new ArrayList();
107         for(Iterator itr=mbeans.iterator(); itr.hasNext();){
108             MBeanData mbeanData = (MBeanData)itr.next();
109             ObjectName objName = new ObjectName(mbeanData.getName());
110             try {
111                 ObjectInfo objInfo = serverConnection.getObjectInfo(objName);
112                 ObjectAttributeInfo[] objAttrInfo = objInfo.getAttributes();
113                 if(objAttrInfo!=null && objAttrInfo.length > 0){
114                     if(dataTypes!=null && dataTypes.length > 0){
115                         if(checkAttributeDataType(serverConnection,
116                                 objName, objAttrInfo, dataTypes,
117                                 context.getApplicationConfig(), null)){
118                             mbeanToAttributesList.add(mbeanData);
119                         }
120                     }else{
121                         mbeanToAttributesList.add(mbeanData);
122                     }
123                 }
124             } catch (Exception JavaDoc e) {
125                 /* if there is an error while getting MBean Info, continue
126                     looking further */

127                 String JavaDoc errorMessage = "Error getting ObjectInfo for: " +
128                         objName + ", error=" + e.getMessage();
129                 logger.log(Level.WARNING, errorMessage);
130                 logger.log(Level.FINE, errorMessage, e);
131             }
132         }
133          return mbeanToAttributesList;
134     }
135
136     /**
137      *
138      * @param objAttrInfo
139      * @param dataTypes
140      * @param appConfig
141      * @param attributesList (optional) if specified, it will be populated
142      * with ObjectAttributeInfo objects that match the dataTypes
143      * specified
144      * @return
145      */

146     private boolean checkAttributeDataType(ServerConnection connection,
147                                            ObjectName objectName,
148                                            ObjectAttributeInfo[] objAttrInfo,
149                                            String JavaDoc[] dataTypes,
150                                            ApplicationConfig appConfig,
151                                            List attributesList){
152
153         boolean result = false;
154         outerloop:
155         for(int i=0; i<objAttrInfo.length;i++){
156             ObjectAttributeInfo attrInfo = objAttrInfo[i];
157             for(int j=0; j<dataTypes.length; j++){
158                 Class JavaDoc attrInfoType = getClass(attrInfo.getType(),
159                         appConfig.getApplicationClassLoader());
160                 Class JavaDoc dataType = getClass(dataTypes[j],
161                         this.getClass().getClassLoader());
162                 if(attrInfoType != null &&
163                         dataType.isAssignableFrom(attrInfoType)){
164                     result = true;
165                     if(attributesList != null){
166                         /* special handling for CompositeData */
167                         if(attrInfoType.getName().
168                                 equals("javax.management.openmbean.CompositeData")){
169                             handleCompositeData(connection, objectName, attrInfo,
170                                     dataTypes, attributesList);
171                         }else{
172                             attributesList.add(attrInfo);
173                         }
174                     }else{
175                         // we found one. return true
176
break outerloop;
177                     }
178                 }
179             }
180         }
181         return result;
182     }
183
184     /**
185      * Expands a CompositeData object into individual attributes with the
186      * naming convention:
187      * <p>
188      * attributeName.itemName
189      * <p>
190      * The items should conform to given "dataType" array. These individual
191      * attributes are added to the <code>attributeList</code>
192      * @param attributesList ObjectAttributeInfo instances are added to this
193      * list
194      */

195     private void handleCompositeData(ServerConnection connection,
196                                      ObjectName objectName,
197                                      ObjectAttributeInfo attrInfo,
198                                      String JavaDoc[] dataTypes,
199                                      List attributesList){
200
201         CompositeType JavaDoc type = getCompositeType(connection, objectName, attrInfo);
202         for(Iterator it=type.keySet().iterator(); it.hasNext(); ){
203             String JavaDoc itemName = (String JavaDoc)it.next();
204             OpenType JavaDoc itemType = type.getType(itemName);
205             Class JavaDoc itemTypeClass = getClass(itemType.getClassName(),
206                         this.getClass().getClassLoader());
207             for(int j=0; j<dataTypes.length; j++){
208
209                 Class JavaDoc dataType = getClass(dataTypes[j],
210                         this.getClass().getClassLoader());
211                 if(dataType.isAssignableFrom(itemTypeClass)){
212                     attributesList.add(
213                             new ObjectAttributeInfo(
214                                     attrInfo.getName() + COMPOSITE_ATTR_SEPARATOR + itemName,
215                                     type.getDescription(itemName),
216                                     itemType.getClassName(), false, true, false));
217                 }
218             }
219         }
220     }
221
222     // todo: is there a simpler way to get CompositeType (without getting the value)
223
private CompositeType JavaDoc getCompositeType(ServerConnection connection,
224                                            ObjectName objectName,
225                                            ObjectAttributeInfo attrInfo){
226         CompositeData JavaDoc compositeData =
227                 (CompositeData JavaDoc)connection.getAttribute(objectName, attrInfo.getName());
228         return compositeData.getCompositeType();
229     }
230
231     private Class JavaDoc getClass(String JavaDoc type, ClassLoader JavaDoc classLoader){
232         if(type.equals("boolean"))
233              return Boolean JavaDoc.class;
234         if(type.equals("byte"))
235              return Byte.TYPE;
236         if(type.equals("char"))
237              return Character JavaDoc.class;
238         if(type.equals("double"))
239              return Double JavaDoc.class;
240         if(type.equals("float"))
241              return Float JavaDoc.class;
242         if(type.equals("int"))
243              return Integer JavaDoc.class;
244         if(type.equals("long"))
245              return Long JavaDoc.class;
246         if(type.equals("short"))
247              return Short JavaDoc.class;
248         if(type.equals("void"))
249              return Void JavaDoc.class;
250         Class JavaDoc clazz = null;
251         try{
252             clazz = Class.forName(type, true, classLoader);
253
254         }catch(ClassNotFoundException JavaDoc e){
255             logger.fine("Error finding class of type=" + type +
256                     ", error=" + e.getMessage());
257         }
258         return clazz;
259     }
260
261     private static class ObjectNameTuple{
262         String JavaDoc domain;
263         String JavaDoc name;
264
265         void setObjectName(String JavaDoc canonicalName){
266             int index = canonicalName.indexOf(":");
267             domain = canonicalName.substring(0, index);
268             name = canonicalName.substring(index + 1);
269         }
270
271         String JavaDoc getName(){
272             return name;
273         }
274         String JavaDoc getDomain(){
275             return domain;
276         }
277     }
278
279     public ObjectInfo getMBeanInfo(ServiceContext context)
280             throws ServiceException {
281         canAccessThisMBean(context);
282         ServerConnection serverConnection =
283                 ServiceUtils.getServerConnectionEvenIfCluster(
284                         context.getApplicationConfig());
285         ObjectInfo objectInfo =
286                 serverConnection.getObjectInfo(context.getObjectName());
287         return objectInfo;
288     }
289
290     /**
291      * @return list of all attribute values
292      */

293     public AttributeListData[] getAttributes(ServiceContext context)
294             throws ServiceException {
295         canAccessThisMBean(context);
296         ServerConnection serverConnection = null;
297         try {
298             serverConnection =
299                     ServiceUtils.getServerConnectionEvenIfCluster(
300                             context.getApplicationConfig());
301             ObjectInfo objInfo =
302                     serverConnection.getObjectInfo(context.getObjectName());
303             assert objInfo != null;
304             ObjectAttributeInfo[] attributes = objInfo.getAttributes();
305             List attributeNames = new LinkedList();
306             for (int i = 0; i < attributes.length; i++) {
307                 if(attributes[i].isReadable()){
308                     attributeNames.add(attributes[i].getName());
309                 }
310             }
311             String JavaDoc[] attributeArray = StringUtils.listToStringArray(attributeNames);
312             return getAttributes(context, attributeArray, true);
313         } finally {
314             ServiceUtils.close(serverConnection);
315         }
316     }
317
318     /**
319      *
320      * @return list of attribute values for given attributes
321      */

322     public AttributeListData[] getAttributes(ServiceContext context,
323                                              String JavaDoc[] attributes,
324                                              boolean handleCluster)
325             throws ServiceException {
326         canAccessThisMBean(context);
327         ApplicationConfig appConfig = context.getApplicationConfig();
328         ObjectName objectName = context.getObjectName();
329
330         AttributeListData[] resultData = null;
331         if(appConfig.isCluster()){
332             if(!handleCluster){
333                 throw new ServiceException(ErrorCodes.OPERATION_NOT_SUPPORTED_FOR_CLUSTER);
334             }
335             /* we need to perform this operation for all servers
336                 in this cluster */

337             resultData = new AttributeListData[appConfig.getApplications().size()];
338             int index = 0;
339             for(Iterator it=appConfig.getApplications().iterator(); it.hasNext(); index++){
340                 ApplicationConfig childAppConfig = (ApplicationConfig)it.next();
341                 try {
342                     resultData[index] =
343                             getAttributes(context,
344                                     childAppConfig, objectName, attributes);
345                 } catch (ConnectionFailedException e) {
346                     resultData[index] =
347                             new AttributeListData(childAppConfig.getName());
348                 }
349             }
350         }else{
351             resultData = new AttributeListData[1];
352             resultData[0] =
353                     getAttributes(context, appConfig, objectName, attributes);
354         }
355         return resultData;
356     }
357
358     /**
359      * Returns ObjectAttribute instance containing the value of the given
360      * attribute. This method also handles CompositeData item with the
361      * attribute naming convention:
362      * <p>
363      * Building.NumberOfFloors
364      * <p>
365      * where "Building" is the composite attribute name and "NumberOfFloors"
366      * is the item name in the "Building" composite type.
367      *
368      * @param context
369      * @param attribute
370      * @return
371      * @throws ServiceException
372      */

373     public ObjectAttribute getObjectAttribute(ServiceContext context,
374                                               String JavaDoc attribute)
375             throws ServiceException{
376         assert context.getObjectName() != null;
377         assert context.getApplicationConfig() != null;
378         canAccessThisMBean(context);
379         AccessController.checkAccess(context,
380                 ACLConstants.ACL_VIEW_MBEAN_ATTRIBUTES,
381                 attribute);
382         // we don't support clustering here
383
assert !context.getApplicationConfig().isCluster();
384
385         ServerConnection connection =
386                         context.getServerConnection();
387         List attrList =
388                 connection.getAttributes(context.getObjectName(),
389                         new String JavaDoc[]{attribute});
390         ObjectAttribute attrValue = (ObjectAttribute)attrList.get(0);
391         if(attrValue.getStatus() != ObjectAttribute.STATUS_NOT_FOUND){
392             return attrValue;
393         }
394
395         /* see if this is a composite attribute */
396         String JavaDoc attributeName = null;
397         String JavaDoc itemName = null;
398         int index = attribute.indexOf(COMPOSITE_ATTR_SEPARATOR);
399         if(index == -1)
400             return attrValue;
401
402         // composite data attribute
403
itemName = attribute.substring(index + 1);
404         attributeName = attribute.substring(0, index);
405
406         attrList =
407                 connection.getAttributes(context.getObjectName(),
408                         new String JavaDoc[]{attributeName});
409         attrValue = (ObjectAttribute)attrList.get(0);
410         if(attrValue.getStatus() == ObjectAttribute.STATUS_OK){
411             CompositeData JavaDoc compositeData = (CompositeData JavaDoc)attrValue.getValue();
412             attrValue = new ObjectAttribute(attribute,
413                     compositeData.get(itemName));
414         }
415         return attrValue;
416     }
417
418     /**
419      * @return list of attribute values for given attributes
420      */

421     private AttributeListData getAttributes(ServiceContext context,
422                                             ApplicationConfig appConfig,
423                                             ObjectName objectName,
424                                             String JavaDoc[] attributes)
425             throws ConnectionFailedException {
426
427         // TODO: we should hide the attributes in the jsp
428
for(int attrCount = 0; attrCount < attributes.length; attrCount++){
429             AccessController.checkAccess(context,
430                     ACLConstants.ACL_VIEW_MBEAN_ATTRIBUTES,
431                     attributes[attrCount]);
432         }
433         ServerConnection connection = null;
434
435         try {
436             connection = ServerConnector.getServerConnection(appConfig);
437             List attrList =
438                     connection.getAttributes(objectName, attributes);
439             return new AttributeListData(appConfig.getName(), attrList);
440         } finally {
441             ServiceUtils.close(connection);
442         }
443     }
444
445     public List filterAttributes(ServiceContext context, ObjectName objectName,
446                                  ObjectAttributeInfo[] objAttrInfo, String JavaDoc[] dataTypes){
447         List objAttrInfoList = new LinkedList();
448         checkAttributeDataType(context.getServerConnection(),
449                 objectName, objAttrInfo, dataTypes,
450                 context.getApplicationConfig() ,objAttrInfoList);
451          return objAttrInfoList;
452     }
453
454     public OperationResultData[] invoke(ServiceContext context,
455                                         String JavaDoc operationName,
456                                         String JavaDoc[] params)
457             throws ServiceException {
458         canAccessThisMBean(context);
459         AccessController.checkAccess(context,
460                 ACLConstants.ACL_EXECUTE_MBEAN_OPERATIONS, operationName);
461
462         /* try to determine the method, based on params */
463         ObjectOperationInfo operationInfo =
464                 findOperation(context, operationName,
465                         params != null ? params.length : 0);
466         return invoke(context, operationName, params,
467                 operationInfo.getParameters());
468     }
469
470     /**
471      * Invokes MBean operation
472      * @return
473      * @throws ServiceException
474      */

475     public OperationResultData[] invoke(ServiceContext context,
476                                         String JavaDoc operationName,
477                                         String JavaDoc[] params,
478                                         String JavaDoc[] signature)
479             throws ServiceException {
480         canAccessThisMBean(context);
481         AccessController.checkAccess(context,
482                 ACLConstants.ACL_EXECUTE_MBEAN_OPERATIONS, operationName);
483
484         ApplicationConfig appConfig = context.getApplicationConfig();
485         ObjectName objectName = context.getObjectName();
486
487         OperationResultData[] resultData = null;
488         if(appConfig.isCluster()){
489             /* we need to perform this operation for all servers
490                 in this cluster */

491             resultData = new OperationResultData[appConfig.getApplications().size()];
492             int index = 0;
493             for(Iterator it=appConfig.getApplications().iterator(); it.hasNext(); index++){
494                 ApplicationConfig childAppConfig = (ApplicationConfig)it.next();
495                 resultData[index] =
496                         executeMBeanOperation(context, childAppConfig, objectName,
497                                 operationName, params, signature);
498             }
499         }else{
500             resultData = new OperationResultData[1];
501             resultData[0] =
502                     executeMBeanOperation(context, appConfig, objectName,
503                             operationName, params, signature);
504         }
505         return resultData;
506     }
507
508     private static OperationResultData executeMBeanOperation(
509             ServiceContext context,
510             ApplicationConfig appConfig,
511             ObjectName objectName,
512             String JavaDoc operationName,
513             String JavaDoc[] params,
514             String JavaDoc[] signature){
515
516         OperationResultData resultData =
517                 new OperationResultData(appConfig.getName());
518         ServerConnection serverConnection = null;
519         try {
520             serverConnection = ServerConnector.getServerConnection(appConfig);
521             Object JavaDoc[] typedParams = getTypedArray(appConfig,
522                     params, signature);
523             final Object JavaDoc result = serverConnection.invoke(objectName, operationName,
524                             typedParams, signature);
525
526             resultData.setOutput(result);
527             UserActivityLogger.getInstance().logActivity(
528                     context.getUser().getUsername(),
529                     "Performed "+operationName+" on "+objectName.getCanonicalName()
530                     + " in application " + appConfig.getName());
531         } catch (ConnectionFailedException e) {
532             logger.log(Level.INFO, "Error executing operation " +
533                     operationName + " on " + objectName, e);
534             resultData.setResult(OperationResultData.RESULT_ERROR);
535             resultData.setErrorString(ErrorCatalog.getMessage(ErrorCodes.CONNECTION_FAILED));
536         } catch (RuntimeException JavaDoc e){
537             logger.log(Level.SEVERE, "Error executing operation " +
538                     operationName + " on " + objectName, e);
539             resultData.setResult(OperationResultData.RESULT_ERROR);
540             if(e.getCause() != null){
541                 if(e.getCause().getClass().getName().
542                         equals("javax.management.RuntimeMBeanException") &&
543                         e.getCause().getCause() != null){
544                     resultData.setException(e.getCause().getCause());
545                 }else{
546                     resultData.setException(e.getCause());
547                 }
548             }else{
549                 resultData.setException(e);
550             }
551         } catch (Exception JavaDoc e){
552             logger.log(Level.SEVERE, "Error executing operation " +
553                     operationName + " on " + objectName, e);
554             resultData.setResult(OperationResultData.RESULT_ERROR);
555             resultData.setException(e);
556         } finally {
557             ServiceUtils.close(serverConnection);
558         }
559         return resultData;
560     }
561
562     private ObjectOperationInfo findOperation(ServiceContext context,
563                                               String JavaDoc operationName,
564                                               int paramCount){
565
566         ObjectName objectName = context.getObjectName();
567         ServerConnection connection = null;
568         try {
569             connection =
570                 ServiceUtils.getServerConnectionEvenIfCluster(
571                         context.getApplicationConfig());
572             ObjectInfo objectInfo = connection.getObjectInfo(objectName);
573             ObjectOperationInfo[] operationInfo = objectInfo.getOperations();
574             for(int i=0; i< operationInfo.length; i++){
575                 if(operationInfo[i].getName().equals(operationName) &&
576                         operationInfo[i].getSignature().length == paramCount){
577                     return operationInfo[i];
578                 }
579             }
580             throw new ServiceException(ErrorCodes.INVALID_MBEAN_OPERATION,
581                     operationName, objectName);
582         } finally {
583             ServiceUtils.close(connection);
584         }
585     }
586
587     //TODO: should we first check that all apps in a cluster are up,
588
// before updating? - rk
589
public AttributeListData[] setAttributes(ServiceContext context,
590                                              String JavaDoc[][] attributes)
591             throws ServiceException{
592         canAccessThisMBean(context);
593         List applications = getApplications(context.getApplicationConfig());
594         ObjectName objectName = context.getObjectName();
595         List attributeList = buildAttributeList(context, attributes);
596         AttributeListData[] attrListData =
597                 new AttributeListData[applications.size()];
598         int index = 0;
599         for(Iterator it=applications.iterator(); it.hasNext(); index++){
600             final ApplicationConfig childAppConfig =
601                         (ApplicationConfig)it.next();
602             attrListData[index] = updateAttributes(context, childAppConfig,
603                     objectName, attributeList);
604         }
605         return attrListData;
606     }
607
608     /**
609      * Updates MBean attributes at a stand alone application level or at a
610      * cluster level.
611      * <p>
612      * The attributes element contains the keys in the format:
613      * attr+<applicationId>+<attrName>+<attrType>
614      * <p>
615      * todo: improve this interface (currently written for webui)
616      *
617      *
618      * @param context
619      * @param attributes Map containing
620      * @throws ServiceException
621      */

622     public AttributeListData[] setAttributes(ServiceContext context,
623                                              Map attributes)
624             throws ServiceException{
625         canAccessThisMBean(context);
626         List applications = getApplications(context.getApplicationConfig());
627         ObjectName objectName = context.getObjectName();
628         AttributeListData[] attrListData =
629                 new AttributeListData[applications.size()];
630         int index = 0;
631
632         ServerConnection connection =
633                 ServiceUtils.getServerConnectionEvenIfCluster(
634                         context.getApplicationConfig());
635         try {
636             ObjectInfo objInfo = connection.getObjectInfo(objectName);
637             for(Iterator it=applications.iterator(); it.hasNext(); index++){
638                 final ApplicationConfig childAppConfig =
639                             (ApplicationConfig)it.next();
640                 List attributeList = buildAttributeList(attributes,
641                         childAppConfig, objInfo.getAttributes(), connection,
642                         objectName);
643                 attrListData[index] = updateAttributes(context, childAppConfig,
644                         objectName, attributeList);
645             }
646         } finally {
647             ServiceUtils.close(connection);
648         }
649         return attrListData;
650     }
651
652     public Map queryMBeansWithNotifications(ServiceContext context)
653             throws ServiceException {
654
655         ServerConnection serverConnection =
656                 context.getServerConnection();
657         Set mbeans = serverConnection.queryNames(DEFAULT_FILTER_OBJECT_NAME);
658         Map mbeanToNoficationsMap = new TreeMap();
659         for(Iterator it=mbeans.iterator(); it.hasNext(); ){
660             ObjectName objName = (ObjectName)it.next();
661
662             try {
663                 ObjectInfo objInfo = serverConnection.getObjectInfo(objName);
664                 ObjectNotificationInfo[] notifications = objInfo.getNotifications();
665                 if(notifications != null && notifications.length > 0){
666                     mbeanToNoficationsMap.put(objName.getDisplayName(), notifications);
667                 }
668             } catch (Exception JavaDoc e) {
669                 /* if there is an error while getting MBean Info, continue
670                     looking further */

671                 String JavaDoc errorMessage = "Error getting ObjectInfo for: " +
672                         objName + ", error=" + e.getMessage();
673                 logger.log(Level.WARNING, errorMessage);
674                 logger.log(Level.FINE, errorMessage, e);
675             }
676         }
677         return mbeanToNoficationsMap;
678     }
679     private AttributeListData updateAttributes(ServiceContext context,
680                                                ApplicationConfig appConfig,
681                                                ObjectName objectName,
682                                                List attributeList){
683         for(Iterator attrIterator = attributeList.iterator(); attrIterator.hasNext();){
684             ObjectAttribute objAttr = (ObjectAttribute)attrIterator.next();
685             AccessController.checkAccess(context,
686                     ACLConstants.ACL_UPDATE_MBEAN_ATTRIBUTES,
687                     objAttr.getName());
688         }
689         AttributeListData attrListData = null;
690         ServerConnection serverConnection = null;
691         try{
692             serverConnection = ServerConnector.getServerConnection(appConfig);
693             attributeList =
694                     serverConnection.setAttributes(objectName, attributeList);
695             attrListData = new AttributeListData(appConfig.getName(),
696                     attributeList);
697             String JavaDoc logString = getLogString(attributeList);
698             UserActivityLogger.getInstance().logActivity(
699                     context.getUser().getUsername(),
700                     "Updated the attributes of application:" +
701                     appConfig.getName() + ", object name:" +
702                     objectName.getCanonicalName() +
703                     logString);
704         }catch(ConnectionFailedException e){
705             logger.log(Level.FINE, "Error connecting to :" +
706                     appConfig.getName(), e);
707             attrListData = new AttributeListData(appConfig.getName());
708         }finally{
709             ServiceUtils.close(serverConnection);
710         }
711         return attrListData;
712     }
713
714     /**
715      * Converts a two dimentional String array containing attribute name and
716      * value to a list of ObjectAttribute objects.
717      *
718      * @return list containing ObjectAttribute objects
719      */

720     private List buildAttributeList(ServiceContext context,
721                                     String JavaDoc[][] attributes){
722         ObjectName objectName;
723         ObjectInfo objInfo;
724         ServerConnection connection = null;
725         try {
726             connection =
727                     ServiceUtils.getServerConnectionEvenIfCluster(
728                             context.getApplicationConfig());
729             objectName = context.getObjectName();
730             objInfo = connection.getObjectInfo(objectName);
731         } finally {
732             ServiceUtils.close(connection);
733         }
734
735         ObjectAttributeInfo[] objAttributes = objInfo.getAttributes();
736         List attributeList = new LinkedList();
737         for(int i=0; i<attributes.length; i++){
738             String JavaDoc attribute = attributes[i][0];
739             String JavaDoc type = getAttributeType(connection,
740                     objAttributes, attribute, objectName);
741             /* ensure that this attribute is writable */
742             ensureAttributeIsWritable(objAttributes, attribute, objectName);
743
744             Object JavaDoc value = getTypedValue(
745                     context.getApplicationConfig(), attributes[i][1], type);
746             ObjectAttribute objAttribute =
747                     new ObjectAttribute(attribute, value);
748             attributeList.add(objAttribute);
749         }
750         return attributeList;
751     }
752
753     // handles composite attribute type
754
private String JavaDoc getAttributeType(ServerConnection connection,
755                                     ObjectAttributeInfo[] objAttributes,
756                                     String JavaDoc attribute,
757                                     ObjectName objectName){
758
759         /* first look for normal attribute */
760         for(int i=0; i<objAttributes.length; i++){
761             if(objAttributes[i].getName().equals(attribute)){
762                 return objAttributes[i].getType();
763             }
764         }
765
766         /* now look for CompositeData */
767         String JavaDoc itemName = null;
768         final int index = attribute.indexOf(COMPOSITE_ATTR_SEPARATOR);
769         if(index != -1){
770             itemName = attribute.substring(index + 1);
771             attribute = attribute.substring(0, index);
772             for(int i=0; i<objAttributes.length; i++){
773                 if(objAttributes[i].getName().equals(attribute)){
774                     // it is a CompositeData type
775
CompositeType JavaDoc type = getCompositeType(connection,
776                             objectName, objAttributes[i]);
777                     return type.getType(itemName).getClassName();
778                 }
779             }
780         }
781         throw new ServiceException(ErrorCodes.INVALID_MBEAN_ATTRIBUTE,
782                 attribute, objectName);
783     }
784
785     private void ensureAttributeIsWritable(ObjectAttributeInfo[] objAttributes,
786                                            String JavaDoc attribute,
787                                            ObjectName objectName){
788         ObjectAttributeInfo attributeInfo = null;
789         for(int i=0; i<objAttributes.length; i++){
790             if(objAttributes[i].getName().equals(attribute)){
791                 attributeInfo = objAttributes[i];
792                 break;
793             }
794         }
795         assert attributeInfo != null :"attribute not found:" + attribute;
796         if(!attributeInfo.isWritable()){
797             throw new ServiceException(ErrorCodes.READ_ONLY_MBEAN_ATTRIBUTE,
798                     attribute, objectName);
799         }
800     }
801
802
803     private List getApplications(ApplicationConfig appConfig){
804         List applications = null;
805         if(appConfig.isCluster()){
806             applications = appConfig.getApplications();
807         }else{
808             applications = new ArrayList(1);
809             applications.add(appConfig);
810         }
811         return applications;
812     }
813
814     /**
815      * Map keys are of the format:
816      * attr+<applicationId>+<attrName>
817      *
818      */

819     private List buildAttributeList(Map attributes,
820                                     ApplicationConfig appConfig,
821                                     ObjectAttributeInfo[] objAttributes,
822                                     ServerConnection connection,
823                                     ObjectName objectName){
824
825         String JavaDoc applicationId = appConfig.getApplicationId();
826         Iterator it = attributes.keySet().iterator();
827         List attributeList = new LinkedList();
828         while(it.hasNext()){
829             String JavaDoc param = (String JavaDoc)it.next();
830             // look for keys which only start with "attr+"
831
if(param.startsWith("attr+")){
832                 StringTokenizer tokenizer = new StringTokenizer(param, "+");
833                 if(tokenizer.countTokens() != 3){
834                     throw new RuntimeException JavaDoc("Invalid param name: " + param);
835                 }
836                 tokenizer.nextToken(); // equals to "attr"
837
if(applicationId.equals(tokenizer.nextToken())){ // applicationId
838
String JavaDoc attrName = tokenizer.nextToken();
839                     String JavaDoc attrType = getAttributeType(connection,
840                             objAttributes, attrName, objectName);
841
842                     String JavaDoc[] attrValues = (String JavaDoc[])attributes.get(param);
843                     Object JavaDoc typedValue = null;
844                     if(attrType.startsWith("[")){
845                         // it is an array
846
// the first elements in the array is dummy to allow
847
// empty string to be saved
848
String JavaDoc[] actualValue = new String JavaDoc[attrValues.length - 1];
849                         for(int i=0;i<actualValue.length;i++){
850                             actualValue[i] = attrValues[i+1];
851                         }
852                         try {
853                             typedValue = ConvertUtils.convert(actualValue,
854                                     Class.forName(attrType));
855                         } catch (ClassNotFoundException JavaDoc e) {
856                             throw new RuntimeException JavaDoc(e);
857                         }
858                     }else{
859                         typedValue =
860                                 getTypedValue(appConfig, attrValues[0], attrType);
861                     }
862                     attributeList.add(new ObjectAttribute(attrName, typedValue));
863                 }
864             }
865         }
866         return attributeList;
867     }
868
869     /**
870      *
871      * @param attributes
872      * @return
873      */

874     private String JavaDoc getLogString(List attributes){
875         StringBuffer JavaDoc logString = new StringBuffer JavaDoc("");
876         for(Iterator iterator = attributes.iterator(); iterator.hasNext(); ){
877             ObjectAttribute attribute = (ObjectAttribute)iterator.next();
878             logString.append(" [");
879             logString.append(attribute.getName());
880             logString.append("=");
881             logString.append(attribute.getValue());
882             logString.append("]");
883         }
884         return logString.toString();
885     }
886
887
888     private void canAccessThisMBean(ServiceContext context){
889         final ApplicationConfig config = context.getApplicationConfig();
890         final MBeanConfig configuredMBean =
891                 config.findMBeanByObjectName(context.getObjectName().getCanonicalName());
892         AccessController.checkAccess(context,
893                 ACLConstants.ACL_VIEW_APPLICATIONS);
894         if(configuredMBean != null)
895             AccessController.checkAccess(context,
896                     ACLConstants.ACL_VIEW_MBEANS);
897     }
898
899     public static Object JavaDoc getTypedValue(ApplicationConfig appConfig,
900                                        String JavaDoc value,
901                                        String JavaDoc type){
902
903         if(type.equals("int")){
904             type = "java.lang.Integer";
905         }else if(type.equals("long")){
906             type = "java.lang.Long";
907         }else if(type.equals("short")){
908             type = "java.lang.Short";
909         }else if(type.equals("float")){
910             type = "java.lang.Float";
911         }else if(type.equals("double")){
912             type = "java.lang.Double";
913         }else if(type.equals("char")){
914             type = "java.lang.Character";
915         }else if(type.equals("boolean")){
916             type = "java.lang.Boolean";
917         }else if(type.equals("byte")){
918             type = "java.lang.Byte";
919         }
920
921         try {
922             /* handle ObjectName as a special type */
923             if(type.equals("javax.management.ObjectName")){
924                 Class JavaDoc clazz = Class.forName(type, true,
925                         appConfig.getApplicationClassLoader());
926                 try {
927                     Constructor JavaDoc ctor = clazz.getConstructor(new Class JavaDoc[]{String JavaDoc.class});
928                     return ctor.newInstance(new Object JavaDoc[]{value});
929                 } catch (Exception JavaDoc e) {
930                     throw new RuntimeException JavaDoc(e);
931                 }
932             }
933
934             /* other types */
935             return ConvertUtils.convert(value, Class.forName(type));
936         } catch (ClassNotFoundException JavaDoc e) {
937             throw new RuntimeException JavaDoc(e);
938         }
939     }
940
941     public static Object JavaDoc[] getTypedArray(ApplicationConfig appConfig,
942                                          String JavaDoc[] values,
943                                          String JavaDoc[] type){
944         Object JavaDoc[] obj = new Object JavaDoc[values.length];
945         for(int i=0; i<values.length; i++){
946             obj[i] = getTypedValue(appConfig, values[i], type[i]);
947         }
948         return obj;
949     }
950
951     public ObjectOperationInfo getOperationInfo(ServiceContext context,
952                                        String JavaDoc operationName,
953                                        String JavaDoc[] signature)
954             throws ServiceException {
955
956         ObjectOperationInfo operationInfo = null;
957         ObjectInfo objectInfo = getMBeanInfo(context);
958         ObjectOperationInfo[] operations = objectInfo.getOperations();
959
960         for(int index = 0; index < operations.length; index++) {
961             operationInfo = operations[index];
962
963             if(operationName.equals(operationInfo.getName())) {
964                 int matchCounter = 0;
965                 ObjectParameterInfo[] objectSignature = operationInfo.getSignature();
966
967                 if(signature.length == objectSignature.length) {
968                     for(int paramIndex = 0; paramIndex < objectSignature.length; paramIndex++) {
969                         if(signature[paramIndex].equals(objectSignature[paramIndex].getType())) {
970                             matchCounter++;
971                         }
972                     }
973
974                     if(matchCounter == signature.length) {
975                         break;
976                     }
977                 }
978             }
979         }
980         return operationInfo;
981     }
982
983     public String JavaDoc getAttributeDataType(ServiceContext context,
984                                               String JavaDoc attributeName,
985                                               String JavaDoc objectName){
986         ServerConnection connection = context.getServerConnection();
987         ObjectName objName = new ObjectName(objectName);
988         ObjectInfo objectInfo = connection.getObjectInfo(objName);
989         ObjectAttributeInfo[] objAttrInfo = objectInfo.getAttributes();
990         return getAttributeType(connection, objAttrInfo, attributeName, objName);
991     }
992 }
993
Popular Tags