JmxService.java
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.domain.model;
022 
023 import java.lang.management.ManagementFactory;
024 import java.util.Set;
025 import java.util.UUID;
026 
027 import javax.management.MBeanException;
028 import javax.management.MBeanServer;
029 import javax.management.MalformedObjectNameException;
030 import javax.management.ObjectName;
031 
032 import org.apache.qpid.management.Messages;
033 import org.apache.qpid.management.Names;
034 import org.apache.qpid.management.domain.model.QpidClass.QManManagedObject;
035 import org.apache.qpid.management.domain.model.QpidEvent.QManManagedEvent;
036 import org.apache.qpid.management.domain.model.type.Binary;
037 import org.apache.qpid.management.domain.services.QMan;
038 import org.apache.qpid.transport.util.Logger;
039 
040 /**
041  * A simple facade used to perform operations on Mbean server.
042  */
043 public class JmxService
044 {
045     private final static Logger LOGGER = Logger.get(JmxService.class);
046     MBeanServer _mxServer = ManagementFactory.getPlatformMBeanServer();
047     
048     /**
049      * Registers QMan with the MBeanServer.
050      * After that QMan management interface will be JMX-exposed. 
051      
052      @param qman QMan
053      @throws MBeanException when some error occurs during registration.
054      */
055     public void registerQManService(QMan qmanthrows MBeanException 
056     {
057       ObjectName name = createQManName();
058       if (!_mxServer.isRegistered(name))
059       {
060         try {
061         _mxServer.registerMBean(qman, name);
062       catch (Exception exception) {
063         throw new MBeanException(exception);
064       }
065       }
066     }
067     
068     /**
069      * Registers an event instance with MBean server.
070      
071      @param eventInstance the mben event instance
072      @param brokerId the broker identifier.
073      @param packageName the package name.
074      @param eventClassName the event class name.
075      @return the object name used for registration.
076      */
077   ObjectName registerEventInstance(
078       QManManagedEvent eventInstance,
079       UUID brokerId, 
080       String packageName, 
081       String eventClassName
082   {
083         ObjectName name = createEventName(brokerId, packageName, eventClassName);
084         if (!_mxServer.isRegistered(name)) 
085         {
086             try
087             {
088                 _mxServer.registerMBean(eventInstance, name);
089 
090                 LOGGER.debug(
091                     Messages.QMAN_200010_EVENT_MBEAN_REGISTERED,
092                         brokerId,
093                         packageName,
094                         eventClassName,
095                         name);
096             }  catch (Exception exception)
097             {
098                 throw new RuntimeException(exception);
099             
100         }
101         return name;
102 }
103     
104     /**
105      * Registers a pre-existing object instance as an MBean with the MBean
106      * server. 
107      
108      @param instance the object instance.
109      @param brokerId the broker identifier.
110      @param packageName the name of the package containing this instance.
111      @param className the name of the owner class of this instance.
112      @param objectId the object instance identifier.
113      *  @return the object name used for registration.
114      */
115     ObjectName registerObjectInstance(
116             QManManagedObject instance,
117             UUID brokerId,
118             String packageName, 
119             String className, 
120             Binary objectId)
121     {    
122             ObjectName name = createObjectName(brokerId, packageName, className, objectId);
123             if (!_mxServer.isRegistered(name)) 
124             {
125                 try
126                 {
127                     _mxServer.registerMBean(instance, name);
128 
129                     LOGGER.debug(
130                             Messages.QMAN_200011_OBJECT_MBEAN_REGISTERED, 
131                             brokerId,
132                             packageName,
133                             className,
134                             objectId,
135                             name);
136                 }  catch (Exception exception)
137                 {
138                     throw new RuntimeException(exception);
139                 
140             }
141             return name;
142     }
143 
144     /**
145      * Removes / unregisters a managed object instance from the MBean Server.
146      
147      @param brokerId the broker identifier.
148      @param packageName the name of the package containing this instance.
149      @param className the name of the owner class of this instance.
150      @param objectId the object instance identifier.
151      @return obejctName the obejct name used for deregistration.
152      */
153     ObjectName unregisterObjectInstance(
154             UUID brokerId,
155             String packageName, 
156             String className, 
157             Binary objectId)
158     {    
159             ObjectName name = createObjectName(brokerId, packageName, className, objectId);
160             if (_mxServer.isRegistered(name)) 
161             {
162                 try
163                 {
164                     _mxServer.unregisterMBean(name);
165 
166                     LOGGER.debug(
167                             Messages.QMAN_200012_OBJECT_MBEAN_UNREGISTERED, 
168                             brokerId,
169                             packageName,
170                             className,
171                             objectId,
172                             name);
173                 }  catch (Exception exception)
174                 {
175                     LOGGER.error(exception,Messages.QMAN_100013_MBEAN_REGISTRATION_FAILURE,name);
176                 
177             }
178             return name;
179     }    
180     
181     /**
182      * Removes (unregister) all events from MBean Server.
183      */
184     void unregisterEvents()
185     {
186       for (ObjectName name : getEventMBeans()) 
187       {
188         try 
189         {
190           _mxServer.unregisterMBean(name);
191         catch(Exception ignore)
192         {
193         }
194     }
195     }
196     
197     @SuppressWarnings("unchecked")
198   Set<ObjectName> getEventMBeans()
199     {
200       return _mxServer.queryNames(createEventSearchName(),null);
201     }
202     
203     /**
204      * Removes (unregister) all object instances from MBean Server.
205      */
206     @SuppressWarnings("unchecked")
207   void unregisterObjectInstances()
208     {
209       Set<ObjectName> names = _mxServer.queryNames(createObjectInstanceSearchName(),null);
210       for (ObjectName name : names
211       {
212         try 
213         {
214           _mxServer.unregisterMBean(name);
215         catch(Exception ignore)
216         {
217         }
218     }
219     }    
220     
221     /**
222      * Factory method for ObjectNames.
223      
224      @param brokerId the broker identifier.
225      @param packageName the name of the package containing this instance.
226      @param className the name of the owner class of this instance.
227      @param objectId the object instance identifier.
228      @return the object name built according to the given parameters.
229      */
230     private ObjectName createObjectName(UUID brokerId, String packageName, String className, Binary objectId
231     {
232         String asString = new StringBuilder()
233             .append(Names.DOMAIN_NAME)
234             .append(':')
235             .append(Names.BROKER_ID)
236             .append('=')
237             .append(brokerId)
238             .append(",type=Object,")
239             .append(Names.PACKAGE)
240             .append('=')
241             .append(packageName)
242             .append(',')
243             .append(Names.CLASS)
244             .append('=')
245             .append(className)
246             .append(',')
247             .append(Names.OBJECT_ID)
248             .append('=')
249             .append(objectId)
250             .toString();
251         try
252         {
253             return new ObjectName(asString);
254         catch (MalformedObjectNameException exception)
255         {
256             throw new RuntimeException(exception);
257         
258     }
259         
260     /**
261      * Creates an object name that will be used for searching all registered events.
262      
263      @return the object name that will be used for searching all registered events.
264      */
265     ObjectName createEventSearchName() 
266     {
267         String asString = new StringBuilder()
268             .append(Names.DOMAIN_NAME)
269             .append(':')
270             .append('*')
271             .append(",type=Event")
272             .toString();
273         try
274         {
275             return new ObjectName(asString);
276         catch (MalformedObjectNameException exception)
277         {
278             throw new RuntimeException(exception);
279         
280     }        
281     
282     /**
283      * Creates an object name that will be used for searching all registered events.
284      
285      @return the object name that will be used for searching all registered events.
286      */
287     ObjectName createClassDefinitionSearchName() 
288     {
289         String asString = new StringBuilder()
290             .append(Names.DOMAIN_NAME)
291             .append(":Category=Schema,*")
292             .toString();
293         try
294         {
295             return new ObjectName(asString);
296         catch (MalformedObjectNameException exception)
297         {
298             throw new RuntimeException(exception);
299         
300     }           
301     
302     /**
303      * Creates an object name that will be used for searching all registered object instances.
304      
305      @return the object name that will be used for searching all registered object instances.
306      */
307     private ObjectName createObjectInstanceSearchName() 
308     {
309         String asString = new StringBuilder()
310             .append(Names.DOMAIN_NAME)
311             .append(':')
312             .append('*')
313             .append(",type=Object")
314             .toString();
315         try
316         {
317             return new ObjectName(asString);
318         catch (MalformedObjectNameException exception)
319         {
320             throw new RuntimeException(exception);
321         }         
322     }
323     
324     /**
325      * Factory method for ObjectNames.
326      
327      @param brokerId the broker identifier.
328      @param packageName the name of the package containing this instance.
329      @param className the name of the owner class of this instance.
330      @return the object name built according to the given parameters.
331      */
332     private ObjectName createEventName(UUID brokerId, String packageName, String className
333     {
334         String asString = new StringBuilder()
335             .append(Names.DOMAIN_NAME)
336             .append(':')
337             .append(Names.BROKER_ID)
338             .append('=')
339             .append(brokerId)
340             .append(",type=Event,")
341             .append(Names.PACKAGE)
342             .append('=')
343             .append(packageName)
344             .append(',')
345             .append(Names.CLASS)
346             .append('=')
347             .append(className)
348             .append(',')
349             .append(Names.OBJECT_ID)
350             .append('=')
351             .append(UUID.randomUUID())
352             .toString();
353         try
354         {
355             return new ObjectName(asString);
356         catch (MalformedObjectNameException exception)
357         {
358             throw new RuntimeException(exception);
359         
360     }        
361     
362     /**
363      * Creates the QMan object name.
364      
365      @return the QMan object name.
366      */
367     private ObjectName createQManName() 
368     {
369         String asString = new StringBuilder()
370             .append(Names.DOMAIN_NAME)
371             .append(':')
372             .append("Type=Service")
373             .toString();
374         try
375         {
376             return new ObjectName(asString);
377         catch (MalformedObjectNameException exception)
378         {
379             throw new RuntimeException(exception);
380         
381     }
382 
383     ObjectName createEntityDefinitionName(String packageName, String className, String type
384     {
385     String asString = new StringBuilder()
386     .append(Names.DOMAIN_NAME)
387     .append(':')
388     .append("Category=Schema,Type=")
389     .append(type)
390     .append(",package=")
391     .append(packageName)
392     .append(",name=")
393     .append(className)
394     .toString();
395         try
396         {
397             return new ObjectName(asString);
398         catch (MalformedObjectNameException exception)
399         {
400             throw new RuntimeException(exception);
401         }     
402     }
403     
404   public void registerEntityDefinition(ObjectName name, QpidEntity entity,String packageName, String className)
405   {
406     try 
407     {
408       if (!_mxServer.isRegistered(name))
409         _mxServer.registerMBean(entity, name);
410         _mxServer.addNotificationListener(name, createQManName(), null, null);
411     catch(Exception exception)  
412     {
413       throw new RuntimeException(exception);
414     }
415   }
416 
417   @SuppressWarnings("unchecked")
418   public void unregisterClassDefinitions()
419   {
420     Set<ObjectName> names = _mxServer.queryNames(createClassDefinitionSearchName(),null);
421       for (ObjectName name : names
422       {
423         try 
424         {
425           _mxServer.unregisterMBean(name);
426         catch(Exception ignore)
427         {
428         }
429     }
430     
431   }        
432 }