/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.management.j2ee; import org.jboss.invocation.InvocationStatistics; import org.jboss.logging.Logger; import org.jboss.management.j2ee.statistics.CountStatisticImpl; import org.jboss.management.j2ee.statistics.EJBStatsImpl; import org.jboss.management.j2ee.statistics.TimeStatisticImpl; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.j2ee.statistics.Stats; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; /** * Root class of the JBoss JSR-77.3.10 EJB model * * @author <a href="mailto:andreas@jboss.org">Andreas Schaefer</a> * @author <a href="mailto:scott.stark@jboss.org">Scott Stark</a> * @author <a href="mailto:thomas.diesler@jboss.org">Thomas Diesler</a> * @version $Revision: 81025 $ */ public abstract class EJB extends J2EEManagedObject implements EJBMBean { // Constants ----------------------------------------------------- public static final int ENTITY_BEAN = 0; public static final int STATEFUL_SESSION_BEAN = 1; public static final int STATELESS_SESSION_BEAN = 2; public static final int MESSAGE_DRIVEN_BEAN = 3; // Attributes ---------------------------------------------------- /** The logger */ private static Logger log = Logger.getLogger(EJB.class); /** * The ObjectName of the ejb container MBean */ protected ObjectName ejbContainerName; protected String jndiName; protected String localJndiName; // Static -------------------------------------------------------- /** * Create a JSR77 EJB submodel. * * @param mbeanServer the MBeanServer to use for mbean creation * @param ejbModuleName the name of the JSR77 EJBModule mbean * @param ejbContainerName the name of the JBoss ejb container mbean * @param ejbType an EJB.XXX_BEAN type constant value * @param ejbName the bean ejb-name * @param jndiName the jndi name of the remote home binding if one exists, or null * @param localJndiName the jndi name of the local home binding if one exists, or null * @return the ObjectName of the JSR77 EJB mbean */ public static ObjectName create(MBeanServer mbeanServer, ObjectName ejbModuleName, ObjectName ejbContainerName, int ejbType, String ejbName, String jndiName, String localJndiName) { try { // Now create the EJB mbean EJB ejb = null; switch (ejbType) { case ENTITY_BEAN: ejb = new EntityBean(ejbName, ejbModuleName, ejbContainerName, jndiName, localJndiName); break; case STATEFUL_SESSION_BEAN: ejb = new StatefulSessionBean(ejbName, ejbModuleName, ejbContainerName, jndiName, localJndiName); break; case STATELESS_SESSION_BEAN: ejb = new StatelessSessionBean(ejbName, ejbModuleName, ejbContainerName, jndiName, localJndiName); break; case MESSAGE_DRIVEN_BEAN: ejb = new MessageDrivenBean(ejbName, ejbModuleName, ejbContainerName, localJndiName); break; } ObjectName jsr77Name = ejb.getObjectName(); mbeanServer.registerMBean(ejb, jsr77Name); log.debug("Created JSR-77 EJB: " + jsr77Name); return jsr77Name; } catch (Exception e) { log.debug("Could not create JSR-77 EJB: " + ejbName, e); return null; } } public static void destroy(MBeanServer mbeanServer, ObjectName jsr77Name) { try { // Now remove the EJB mbeanServer.unregisterMBean(jsr77Name); log.debug("Destroyed JSR-77 EJB: " + jsr77Name); } catch (javax.management.InstanceNotFoundException ignore) { } catch (Exception e) { log.debug("Could not destroy JSR-77 EJB: " + jsr77Name, e); } } // Constructors -------------------------------------------------- /** * Create a EJB model * * @param ejbType the EJB.EJB_TYPES string * @param ejbName the ejb-name from the deployment * @param ejbModuleName the JSR-77 EJBModule name for this bean * @param ejbContainerName the JMX name of the JBoss ejb container MBean * @throws MalformedObjectNameException * @throws InvalidParentException */ public EJB(String ejbType, String ejbName, ObjectName ejbModuleName, ObjectName ejbContainerName) throws MalformedObjectNameException, InvalidParentException { this(ejbType, ejbName, ejbModuleName, ejbContainerName, null, null); } /** * Create a EJB model * * @param ejbType the EJB.EJB_TYPES string * @param ejbName the ejb-name from the deployment * @param ejbModuleName the JSR-77 EJBModule name for this bean * @param ejbContainerName the JMX name of the JBoss ejb container MBean * @param jndiName the jndi name of the remote home binding is one exists, * null if there is no remote home. * @param localJndiName the jndi name of the local home binding is one exists, * null if there is no local home. * @throws MalformedObjectNameException * @throws InvalidParentException */ public EJB(String ejbType, String ejbName, ObjectName ejbModuleName, ObjectName ejbContainerName, String jndiName, String localJndiName) throws MalformedObjectNameException, InvalidParentException { super(ejbType, ejbName, ejbModuleName); this.ejbContainerName = ejbContainerName; this.jndiName = jndiName; this.localJndiName = localJndiName; } // Begin StatisticsProvider interface methods /** * Obtain the Stats from the StatisticsProvider. * * @return An EJBStats subclass * @jmx:managed-attribute */ public abstract Stats getstats(); /** * Reset all statistics in the StatisticsProvider * * @jmx:managed-operation */ public abstract void resetStats(); // End StatisticsProvider interface methods public String getJndiName() { return this.jndiName; } public String getLocalJndiName() { return this.localJndiName; } // java.lang.Object overrides -------------------------------------- public String toString() { return "EJB { " + super.toString() + " } []"; } // Package protected --------------------------------------------- // Protected ----------------------------------------------------- /** * Obtain the Stats from the StatisticsProvider. This method simply * updates the statistics common to all EJBs: * CreateCount * RemoveCount * InvocationTimes * <p/> * It should be invoked to update these common statistics. */ protected void updateCommonStats(EJBStatsImpl stats) { try { ObjectName containerName = getContainerName(); CountStatisticImpl createCount = (CountStatisticImpl) stats.getCreateCount(); Long creates = (Long) server.getAttribute(containerName, "CreateCount"); createCount.set(creates.longValue()); CountStatisticImpl removeCount = (CountStatisticImpl) stats.getRemoveCount(); Long removes = (Long) server.getAttribute(containerName, "RemoveCount"); removeCount.set(removes.longValue()); // Now build a TimeStatistics for every InvocationStatistics times = (InvocationStatistics) server.getAttribute(containerName, "InvokeStats"); HashMap timesMap = new HashMap(times.getStats()); Iterator iter = timesMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Method m = (Method) entry.getKey(); InvocationStatistics.TimeStatistic stat = (InvocationStatistics.TimeStatistic) entry.getValue(); TimeStatisticImpl tstat = new TimeStatisticImpl(m.getName(), StatisticsConstants.MILLISECOND, "The timing information for the given method"); tstat.set(stat.count, stat.minTime, stat.maxTime, stat.totalTime); stats.addStatistic(m.getName(), tstat); } } catch (Exception e) { log.debug("Failed to retrieve stats", e); } } /** * @return the JMX name of the EJB container */ protected ObjectName getContainerName() { return this.ejbContainerName; } /** * @return the JMX name of the EJB container cache */ protected ObjectName getContainerCacheName() { ObjectName cacheName = null; try { Hashtable props = ejbContainerName.getKeyPropertyList(); props.put("plugin", "cache"); cacheName = new ObjectName(ejbContainerName.getDomain(), props); } catch (MalformedObjectNameException e) { } return cacheName; } /** * @return the JMX name of the EJB container pool */ protected ObjectName getContainerPoolName() { ObjectName poolName = null; try { Hashtable props = ejbContainerName.getKeyPropertyList(); props.put("plugin", "pool"); poolName = new ObjectName(ejbContainerName.getDomain(), props); } catch (MalformedObjectNameException e) { } return poolName; } /** * @return A hashtable with the EJB-Module, J2EE-Application and J2EE-Server as parent */ protected Hashtable getParentKeys(ObjectName pParent) { Hashtable lReturn = new Hashtable(); Hashtable lProperties = pParent.getKeyPropertyList(); lReturn.put(J2EETypeConstants.EJBModule, lProperties.get("name")); // J2EE-Application and J2EE-Server is already parent of J2EE-Application therefore lookup // the name by the J2EE-Server type lReturn.put(J2EETypeConstants.J2EEApplication, lProperties.get(J2EETypeConstants.J2EEApplication)); lReturn.put(J2EETypeConstants.J2EEServer, lProperties.get(J2EETypeConstants.J2EEServer)); return lReturn; } // Private ------------------------------------------------------- // Inner classes ------------------------------------------------- }