/* * Mobicents: The Open Source SLEE Platform * * Copyright 2003-2005, CocoonHive, LLC., * and individual contributors as indicated * by the @authors tag. See the copyright.txt * 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 General Public License (GPL) as * published by the Free Software Foundation; * either version 2 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 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.mobicents.slee.container; import java.io.File; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.slee.management.SleeManagementMBean; import javax.slee.management.SleeState; import javax.slee.profile.ProfileFacility; import org.apache.log4j.Logger; import org.jboss.mx.util.MBeanProxy; import org.jboss.mx.util.MBeanServerLocator; import org.jboss.util.naming.Util; import org.jboss.virtual.VFS; import org.jboss.virtual.VFSUtils; import org.mobicents.cluster.MobicentsCluster; import org.mobicents.slee.container.component.ComponentRepositoryImpl; import org.mobicents.slee.container.component.management.DeployableUnitManagement; import org.mobicents.slee.container.management.ResourceManagement; import org.mobicents.slee.container.management.SbbManagement; import org.mobicents.slee.container.management.ServiceManagement; import org.mobicents.slee.container.management.SleeProfileTableManager; import org.mobicents.slee.container.management.jmx.AlarmMBeanImpl; import org.mobicents.slee.container.management.jmx.MobicentsManagement; import org.mobicents.slee.container.management.jmx.TraceMBeanImpl; import org.mobicents.slee.container.management.jmx.editors.SleePropertyEditorRegistrator; import org.mobicents.slee.container.profile.ProfileObjectPoolManagement; import org.mobicents.slee.container.rmi.RmiServerInterfaceMBean; import org.mobicents.slee.container.service.ServiceActivityContextInterfaceFactoryImpl; import org.mobicents.slee.container.service.ServiceActivityFactoryImpl; import org.mobicents.slee.runtime.activity.ActivityContextFactoryImpl; import org.mobicents.slee.runtime.eventrouter.EventRouter; import org.mobicents.slee.runtime.eventrouter.EventRouterImpl; import org.mobicents.slee.runtime.facilities.ActivityContextNamingFacilityImpl; import org.mobicents.slee.runtime.facilities.TimerFacilityImpl; import org.mobicents.slee.runtime.facilities.nullactivity.NullActivityContextInterfaceFactoryImpl; import org.mobicents.slee.runtime.facilities.nullactivity.NullActivityFactoryImpl; import org.mobicents.slee.runtime.facilities.profile.ProfileFacilityImpl; import org.mobicents.slee.runtime.facilities.profile.ProfileTableActivityContextInterfaceFactoryImpl; import org.mobicents.slee.runtime.sbb.SbbObjectPoolManagement; import org.mobicents.slee.runtime.transaction.SleeTransactionManager; import org.mobicents.slee.util.JndiRegistrationManager; /** * Implements the SleeContainer. The SleeContainer is the anchor for the Slee. * It is the central location from where all other major data structures are * accessible. * * @author F.Moggia * @author M. Ranganathan * @author Ivelin Ivanov * @author Emil Ivov * @author Tim Fox * @author eduardomartins */ public class SleeContainer { // STATIC private final static Logger logger = Logger.getLogger(SleeContainer.class); // static init code static { // establish the location of mobicents.sar try { java.net.URL url = VFSUtils.getCompatibleURL(VFS.getRoot(SleeContainer.class.getClassLoader() .getResource(".."))); java.net.URI uri = new java.net.URI(url.toExternalForm() .replaceAll(" ", "%20")); deployPath = new File(uri).getAbsolutePath(); } catch (Exception e) { logger .error( "Failed to establish path to Mobicents root deployment directory (mobicents.sar)", e); deployPath = null; } // Config JUL logger to use Log4J filter Handler[] handlers = java.util.logging.Logger.getLogger("") .getHandlers(); for (Handler handler : handlers) if (handler instanceof ConsoleHandler) handler.setFilter(new MobicentsLogFilter()); } private static String deployPath; /** * * @return the full file system path where mobicents.sar is located */ public static String getDeployPath() { return deployPath; } private static SleeContainer sleeContainer; private final SleeTransactionManager sleeTransactionManager; private final MobicentsCluster cluster; // FIELDS // mbean server where the container's mbeans are registred private final MBeanServer mbeanServer; /** The lifecycle state of the SLEE */ private SleeState sleeState; // the class that actually posts events to the SBBs. // This should be made into a facility and registered with jmx and jndi // so it can be independently controlled. private EventRouter router; // monitor object for sync on management operations private final Object managementMonitor = new Object(); // for external access to slee private RmiServerInterfaceMBean rmiServerInterfaceMBeanImpl; // component managers private final ComponentRepositoryImpl componentRepositoryImpl; private final ServiceManagement serviceManagement; private final SleeProfileTableManager sleeProfileTableManager; private final ResourceManagement resourceManagement; private final SbbManagement sbbManagement; // object pool management private final SbbObjectPoolManagement sbbPoolManagement; private final ProfileObjectPoolManagement profileObjectPoolManagement; // non clustered scheduler private ScheduledExecutorService nonClusteredScheduler; private static final int NON_CLUSTERED_SCHEDULER_THREADS = 8; /** * where DUs are stored */ private final DeployableUnitManagement deployableUnitManagement = new DeployableUnitManagement(); // slee factories private final ActivityContextFactoryImpl activityContextFactory; private final NullActivityContextInterfaceFactoryImpl nullActivityContextInterfaceFactory; private final NullActivityFactoryImpl nullActivityFactory; private final ProfileTableActivityContextInterfaceFactoryImpl profileTableActivityContextInterfaceFactory; private final ServiceActivityContextInterfaceFactoryImpl serviceActivityContextInterfaceFactory; private final ServiceActivityFactoryImpl serviceActivityFactory; // slee facilities private final ActivityContextNamingFacilityImpl activityContextNamingFacility; private final AlarmMBeanImpl alarmMBeanImpl; private final TraceMBeanImpl traceMBeanImpl; private final ProfileFacilityImpl profileFacility; private final TimerFacilityImpl timerFacility; private final MobicentsUUIDGenerator uuidGenerator = MobicentsUUIDGenerator.getInstance(); // LIFECYLE RELATED /** * Creates a new instance of SleeContainer -- This is called from the * SleeManagementMBean to get the whole thing running. * */ public SleeContainer(SleeTransactionManager sleeTransactionManager, MobicentsCluster cluster, AlarmMBeanImpl alarmMBeanImpl, TraceMBeanImpl traceMBeanImpl) throws Exception { if (sleeTransactionManager == null) { throw new NullPointerException("null slee transaction manager"); } if (cluster == null) { throw new NullPointerException("null cluster"); } if (alarmMBeanImpl == null) { throw new NullPointerException("null alarm mbean"); } if (traceMBeanImpl == null) { throw new NullPointerException("null trace mbean"); } // created in STOPPED state and remain so until started this.sleeState = SleeState.STOPPED; this.mbeanServer = MBeanServerLocator.locateJBoss(); this.sleeTransactionManager = sleeTransactionManager; this.cluster = cluster; this.alarmMBeanImpl = alarmMBeanImpl; this.traceMBeanImpl = traceMBeanImpl; // Force this property to allow invocation of getters. // http://code.google.com/p/mobicents/issues/detail?id=63 System.setProperty("jmx.invoke.getters", "true"); this.componentRepositoryImpl = new ComponentRepositoryImpl(); this.serviceManagement = new ServiceManagement(this); this.sleeProfileTableManager = new SleeProfileTableManager(this); this.sbbManagement = new SbbManagement(this); this.resourceManagement = new ResourceManagement(this); this.activityContextFactory = new ActivityContextFactoryImpl(this); this.activityContextNamingFacility = new ActivityContextNamingFacilityImpl(this); this.nullActivityFactory = new NullActivityFactoryImpl(this); this.nullActivityContextInterfaceFactory = new NullActivityContextInterfaceFactoryImpl( this); this.profileTableActivityContextInterfaceFactory = new ProfileTableActivityContextInterfaceFactoryImpl(this); this.timerFacility = new TimerFacilityImpl(this); this.profileFacility = new ProfileFacilityImpl(this); this.serviceActivityFactory = new ServiceActivityFactoryImpl(this); this.serviceActivityContextInterfaceFactory = new ServiceActivityContextInterfaceFactoryImpl(this); this.sbbPoolManagement = new SbbObjectPoolManagement(this); this.profileObjectPoolManagement = new ProfileObjectPoolManagement(this); } /** * Initialization code. * */ public void init(SleeManagementMBean sleeManagementMBean, ObjectName rmiServerInterfaceMBean) throws Exception { logger.info("Initializing SLEE container..."); // init jndi Context ctx = new InitialContext(); ctx = Util.createSubcontext(ctx, JVM_ENV + CTX_SLEE); Util.createSubcontext(ctx, "resources"); Util.createSubcontext(ctx, "container"); Util.createSubcontext(ctx, "facilities"); Util.createSubcontext(ctx, "sbbs"); ctx = Util.createSubcontext(ctx, "nullactivity"); Util.createSubcontext(ctx, "factory"); Util.createSubcontext(ctx, "nullactivitycontextinterfacefactory"); // TODO possibly make nthreads configurable? this.nonClusteredScheduler = new ScheduledThreadPoolExecutor(NON_CLUSTERED_SCHEDULER_THREADS); this.router = new EventRouterImpl(this,MobicentsManagement.eventRouterExecutors,MobicentsManagement.monitoringUncommittedAcAttachs); JndiRegistrationManager.registerWithJndi("slee/facilities", "activitycontextnaming", activityContextNamingFacility); JndiRegistrationManager.registerWithJndi("slee/nullactivity", "nullactivitycontextinterfacefactory", nullActivityContextInterfaceFactory); JndiRegistrationManager.registerWithJndi("slee/nullactivity", "nullactivityfactory", nullActivityFactory); JndiRegistrationManager.registerWithJndi("slee/facilities", ProfileTableActivityContextInterfaceFactoryImpl.JNDI_NAME, profileTableActivityContextInterfaceFactory); JndiRegistrationManager.registerWithJndi("slee/facilities", TimerFacilityImpl.JNDI_NAME, timerFacility); JndiRegistrationManager.registerWithJndi("slee/facilities", ProfileFacilityImpl.JNDI_NAME, profileFacility); JndiRegistrationManager.registerWithJndi("slee/serviceactivity/", ServiceActivityFactoryImpl.JNDI_NAME, serviceActivityFactory); JndiRegistrationManager.registerWithJndi("slee/serviceactivity/", ServiceActivityContextInterfaceFactoryImpl.JNDI_NAME, serviceActivityContextInterfaceFactory); JndiRegistrationManager.registerWithJndi("slee/facilities", AlarmMBeanImpl.JNDI_NAME, alarmMBeanImpl); JndiRegistrationManager.registerWithJndi("slee/facilities", TraceMBeanImpl.JNDI_NAME, traceMBeanImpl.getTraceFacility()); registerWithJndi(); startRMIServer(rmiServerInterfaceMBean); // Register property editors for the composite SLEE types so that the // jboss jmx console can pass it as an argument. new SleePropertyEditorRegistrator().register(); this.sbbPoolManagement.register(); this.profileObjectPoolManagement.register(); } /** * * Cleanup in the reverse order of init() * * @throws NamingException * */ public void close() throws NamingException { unregisterWithJndi(); Context ctx = new InitialContext(); Util.unbind(ctx, JVM_ENV + CTX_SLEE); stopRMIServer(); nonClusteredScheduler.shutdown(); nonClusteredScheduler = null; } /** * Get the current state of the Slee Container * * @return SleeState */ public SleeState getSleeState() { return this.sleeState; } /** * Set the current state of the Slee Container. CAUTION: Do not invoke this * method directly! Use the SleeManagementMBean to change the Slee State * * @param SleeState */ public SleeState setSleeState(SleeState newState) { return this.sleeState = newState; } /** * dumps the container state as a string, useful for debug/profiling * * @return */ public String dumpState() { return deployableUnitManagement + "\n" + componentRepositoryImpl + "\n" + resourceManagement + "\n" + sbbPoolManagement + "\n" + timerFacility + "\n" + traceMBeanImpl + "\n" + sleeProfileTableManager + "\n" + profileObjectPoolManagement + "\n" + activityContextFactory + "\n" + activityContextNamingFacility + "\n" + nullActivityFactory + "\n" + getEventRouter() + "\n" + getTransactionManager(); } // GETTERS -- managers /** * object for synchronization on management operations that (un)install * components */ public Object getManagementMonitor() { return managementMonitor; } /** * retrieves the container's component repository implementation * @return */ public ComponentRepositoryImpl getComponentRepositoryImpl() { return componentRepositoryImpl; } /** * Retrieves the container's non clustered scheduler. * * @return the nonClusteredScheduler */ public ScheduledExecutorService getNonClusteredScheduler() { return nonClusteredScheduler; } /** * manages (un)install of resource adaptors * * @return */ public ResourceManagement getResourceManagement() { return resourceManagement; } /** * manages (un)install of sbbs * * @return */ public SbbManagement getSbbManagement() { return sbbManagement; } /** * Retrieves the manager of sbb object pools * @return */ public SbbObjectPoolManagement getSbbPoolManagement() { return sbbPoolManagement; } /** * Retrieves the profile object pool management * @return */ public ProfileObjectPoolManagement getProfileObjectPoolManagement() { return profileObjectPoolManagement; } /** * manages (un)install of services * * @return */ public ServiceManagement getServiceManagement() { return this.serviceManagement; } public SleeProfileTableManager getSleeProfileTableManager() { return this.sleeProfileTableManager; } /** * Retrieves the deployable unit manager * @return */ public DeployableUnitManagement getDeployableUnitManagement() { return deployableUnitManagement; } // GETTERS -- slee factories public ActivityContextFactoryImpl getActivityContextFactory() { return this.activityContextFactory; } public NullActivityContextInterfaceFactoryImpl getNullActivityContextInterfaceFactory() { return this.nullActivityContextInterfaceFactory; } public NullActivityFactoryImpl getNullActivityFactory() { return this.nullActivityFactory; } public ProfileTableActivityContextInterfaceFactoryImpl getProfileTableActivityContextInterfaceFactory() { return profileTableActivityContextInterfaceFactory; } public ServiceActivityContextInterfaceFactoryImpl getServiceActivityContextFactory() { return this.serviceActivityContextInterfaceFactory; } /** * * @return the serviceActivityFactory */ public ServiceActivityFactoryImpl getServiceActivityFactory() { return serviceActivityFactory; } // GETTERS -- slee facilities public javax.slee.facilities.ActivityContextNamingFacility getActivityContextNamingFacility() { return activityContextNamingFacility; } /** * * @return */ public AlarmMBeanImpl getAlarmMBean() { return alarmMBeanImpl; } /** * * @return */ public ProfileFacility getProfileFacility() { return profileFacility; } /** * * @return */ public TimerFacilityImpl getTimerFacility() { return timerFacility; } /** * * @return */ public TraceMBeanImpl getTraceMBean() { return traceMBeanImpl; } // GETTERS -- slee runtime /** * a UUID generator for the container */ public MobicentsUUIDGenerator getUuidGenerator() { return uuidGenerator; } /** * the container's event router */ public EventRouter getEventRouter() { return this.router; } /** * Get the transaction manager * * @throws */ public SleeTransactionManager getTransactionManager() { return sleeTransactionManager; } /** * The cache which manages the container's HA and FT data * @return */ public MobicentsCluster getCluster() { return cluster; } /** * Return the MBeanServer that the SLEEE is registers with in the current * JVM */ public MBeanServer getMBeanServer() { return mbeanServer; } // RMI RELATED /* * Start the HA RMI Server, used by JCA resource adaptors to communicate * with the SLEE */ private void startRMIServer(ObjectName rmiServerInterfaceMBean) { try { logger.debug("creating RmiServerInterface using MBeanProxy"); rmiServerInterfaceMBeanImpl = (RmiServerInterfaceMBean) MBeanProxy .get(RmiServerInterfaceMBean.class, rmiServerInterfaceMBean, mbeanServer); rmiServerInterfaceMBeanImpl.startRMIServer(); } catch (Throwable e) { logger.error( "Failed to start HA RMI server for Remote slee service", e); } } private void stopRMIServer() { logger.debug("Stopping RMI Server for slee service"); rmiServerInterfaceMBeanImpl.stopRMIServer(); } public int getRmiRegistryPort() throws Exception { Integer port = (Integer) mbeanServer.getAttribute(new ObjectName( "slee:service=SleeTCKWrapper"), "RMIRegistryPort"); return port.intValue(); } // JNDI RELATED // For unit testing only -- to be removed later. private static final String JNDI_NAME = "container"; public static final String JVM_ENV = "java:"; /** standard ENC name in JNDI */ public static final String COMP_ENV = "java:comp/env"; /** the root context for SLEE */ private static final String CTX_SLEE = "slee"; /** * Return the SleeContainer instance registered in the JVM scope of JNDI */ public static SleeContainer lookupFromJndi() { try { if (sleeContainer != null) return sleeContainer; else { sleeContainer = (SleeContainer) JndiRegistrationManager.getFromJndi("slee/" + JNDI_NAME); return sleeContainer; } } catch (Exception ex) { logger.error("Unexpected error: Cannot retrieve SLEE Container!", ex); return null; } } private void registerWithJndi() { JndiRegistrationManager.registerWithJndi("slee", JNDI_NAME, this); } private void unregisterWithJndi() { JndiRegistrationManager.unregisterWithJndi("slee/" + JNDI_NAME); } }