FileDocCategorySizeDatePackage
BasicCustomMBeanOperations.javaAPI DocGlassfish v2 API18129Fri May 04 22:24:10 BST 2007com.sun.enterprise.admin.mbeans.custom

BasicCustomMBeanOperations

public class BasicCustomMBeanOperations extends Object implements CustomMBeanOperationsMBean

Fields Summary
protected final com.sun.enterprise.config.ConfigContext
acc
The instance of AdminContext that correpsponds to configuration on disk
Constructors Summary
public BasicCustomMBeanOperations()

        this.acc = MBeanRegistryFactory.getAdminContext().getAdminConfigContext();
    
Methods Summary
protected java.util.MapcheckAndModifyParamsForName(java.util.Map params)

        checkParams(params);
        final Map<String, String> paramsWithNameKey = putNameIfAbsent(params); // possibly changes the params
        //at this point, it can be safely assumed that both name and class-name of the custom-mbean are available
        final String name = paramsWithNameKey.get(CustomMBeanConstants.NAME_KEY);
        return ( paramsWithNameKey );
    
protected voidcheckParams(java.util.Map params)

        if (!params.containsKey(CustomMBeanConstants.IMPL_CLASS_NAME_KEY))
            throw new IllegalArgumentException(CMBStrings.get("NoImplClass"));
        checkValidIfPresent(params);
        checkValidObjectNameIfPresent(params);
    
private voidcheckValidIfPresent(java.util.Map params)

        final String nameKey    = CustomMBeanConstants.NAME_KEY;
        final String name       = params.get(nameKey);
        final String cKey       = CustomMBeanConstants.IMPL_CLASS_NAME_KEY;
        final String cVal       = params.get(cKey);
        final String onKey      = CustomMBeanConstants.OBJECT_NAME_KEY;
        final String onVal      = params.get(onKey);
        if (params.containsKey(nameKey) && name == null)

            throw new IllegalArgumentException(CMBStrings.get("MapHasNullParam", "Name"));
        if (params.containsKey(cKey) && cVal == null)
            throw new IllegalArgumentException(CMBStrings.get("MapHasNullParam", "ClassName"));
        if (params.containsKey(onKey) && onVal == null)
            throw new IllegalArgumentException(CMBStrings.get("MapHasNullParam", "ObjectName"));
    
private voidcheckValidObjectNameIfPresent(java.util.Map params)

        final String onKey      = CustomMBeanConstants.OBJECT_NAME_KEY;
        final String onVal      = params.get(onKey);
        boolean onSpecified     = params.containsKey(onKey) && onVal != null;
        ObjectName on           = null;
        if (onSpecified) {
            try {
                on = new ObjectName(onVal); //see if JMX likes it
            } catch(final MalformedObjectNameException me) {
                throw new IllegalArgumentException(me);
            }
            if (on.isPattern())
                throw new IllegalArgumentException(CMBStrings.get("ObjectNamePattern"));
            final String d = on.getDomain();
            if (!CustomMBeanConstants.CUSTOM_MBEAN_DOMAIN.equals(d)) {
                throw new IllegalArgumentException (CMBStrings.get("BadDomainName", d, CustomMBeanConstants.CUSTOM_MBEAN_DOMAIN));
            }
            if (on.getKeyProperty(CustomMBeanConstants.SERVER_KEY) != null) {
                throw new IllegalArgumentException(CMBStrings.get("ObjectNameReserved", on.toString(), CustomMBeanConstants.SERVER_KEY));
            }
        }
    
public java.lang.StringcreateMBean(java.lang.String target, java.lang.String className)

        final Map<String, String> params        = CustomMBeanConstants.unmodifiableMap(CustomMBeanConstants.IMPL_CLASS_NAME_KEY, className);
        final Map<String, String> attributes    = Collections.emptyMap();
        return ( this.createMBean(target, params, attributes) );
    
public java.lang.StringcreateMBean(java.lang.String target, java.util.Map params)

        final Map<String, String> attributes = Collections.emptyMap();
        return ( this.createMBean(target, params, attributes) );
    
