All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jppf.management.spi.JPPFMBeanProviderManager Maven / Gradle / Ivy

There is a newer version: 6.3-alpha
Show newest version
/*
 * JPPF.
 * Copyright (C) 2005-2015 JPPF Team.
 * http://www.jppf.org
 *
 * Licensed 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.jppf.management.spi;

import java.util.*;

import javax.management.*;

import org.jppf.utils.*;
import org.jppf.utils.hooks.*;
import org.slf4j.*;

/**
 * Instances of this class manage all management plugins defined through the Service Provider Interface.
 * @param  the SPI interface for the mbean provider.
 * @author Laurent Cohen
 */
public class JPPFMBeanProviderManager {
  /**
   * Logger for this class.
   */
  private static Logger log = LoggerFactory.getLogger(JPPFMBeanProviderManager.class);
  /**
   * Determines whether debug log statements are enabled.
   */
  private static boolean debugEnabled = LoggingUtils.isDebugEnabled(log);
  /**
   * Keeps a list of MBeans registered with the MBean server.
   */
  private List registeredMBeanNames = new Vector<>();
  /**
   * The mbean server with which all mbeans are registered.
   */
  private MBeanServer server = null;

  /**
   * Initialize this mbean provider manager and register the MBeans implementing the specified provider interface.
   * @param clazz the class object for the provider interface.
   * @param cl the class loader used to oad the MBean implementation classes.
   * @param createParams the parameters used to create the MBean implementations.
   * @param server the MBean server on which to register.
   * @throws Exception if the registration failed.
   */
  public JPPFMBeanProviderManager(final Class clazz, final ClassLoader cl, final Object server, final Object...createParams) throws Exception {
    this.server = (MBeanServer) server;
    ClassLoader tmp = Thread.currentThread().getContextClassLoader();
    ClassLoader loader = cl == null ? tmp : cl;
    if (loader == null) loader = getClass().getClassLoader();
    Hook hook = HookFactory.registerSPIMultipleHook(clazz, null, loader);
    try {
      Thread.currentThread().setContextClassLoader(cl);
      for (HookInstance hookInstance: hook.getInstances()) {
        S concrete = hookInstance.getInstance();
        try {
          Object mbean = hookInstance.invoke("createMBean", createParams);
          if (mbean == null) continue;
          String infName = (String) hookInstance.invoke("getMBeanInterfaceName");
          Class inf = Class.forName((String) infName, true, loader);
          String mbeanName = (String) hookInstance.invoke("getMBeanName");
          boolean b = registerProviderMBean(mbean, inf, mbeanName);
          if (debugEnabled) log.debug("MBean registration " + (b ? "succeeded" : "failed") + " for [" + mbeanName + ']');
          if (b) registeredMBeanNames.add((String) mbeanName);
        } catch (Exception e) {
          String message = "error processing MBean provider {} : {}";
          if (debugEnabled) log.debug(message, concrete, ExceptionUtils.getStackTrace(e));
          else log.warn(message, concrete, ExceptionUtils.getMessage(e));
        }
      }
    } finally {
      Thread.currentThread().setContextClassLoader(tmp);
    }
  }

  /**
   * Register the specified MBean.
   * @param  the type of the MBean interface.
   * @param impl the MBean implementation.
   * @param intf the MBean exposed interface.
   * @param name the MBean name.
   * @return true if the registration succeeded, false otherwise.
   */
  private  boolean registerProviderMBean(final T impl, final Class intf, final String name) {
    try {
      if (debugEnabled) log.debug("found MBean provider: [name="+name+", inf="+intf+", impl="+impl.getClass().getName()+ ']');
      ObjectName objectName = new ObjectName(name);
      if (!server.isRegistered(objectName)) {
        server.registerMBean(impl, objectName);
        return true;
      } else log.warn("an instance of MBean [" + name + "] already exists, registration was skipped");
    } catch(Exception e) {
      log.error(e.getMessage(), e);
    }
    return false;
  }

  /**
   * Un-register all registered mbeans.
   */
  public void unregisterProviderMBeans() {
    if (debugEnabled) log.debug("list of registered MBeans {}", registeredMBeanNames);
    while (!registeredMBeanNames.isEmpty()) {
      String s = registeredMBeanNames.remove(0);
      try {
        server.unregisterMBean(new ObjectName(s));
        if (debugEnabled) log.debug("MBean un-registration succeeded for [{}]", s);
      } catch(Exception e) {
        String format = "MBean un-registration failed for [{}] : {}";
        if (debugEnabled) log.debug(format, s, ExceptionUtils.getStackTrace(e));
        else log.warn(format, s, ExceptionUtils.getMessage(e));
      }
    }
  }
}