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    package org.apache.camel.management;
018    
019    import javax.management.JMException;
020    import javax.management.MBeanServer;
021    import javax.management.ObjectName;
022    import javax.management.modelmbean.InvalidTargetObjectTypeException;
023    import javax.management.modelmbean.ModelMBean;
024    import javax.management.modelmbean.ModelMBeanInfo;
025    import javax.management.modelmbean.RequiredModelMBean;
026    
027    import org.apache.camel.CamelContext;
028    import org.apache.camel.api.management.ManagedInstance;
029    import org.apache.camel.api.management.ManagedResource;
030    import org.apache.camel.api.management.NotificationSenderAware;
031    import org.apache.camel.spi.ManagementMBeanAssembler;
032    import org.apache.camel.util.ObjectHelper;
033    import org.slf4j.Logger;
034    import org.slf4j.LoggerFactory;
035    
036    /**
037     * An assembler to assemble a {@link javax.management.modelmbean.ModelMBean} which can be used
038     * to register the object in JMX. The assembler is capable of using the Camel JMX annotations to
039     * gather the list of JMX operations and attributes.
040     *
041     * @version 
042     */
043    public class DefaultManagementMBeanAssembler implements ManagementMBeanAssembler {
044        private static final Logger LOG = LoggerFactory.getLogger(DefaultManagementMBeanAssembler.class);
045        protected final MBeanInfoAssembler assembler;
046        protected final CamelContext camelContext;
047    
048        public DefaultManagementMBeanAssembler(CamelContext camelContext) {
049            this.camelContext = camelContext;
050            this.assembler = new MBeanInfoAssembler(camelContext);
051        }
052    
053        public ModelMBean assemble(MBeanServer mBeanServer, Object obj, ObjectName name) throws JMException {
054            ModelMBeanInfo mbi = null;
055    
056            // prefer to use the managed instance if it has been annotated with JMX annotations
057            if (obj instanceof ManagedInstance) {
058                // there may be a custom embedded instance which have additional methods
059                Object custom = ((ManagedInstance) obj).getInstance();
060                if (custom != null && ObjectHelper.hasAnnotation(custom.getClass().getAnnotations(), ManagedResource.class)) {
061                    LOG.trace("Assembling MBeanInfo for: {} from custom @ManagedResource object: {}", name, custom);
062                    // get the mbean info from the custom managed object
063                    mbi = assembler.getMBeanInfo(null, custom, name.toString());
064                    // and let the custom object be registered in JMX
065                    obj = custom;
066                }
067            }
068    
069            if (mbi == null) {
070                // use the default provided mbean which has been annotated with JMX annotations
071                LOG.trace("Assembling MBeanInfo for: {} from @ManagedResource object: {}", name, obj);
072                mbi = assembler.getMBeanInfo(obj, null, name.toString());
073            }
074    
075            if (mbi == null) {
076                return null;
077            }
078    
079            RequiredModelMBean mbean;
080            boolean sanitize = camelContext.getManagementStrategy().getManagementAgent().getMask() != null && camelContext.getManagementStrategy().getManagementAgent().getMask();
081            if (sanitize) {
082                mbean = new MaskRequiredModelMBean(mbi, sanitize);
083            } else {
084                mbean = (RequiredModelMBean) mBeanServer.instantiate(RequiredModelMBean.class.getName());
085                mbean.setModelMBeanInfo(mbi);
086            }
087    
088            try {
089                mbean.setManagedResource(obj, "ObjectReference");
090            } catch (InvalidTargetObjectTypeException e) {
091                throw new JMException(e.getMessage());
092            }
093    
094            // Allows the managed object to send notifications
095            if (obj instanceof NotificationSenderAware) {
096                ((NotificationSenderAware)obj).setNotificationSender(new NotificationSenderAdapter(mbean));
097            }
098    
099            return mbean;
100        }
101    
102    }