public java.lang.StringcreateMBean(java.lang.String target, java.util.Map params, java.util.Map attributes)

        if (params == null || attributes == null)
            throw new IllegalArgumentException(CMBStrings.get("InternalError", "null argument"));
        Target t = null;
        try {
            t = TargetBuilder.INSTANCE.createTarget(target, this.acc);
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
        return ( this.createMBeanDefinitionAddingReferenceToServer(t.getName(), params, attributes) );
    
protected java.lang.StringcreateMBeanDefinitionAddingReferenceToServer(java.lang.String s, java.util.Map params, java.util.Map attributes)
Method that does bulk of the work to fulfill most of the functionality of this class. Other methods in this class and any subclasses should consider calling this method. It does the validation checks before creating the mbean definition in server's configuration. Most importantly, if all is well, a custom MBean definition will be created and an application-ref will be created for a server so that when the target server starts up, this mbean (which is referenced) is available for registration.

param
s String representing the name of the server instance
param
params a Map specifying the other parameters optionally needed for mbean
param
attributes a Map specifying the custom MBean initialization attributes

        try {
            final Mbean mbean = this.createMBeanDefinitionInDomain(params,  attributes);
            final ObjectName onPostReg = new ObjectName(mbean.getObjectName());

			// bug 6308668
			// the mbean was created but never deleted IN THE CONTEXT
			if (onExists(s, onPostReg))  //use references here, because object-name is NOT a primary key unlike name
			{
				ServerBeansFactory.removeMbeanDefinition(acc, mbean.getName());
	
                throw new CustomMBeanException(CMBStrings.get("AlreadyExists",  onPostReg.toString()));
			}
            ServerBeansFactory.addMbeanReference(this.acc, mbean.getName(), s);
            return ( mbean.getName() );
        } catch (final Exception e) {
            throw new CustomMBeanException(e);
        }
    
protected com.sun.enterprise.config.serverbeans.MbeancreateMBeanDefinitionInDomain(java.util.Map params, java.util.Map attributes)

        final Map<String, String> mm = checkAndModifyParamsForName(params);
        final String name = mm.get(CustomMBeanConstants.NAME_KEY);
        if (definitionExists(name))
            throw new CustomMBeanException(CMBStrings.get("AlreadyExists",  name));
        final ObjectName onPostReg = selectObjectName(mm, attributes);
        if (!CustomMBeanConstants.CUSTOM_MBEAN_DOMAIN.equals(onPostReg.getDomain())) {
                throw new IllegalArgumentException (CMBStrings.get("BadDomainName", onPostReg.getDomain(), CustomMBeanConstants.CUSTOM_MBEAN_DOMAIN));
        }
        // Now we mutate the params with "final" valid values
        mm.put(CustomMBeanConstants.OBJECT_NAME_KEY, onPostReg.toString()); //put the correct object-name to map
        final Mbean mbean = MBeanValidator.toMbean(mm, attributes, true);
        try {
            ServerBeansFactory.addMbeanDefinition(this.acc, mbean);
        } catch (final Exception e) {
            throw new CustomMBeanException(e);
        }
        return ( mbean );
    
public voidcreateMBeanRef(java.lang.String target, java.lang.String ref)

        throw new UnsupportedOperationException(CMBStrings.get("InternalError", "Not to be called on PE"));
    
private java.util.MapcreateTestMap(java.util.Map params, javax.management.ObjectName on)

        final Map<String, String> nm = new HashMap<String, String> (params);
        nm.put(CustomMBeanConstants.OBJECT_NAME_KEY, on.toString());
        return ( nm );
    
protected booleandefinitionExists(java.lang.String name)

        boolean exists = false;
        try {
            final List<Mbean> mbeans = ServerBeansFactory.getAllMBeanDefinitions(acc);
            for (Mbean m : mbeans) {
                if (m.getName().equals(name)) {
                    exists = true;
                    break;
                }
                    
            }
            return (exists);
        } catch (final Exception e) {
            throw new CustomMBeanException(e);
        }
    
public java.lang.StringdeleteMBean(java.lang.String target, java.lang.String name)

        if (name == null)
          throw new IllegalArgumentException(CMBStrings.get("InternalError", "null argument"));
     
        Target t = null;
        try {
            t = TargetBuilder.INSTANCE.createTarget(target, this.acc);
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
        
        return ( this.deleteMBeanDefinitionRemovingReferenceFromDomain(t.getName(), name) );
    
protected java.lang.StringdeleteMBeanDefinitionRemovingReferenceFromDomain(java.lang.String s, java.lang.String name)

        boolean refd;
        try {
            refd = ServerBeansFactory.isReferencedMBean(acc, s, name);
        } catch(final Exception e) {
            throw new RuntimeException(e);
        }
        if (!refd) {
            throw new RuntimeException(CMBStrings.get("RefsNotFound", s, name));
        }
        removeMBeanDefinitionAndReferenceFromConfigTree(s, name);
        return ( name );
    
public voiddeleteMBeanRef(java.lang.String target, java.lang.String ref)

        throw new UnsupportedOperationException(CMBStrings.get("InternalError", "Not to be called on PE"));
    
public javax.management.MBeanInfogetMBeanInfo(java.lang.String classname)
Return the MBeanInfo of a given Custom MBean. The MBean must be loadable from the standard App Server location. The code does this:
  • Register the MBean in the MBeanServer
  • Fetch and save the MBeanInfo
  • Unregister the MBean
Note that if the MBean can't be deployed successfully then this method won't work.

param
classname
throws
com.sun.enterprise.admin.mbeans.custom.CustomMBeanException
return
The MBeanInfo object.

        try
        {
            // create some unique names...
            final String oname = "user:getMBeanInfo=" + System.nanoTime();   
            final String name = "getMBeanInfo" + System.nanoTime();   

            // create an MBean object because our helper code uses them...
            Mbean mbean = new Mbean();
            mbean.setImplClassName(classname);
            mbean.setName(name);
            mbean.setObjectName(oname);
            mbean.setEnabled(true);

            // fetch the MBeanServer
            final MBeanServer mbs = MBeanServerFactory.getMBeanServer();

            // Create a helper to do the reg/unreg...
            CustomMBeanRegistrationImpl cmr = new CustomMBeanRegistrationImpl(mbs);

            // register it
            cmr.registerMBean(mbean);

            // get the REAL ObjectName
            ObjectName ron = cmr.getCascadingAwareObjectName(mbean);

            // now fetch the MBeanInfo
            MBeanInfo info = mbs.getMBeanInfo(ron);

            // unregister it...
            mbs.unregisterMBean(ron);

            return info;
        }
        catch(Exception e)
        {
            throw new CustomMBeanException(e);
        }
    
protected booleanonExists(java.lang.String server, javax.management.ObjectName on)

        try {
            boolean exists = false;
            final List<Mbean> mbeans = ServerBeansFactory.getReferencedMBeans(acc, server);
            for (Mbean m : mbeans) {
                final String onsFromConfig = m.getObjectName();
                final ObjectName onFromConfig = new ObjectName(onsFromConfig);
                if (onFromConfig.equals(on)) {
                    exists = true;
                    break;
                }
            }
            return ( exists ) ;
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    
protected java.util.MapputNameIfAbsent(java.util.Map m)

        final Map<String, String> nm    = new HashMap<String, String>(m);
        final String c                  = nm.get(CustomMBeanConstants.IMPL_CLASS_NAME_KEY); // must not be null
        assert (c != null);
        if (!nm.containsKey(CustomMBeanConstants.NAME_KEY))
            nm.put(CustomMBeanConstants.NAME_KEY, c);
        return ( nm );
    
private voidremoveMBeanDefinitionAndReferenceFromConfigTree(java.lang.String server, java.lang.String ref)

        try {
            ServerBeansFactory.removeMbeanReference(acc, ref, server);
            ServerBeansFactory.removeMbeanDefinition(acc, ref);
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    
protected javax.management.ObjectNameselectObjectName(java.util.Map mm, java.util.Map attributes)

        final ObjectName onPreReg   = ObjectNameSelectionAlgorithm.select(mm);
        //by the time the algorithm is accessed, if the map contains object-name it is valid
        final MBeanValidator mv     = new MBeanValidator();
        final ObjectName onPostReg  = mv.registerTestMBean(createTestMap(Collections.unmodifiableMap(mm), onPreReg), attributes);
        final String className = mm.get(CustomMBeanConstants.IMPL_CLASS_NAME_KEY);
        final boolean selfReg = ObjectNameSelectionAlgorithm.implementsMBeanRegistrationInterface(className);
        if (onPostReg != null) { // todo -- should throw an exception if it is null!!
            // note that onPostReg is *always* going to contain the "server" property, so we must account for that
            final ObjectName cascadedON = CustomMBeanRegistrationImpl.getCascadingAwareObjectName(onPreReg);

            // It may be setting its own name if it implements MBeanRegistration...
            if (!onPostReg.equals(cascadedON) && !selfReg) {
                throw new CustomMBeanException(CMBStrings.get("ObjectNameMismatch", onPreReg, CustomMBeanRegistrationImpl.getCascadingUnawareObjectName(onPostReg)));
            }
        }
        try {
            mv.unregisterTestMBean(onPostReg); //cleanup, if fails, could be ignored, as a new MBS is employed every time
        } catch (final Exception e) {
            e.printStackTrace();
        }
        //Note that we should always return the object-name without "server" property
        final ObjectName onInConfig = CustomMBeanRegistrationImpl.getCascadingUnawareObjectName(onPostReg);
        return ( onInConfig );