MbeansSourcepublic class MbeansSource extends ModelerSource implements MbeansSourceMBeanThis will create mbeans based on a config file.
The format is an extended version of MLET.
Classloading. We don't support any explicit classloader tag.
A ClassLoader is just an mbean ( it can be the standard MLetMBean or
a custom one ).
XXX add a special attribute to reference the loader mbean,
XXX figure out how to deal with private loaders |
Fields Summary |
---|
private static org.apache.juli.logging.Log | log | org.apache.tomcat.util.modeler.Registry | registry | String | type | boolean | loading | List | mbeans | static boolean | loaderLoaded | private Document | document | private HashMap | object2Node | long | lastUpdate | long | updateInterval |
Methods Summary |
---|
public void | destroy()
registry.invoke(mbeans, "destroy", false);
| public void | execute()
if( registry==null ) registry=Registry.getRegistry();
try {
InputStream stream=getInputStream();
long t1=System.currentTimeMillis();
document = DomUtil.readXml(stream);
// We don't care what the root node is.
Node descriptorsN=document.getDocumentElement();
if( descriptorsN == null ) {
log.error("No descriptors found");
return;
}
Node firstMbeanN=DomUtil.getChild(descriptorsN, null);
if( firstMbeanN==null ) {
// maybe we have a single mlet
if( log.isDebugEnabled() )
log.debug("No child " + descriptorsN);
firstMbeanN=descriptorsN;
}
MBeanServer server=(MBeanServer)Registry.getServer();
// XXX Not very clean... Just a workaround
if( ! loaderLoaded ) {
// Register a loader that will be find ant classes.
ObjectName defaultLoader= new ObjectName("modeler",
"loader", "modeler");
MLet mlet=new MLet( new URL[0], this.getClass().getClassLoader());
server.registerMBean(mlet, defaultLoader);
loaderLoaded=true;
}
// Process nodes
for (Node mbeanN = firstMbeanN; mbeanN != null;
mbeanN= DomUtil.getNext(mbeanN, null, Node.ELEMENT_NODE))
{
String nodeName=mbeanN.getNodeName();
// mbean is the "official" name
if( "mbean".equals(nodeName) || "MLET".equals(nodeName) )
{
String code=DomUtil.getAttribute( mbeanN, "code" );
String objectName=DomUtil.getAttribute( mbeanN, "objectName" );
if( objectName==null ) {
objectName=DomUtil.getAttribute( mbeanN, "name" );
}
if( log.isDebugEnabled())
log.debug( "Processing mbean objectName=" + objectName +
" code=" + code);
// args can be grouped in constructor or direct childs
Node constructorN=DomUtil.getChild(mbeanN, "constructor");
if( constructorN == null ) constructorN=mbeanN;
processArg(constructorN);
try {
ObjectName oname=new ObjectName(objectName);
if( ! server.isRegistered( oname )) {
// We wrap everything in a model mbean.
// XXX need to support "StandardMBeanDescriptorsSource"
String modelMBean=BaseModelMBean.class.getName();
server.createMBean(modelMBean, oname,
new Object[] { code, this},
new String[] { String.class.getName(),
ModelerSource.class.getName() }
);
mbeans.add(oname);
}
object2Node.put( oname, mbeanN );
// XXX Arguments, loader !!!
} catch( Exception ex ) {
log.error( "Error creating mbean " + objectName, ex);
}
Node firstAttN=DomUtil.getChild(mbeanN, "attribute");
for (Node descN = firstAttN; descN != null;
descN = DomUtil.getNext( descN ))
{
processAttribute(server, descN, objectName);
}
} else if("jmx-operation".equals(nodeName) ) {
String name=DomUtil.getAttribute(mbeanN, "objectName");
if( name==null )
name=DomUtil.getAttribute(mbeanN, "name");
String operation=DomUtil.getAttribute(mbeanN, "operation");
if( log.isDebugEnabled())
log.debug( "Processing invoke objectName=" + name +
" code=" + operation);
try {
ObjectName oname=new ObjectName(name);
processArg( mbeanN );
server.invoke( oname, operation, null, null);
} catch (Exception e) {
log.error( "Error in invoke " + name + " " + operation);
}
}
ManagedBean managed=new ManagedBean();
DomUtil.setAttributes(managed, mbeanN);
Node firstN;
// process attribute info
firstN=DomUtil.getChild( mbeanN, "attribute");
for (Node descN = firstN; descN != null;
descN = DomUtil.getNext( descN ))
{
AttributeInfo ci=new AttributeInfo();
DomUtil.setAttributes(ci, descN);
managed.addAttribute( ci );
}
}
long t2=System.currentTimeMillis();
log.info( "Reading mbeans " + (t2-t1));
loading=false;
} catch( Exception ex ) {
log.error( "Error reading mbeans ", ex);
}
| public java.lang.String | getLocation()
return location;
| public java.util.List | getMBeans()Return the list of mbeans created by this source.
It can be used to implement runtime services.
return mbeans;
| public java.lang.Object | getSource()
return source;
| public void | init()
if( mbeans==null) execute();
if( registry==null ) registry=Registry.getRegistry();
registry.invoke(mbeans, "init", false);
| public void | load()
execute(); // backward compat
| public java.util.List | loadDescriptors(org.apache.tomcat.util.modeler.Registry registry, java.lang.String location, java.lang.String type, java.lang.Object source)
setRegistry(registry);
setLocation(location);
setType(type);
setSource(source);
execute();
return mbeans;
| private void | processArg(org.w3c.dom.Node mbeanN)
Node firstArgN=DomUtil.getChild(mbeanN, "arg" );
// process all args
for (Node argN = firstArgN; argN != null;
argN = DomUtil.getNext( argN ))
{
String type=DomUtil.getAttribute(argN, "type");
String value=DomUtil.getAttribute(argN, "value");
if( value==null ) {
// The value may be specified as CDATA
value=DomUtil.getContent(argN);
}
}
| private void | processAttribute(javax.management.MBeanServer server, org.w3c.dom.Node descN, java.lang.String objectName)
String attName=DomUtil.getAttribute(descN, "name");
String value=DomUtil.getAttribute(descN, "value");
String type=null; // DomUtil.getAttribute(descN, "type");
if( value==null ) {
// The value may be specified as CDATA
value=DomUtil.getContent(descN);
}
try {
if( log.isDebugEnabled())
log.debug("Set attribute " + objectName + " " + attName +
" " + value);
ObjectName oname=new ObjectName(objectName);
// find the type
if( type==null )
type=registry.getType( oname, attName );
if( type==null ) {
log.info("Can't find attribute " + objectName + " " + attName );
} else {
Object valueO=registry.convertValue( type, value);
server.setAttribute(oname, new Attribute(attName, valueO));
}
} catch( Exception ex) {
log.error("Error processing attribute " + objectName + " " +
attName + " " + value, ex);
}
| public void | save()Store the mbeans.
XXX add a background thread to store it periodically
// XXX customize no often than ( based on standard descriptor ), etc.
// It doesn't work very well if we call this on each set att -
// the triger will work for the first att, but all others will be delayed
long time=System.currentTimeMillis();
if( location!=null &&
time - lastUpdate > updateInterval ) {
lastUpdate=time;
try {
FileOutputStream fos=new FileOutputStream(location);
DomUtil.writeXml(document, fos);
} catch (TransformerException e) {
log.error( "Error writing");
} catch (FileNotFoundException e) {
log.error( "Error writing" ,e );
}
}
| public void | setLocation(java.lang.String loc)
this.location=loc;
| public void | setRegistry(org.apache.tomcat.util.modeler.Registry reg) // 10s
this.registry=reg;
| public void | setSource(java.lang.Object source)
this.source=source;
| public void | setType(java.lang.String type)Used if a single component is loaded
this.type=type;
| public void | start()
registry.invoke(mbeans, "start", false);
| public void | stop()
registry.invoke(mbeans, "stop", false);
| public void | updateField(javax.management.ObjectName oname, java.lang.String name, java.lang.Object value)
if( loading ) return;
// nothing by default
//log.info( "XXX UpdateField " + oname + " " + name + " " + value);
Node n=(Node)object2Node.get( oname );
if( n == null ) {
log.info( "Node not found " + oname );
return;
}
Node attNode=DomUtil.findChildWithAtt(n, "attribute", "name", name);
if( attNode == null ) {
// found no existing attribute with this name
attNode=n.getOwnerDocument().createElement("attribute");
DomUtil.setAttribute(attNode, "name", name);
n.appendChild(attNode);
}
String oldValue=DomUtil.getAttribute(attNode, "value");
if( oldValue != null ) {
// we'll convert all values to text content
DomUtil.removeAttribute( attNode, "value");
}
DomUtil.setText(attNode, value.toString());
//store();
|
|