org.apache.servicemix.nmr.management.ManagementAgent.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.servicemix.nmr.management.ManagementAgent.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.servicemix.nmr.management;

import java.util.EventObject;
import java.util.Set;
import java.util.HashSet;

import javax.jbi.component.ComponentContext;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.JMException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectInstance;
import javax.management.InstanceAlreadyExistsException;
import javax.management.StandardMBean;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.RequiredModelMBean;
import javax.management.modelmbean.InvalidTargetObjectTypeException;

import org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler;
import org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource;
import org.springframework.beans.factory.DisposableBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.servicemix.nmr.management.stats.CountStatistic;
import org.apache.servicemix.nmr.management.stats.TimeStatistic;
import org.fusesource.commons.management.ManagementStrategy;
import org.fusesource.commons.management.Statistic;
import org.fusesource.commons.management.Statistic.UpdateMode;

/**
 */
public class ManagementAgent implements ManagementStrategy, DisposableBean {

    private static final transient Log LOG = LogFactory.getLog(ManagementAgent.class);

    private MBeanServer mbeanServer;
    private MetadataMBeanInfoAssembler assembler;
    private Set<ObjectName> mbeans = new HashSet<ObjectName>();
    private NamingStrategy namingStrategy;

    public ManagementAgent() {
        assembler = new MetadataMBeanInfoAssembler();
        assembler.setAttributeSource(new AnnotationJmxAttributeSource());
    }

    /**
     * @see org.fusesource.commons.management.ManagementStrategy#manageObject(java.lang.Object)
     */
    public void manageObject(Object managedObject) throws Exception {
        ObjectName objectName = getManagedObjectName(managedObject, null, ObjectName.class);
        manageNamedObject(managedObject, objectName);
    }

    /**
     * @see org.fusesource.commons.management.ManagementStrategy#getManagedObjectName(java.lang.Object,java.lang.String,java.lang.Class)
     */
    public <T> T getManagedObjectName(Object managableObject, String customName, Class<T> nameType)
            throws Exception {
        return String.class.equals(nameType) && managableObject == null && customName == null
                ? nameType.cast(namingStrategy.getJmxDomainName())
                : ObjectName.class.equals(nameType)
                        ? nameType.cast(getTypeSpecificObjectName(managableObject, customName))
                        : null;
    }

    /**
     * @see org.fusesource.commons.management.ManagementStrategy#manageNamedObject(java.lang.Object,java.lang.Object)
     */
    public void manageNamedObject(Object managedObject, Object preferredName) throws Exception {
        managedObject = getTypeSpecificManagedObject(managedObject);
        if (preferredName instanceof ObjectName && managedObject != null) {
            try {
                register(managedObject, (ObjectName) preferredName);
            } catch (Exception ex) {
                throw (JMException) new JMException(ex.getMessage()).initCause(ex);
            }
        }
    }

    /**
     * @see org.fusesource.commons.management.ManagementStrategy#unmanageObject(java.lang.Object)
     */
    public void unmanageObject(Object managedObject) throws Exception {
        ObjectName objectName = getManagedObjectName(managedObject, null, ObjectName.class);
        unmanageNamedObject(objectName);
    }

    /**
     * @see org.fusesource.commons.management.ManagementStrategy#unmanageNamedObject(java.lang.Object)
     */
    public void unmanageNamedObject(Object name) throws Exception {
        if (name instanceof ObjectName) {
            unregister((ObjectName) name);
        }
    }

    /**
     * @see org.fusesource.commons.management.ManagementStrategy#isManaged(java.lang.Object,java.lang.Object)
     */
    public boolean isManaged(Object managableObject, Object name) {
        try {
            return managableObject != null
                    ? getMbeanServer().isRegistered(getManagedObjectName(managableObject, null, ObjectName.class))
                    : name != null && name instanceof ObjectName ? getMbeanServer().isRegistered((ObjectName) name)
                            : false;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * @see org.fusesource.commons.management.ManagementStrategy#createStatistic(java.lang.String,java.lang.Object,UpdateMode)
     */
    public Statistic createStatistic(String name, Object owner, UpdateMode updateMode) {
        return updateMode == UpdateMode.COUNTER ? new TimeStatistic(name, null)
                : updateMode == UpdateMode.VALUE ? new CountStatistic(name, null) : null;
    }

    /**
     * A place-holder implementation of notify that logs events to the commons
     * logging Log.
     */
    public void notify(EventObject event) throws Exception {
        if (LOG.isTraceEnabled()) {
            LOG.trace(event.toString());
        }
    }

    public MBeanServer getMbeanServer() {
        return mbeanServer;
    }

    public void setMbeanServer(MBeanServer mbeanServer) {
        this.mbeanServer = mbeanServer;
    }

    public NamingStrategy getNamingStrategy() {
        return namingStrategy;
    }

    public void setNamingStrategy(NamingStrategy namingStrategy) {
        this.namingStrategy = namingStrategy;
    }

    public void destroy() throws Exception {
        // Using the array to hold the busMBeans to avoid the
        // CurrentModificationException
        Object[] mBeans = mbeans.toArray();
        int caught = 0;
        for (Object name : mBeans) {
            mbeans.remove((ObjectName) name);
            try {
                unregister((ObjectName) name);
            } catch (JMException jmex) {
                LOG.info("Exception unregistering MBean", jmex);
                caught++;
            }
        }
        if (caught > 0) {
            LOG.warn("A number of " + caught
                    + " exceptions caught while unregistering MBeans during stop operation.  "
                    + "See INFO log for details.");
        }
    }

    public void register(Object obj, ObjectName name) throws JMException {
        register(obj, name, !(obj instanceof ManagedEndpoint));
    }

    public void register(Object obj, ObjectName name, boolean forceRegistration) throws JMException {
        try {
            registerMBeanWithServer(obj, name, forceRegistration);
        } catch (NotCompliantMBeanException e) {
            // If this is not a "normal" MBean, then try to deploy it using JMX
            // annotations
            ModelMBeanInfo mbi = assembler.getMBeanInfo(obj, name.toString());
            RequiredModelMBean mbean = (RequiredModelMBean) mbeanServer
                    .instantiate(RequiredModelMBean.class.getName());
            mbean.setModelMBeanInfo(mbi);
            try {
                mbean.setManagedResource(obj, "ObjectReference");
            } catch (InvalidTargetObjectTypeException itotex) {
                throw new JMException(itotex.getMessage());
            }
            registerMBeanWithServer(mbean, name, forceRegistration);
        }
    }

    public void unregister(ObjectName name) throws JMException {
        mbeanServer.unregisterMBean(name);
    }

    private void registerMBeanWithServer(Object obj, ObjectName name, boolean forceRegistration)
            throws JMException {
        ObjectInstance instance = null;
        try {
            instance = mbeanServer.registerMBean(obj, name);
        } catch (InstanceAlreadyExistsException e) {
            if (forceRegistration) {
                mbeanServer.unregisterMBean(name);
                instance = mbeanServer.registerMBean(obj, name);
            } else {
                throw e;
            }
        }

        if (instance != null) {
            mbeans.add(name);
        }
    }

    private ObjectName getTypeSpecificObjectName(Object mo, String customName) throws MalformedObjectNameException {
        return mo instanceof ManagedEndpoint ? namingStrategy.getObjectName((ManagedEndpoint) mo)
                : mo instanceof Nameable
                        ? (customName != null
                                ? namingStrategy.getCustomObjectName(customName, ((Nameable) mo).getName())
                                : namingStrategy.getObjectName((Nameable) mo))
                        : mo instanceof ComponentContext
                                ? namingStrategy.getCustomObjectName(customName,
                                        ((ComponentContext) mo).getComponentName())
                                : null;
    }

    private Object getTypeSpecificManagedObject(Object object) throws NotCompliantMBeanException {
        return object instanceof ManagedEndpoint ? object
                : object instanceof Nameable ? new StandardMBean(object, ((Nameable) object).getPrimaryInterface())
                        : null;
    }
}