updates to managed attribute, tests, objectmbean impl and a note to improve id as viewed in jconsole
This commit is contained in:
parent
95b70cac81
commit
f92ebea9f0
|
@ -228,6 +228,8 @@ public class MBeanContainer extends AbstractLifeCycle implements Container.Liste
|
|||
* Implementation of Container.Listener interface
|
||||
*
|
||||
* @see org.eclipse.jetty.util.component.Container.Listener#addBean(java.lang.Object)
|
||||
*
|
||||
* TODO improve the id property to include better information
|
||||
*/
|
||||
public synchronized void addBean(Object obj)
|
||||
{
|
||||
|
|
|
@ -75,10 +75,10 @@ public class ObjectMBean implements DynamicMBean
|
|||
|
||||
protected Object _managed;
|
||||
private MBeanInfo _info;
|
||||
private Map _getters=new HashMap();
|
||||
private Map _setters=new HashMap();
|
||||
private Map _methods=new HashMap();
|
||||
private Set _convert=new HashSet();
|
||||
private Map<String, Method> _getters=new HashMap<String, Method>();
|
||||
private Map<String, Method> _setters=new HashMap<String, Method>();
|
||||
private Map<String, Method> _methods=new HashMap<String, Method>();
|
||||
private Set<String> _convert=new HashSet<String>();
|
||||
private ClassLoader _loader;
|
||||
private MBeanContainer _mbeanContainer;
|
||||
|
||||
|
@ -261,19 +261,6 @@ public class ObjectMBean implements DynamicMBean
|
|||
continue;
|
||||
}
|
||||
|
||||
// Process Field Annotations
|
||||
for (Field field : oClass.getDeclaredFields())
|
||||
{
|
||||
LOG.debug("Checking: " + field.getName());
|
||||
ManagedAttribute fieldAnnotation = field.getAnnotation(ManagedAttribute.class);
|
||||
|
||||
if (fieldAnnotation != null)
|
||||
{
|
||||
LOG.debug("Field Annotation found for: " + field.getName());
|
||||
attributes.add(defineAttribute(field.getName(),fieldAnnotation));
|
||||
}
|
||||
}
|
||||
|
||||
// Process Method Annotations
|
||||
|
||||
for (Method method : oClass.getDeclaredMethods())
|
||||
|
@ -284,7 +271,7 @@ public class ObjectMBean implements DynamicMBean
|
|||
{
|
||||
// TODO sort out how a proper name could get here, its a method name as an attribute at this point.
|
||||
LOG.debug("Attribute Annotation found for: " + method.getName());
|
||||
attributes.add(defineAttribute(method.getName(),methodAttributeAnnotation));
|
||||
attributes.add(defineAttribute(method,methodAttributeAnnotation));
|
||||
}
|
||||
|
||||
ManagedOperation methodOperationAnnotation = method.getAnnotation(ManagedOperation.class);
|
||||
|
@ -572,119 +559,80 @@ public class ObjectMBean implements DynamicMBean
|
|||
* </ul>
|
||||
* the access is either "RW" or "RO".
|
||||
*/
|
||||
public MBeanAttributeInfo defineAttribute(String name, ManagedAttribute attributeAnnotation)
|
||||
public MBeanAttributeInfo defineAttribute(Method method, ManagedAttribute attributeAnnotation)
|
||||
{
|
||||
//String name = field.getName();
|
||||
// determine the name of the managed attribute
|
||||
String name = attributeAnnotation.name();
|
||||
|
||||
if ("".equals(name))
|
||||
{
|
||||
name = toVariableName(method.getName());
|
||||
}
|
||||
|
||||
String description = attributeAnnotation.value();
|
||||
boolean writable = !attributeAnnotation.readonly();
|
||||
boolean readonly = attributeAnnotation.readonly();
|
||||
boolean onMBean = attributeAnnotation.proxied();
|
||||
boolean convert = attributeAnnotation.managed();
|
||||
|
||||
String uName = name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||
Class oClass = onMBean ? this.getClass() : _managed.getClass();
|
||||
Class<?> oClass = onMBean ? this.getClass() : _managed.getClass();
|
||||
|
||||
LOG.debug("defineAttribute {} {}:{}:{}:{}",name,onMBean,writable,oClass,description);
|
||||
LOG.debug("defineAttribute {} {}:{}:{}:{}",name,onMBean,readonly,oClass,description);
|
||||
|
||||
Class type = null;
|
||||
Method getter = null;
|
||||
Class<?> type = null;
|
||||
Method setter = null;
|
||||
|
||||
type = method.getReturnType();
|
||||
|
||||
String declaredGetter = attributeAnnotation.getter();
|
||||
String declaredSetter = attributeAnnotation.setter();
|
||||
|
||||
|
||||
Method[] methods = oClass.getMethods();
|
||||
for (int m = 0; m < methods.length; m++)
|
||||
|
||||
// dig out a setter if one exists
|
||||
if (!readonly)
|
||||
{
|
||||
if ((methods[m].getModifiers() & Modifier.PUBLIC) == 0)
|
||||
continue;
|
||||
String declaredSetter = attributeAnnotation.setter();
|
||||
|
||||
// Check if it is a declared getter
|
||||
if (methods[m].getName().equals(declaredGetter) && methods[m].getParameterTypes().length == 0)
|
||||
LOG.debug("DeclaredSetter:" + declaredSetter);
|
||||
Method[] methods = oClass.getMethods();
|
||||
for (int m = 0; m < methods.length; m++)
|
||||
{
|
||||
if (getter != null)
|
||||
{
|
||||
LOG.warn("Multiple mbean getters for attr " + name+ " in "+oClass);
|
||||
if ((methods[m].getModifiers() & Modifier.PUBLIC) == 0)
|
||||
continue;
|
||||
}
|
||||
getter = methods[m];
|
||||
if (type != null && !type.equals(methods[m].getReturnType()))
|
||||
|
||||
if (!"".equals(declaredSetter))
|
||||
{
|
||||
LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
|
||||
continue;
|
||||
|
||||
// look for a declared setter
|
||||
if (methods[m].getName().equals(declaredSetter) && methods[m].getParameterTypes().length == 1)
|
||||
{
|
||||
if (setter != null)
|
||||
{
|
||||
LOG.warn("Multiple setters for mbean attr " + name + " in " + oClass);
|
||||
continue;
|
||||
}
|
||||
setter = methods[m];
|
||||
if ( !type.equals(methods[m].getParameterTypes()[0]))
|
||||
{
|
||||
LOG.warn("Type conflict for mbean attr " + name + " in " + oClass);
|
||||
continue;
|
||||
}
|
||||
LOG.debug("Declared Setter: " + declaredSetter);
|
||||
}
|
||||
}
|
||||
type = methods[m].getReturnType();
|
||||
|
||||
LOG.debug("Declared Getter: " + declaredGetter);
|
||||
}
|
||||
|
||||
// Look for a getter
|
||||
if (methods[m].getName().equals("get" + uName) && methods[m].getParameterTypes().length == 0)
|
||||
{
|
||||
if (getter != null)
|
||||
// look for a setter
|
||||
if ( methods[m].getName().equals("set" + uName) && methods[m].getParameterTypes().length == 1)
|
||||
{
|
||||
LOG.warn("Multiple mbean getters for attr " + name+ " in "+oClass);
|
||||
continue;
|
||||
}
|
||||
getter = methods[m];
|
||||
if (type != null && !type.equals(methods[m].getReturnType()))
|
||||
{
|
||||
LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
|
||||
continue;
|
||||
}
|
||||
type = methods[m].getReturnType();
|
||||
}
|
||||
|
||||
// Look for an is getter
|
||||
if (methods[m].getName().equals("is" + uName) && methods[m].getParameterTypes().length == 0)
|
||||
{
|
||||
if (getter != null)
|
||||
{
|
||||
LOG.warn("Multiple mbean getters for attr " + name+ " in "+oClass);
|
||||
continue;
|
||||
}
|
||||
getter = methods[m];
|
||||
if (type != null && !type.equals(methods[m].getReturnType()))
|
||||
{
|
||||
LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
|
||||
continue;
|
||||
}
|
||||
type = methods[m].getReturnType();
|
||||
}
|
||||
|
||||
// look for a declared setter
|
||||
if (writable && methods[m].getName().equals(declaredSetter) && methods[m].getParameterTypes().length == 1)
|
||||
{
|
||||
if (setter != null)
|
||||
{
|
||||
LOG.warn("Multiple setters for mbean attr " + name+ " in "+oClass);
|
||||
continue;
|
||||
}
|
||||
setter = methods[m];
|
||||
if (type != null && !type.equals(methods[m].getParameterTypes()[0]))
|
||||
{
|
||||
LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
|
||||
continue;
|
||||
}
|
||||
LOG.debug("Declared Setter: " + declaredSetter);
|
||||
type = methods[m].getParameterTypes()[0];
|
||||
}
|
||||
|
||||
// look for a setter
|
||||
if (writable && methods[m].getName().equals("set" + uName) && methods[m].getParameterTypes().length == 1)
|
||||
{
|
||||
if (setter != null)
|
||||
{
|
||||
LOG.warn("Multiple setters for mbean attr " + name+ " in "+oClass);
|
||||
continue;
|
||||
if (setter != null)
|
||||
{
|
||||
LOG.warn("Multiple setters for mbean attr " + name + " in " + oClass);
|
||||
continue;
|
||||
}
|
||||
setter = methods[m];
|
||||
if ( !type.equals(methods[m].getParameterTypes()[0]))
|
||||
{
|
||||
LOG.warn("Type conflict for mbean attr " + name + " in " + oClass);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
setter = methods[m];
|
||||
if (type != null && !type.equals(methods[m].getParameterTypes()[0]))
|
||||
{
|
||||
LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
|
||||
continue;
|
||||
}
|
||||
type = methods[m].getParameterTypes()[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -704,16 +652,10 @@ public class ObjectMBean implements DynamicMBean
|
|||
LOG.debug("passed convert checks {} for type {}", name, type);
|
||||
}
|
||||
|
||||
if (getter == null && setter == null)
|
||||
{
|
||||
LOG.warn("No mbean getter or setters found for {} in {}", name, oClass);
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Remember the methods
|
||||
_getters.put(name, getter);
|
||||
_getters.put(name, method);
|
||||
_setters.put(name, setter);
|
||||
|
||||
MBeanAttributeInfo info=null;
|
||||
|
@ -723,16 +665,16 @@ public class ObjectMBean implements DynamicMBean
|
|||
|
||||
if (type.isArray())
|
||||
{
|
||||
info= new MBeanAttributeInfo(name,OBJECT_NAME_ARRAY_CLASS,description,getter!=null,setter!=null,getter!=null&&getter.getName().startsWith("is"));
|
||||
info= new MBeanAttributeInfo(name,OBJECT_NAME_ARRAY_CLASS,description,true,setter!=null,method.getName().startsWith("is"));
|
||||
}
|
||||
else
|
||||
{
|
||||
info= new MBeanAttributeInfo(name,OBJECT_NAME_CLASS,description,getter!=null,setter!=null,getter!=null&&getter.getName().startsWith("is"));
|
||||
info= new MBeanAttributeInfo(name,OBJECT_NAME_CLASS,description,true,setter!=null,method.getName().startsWith("is"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info= new MBeanAttributeInfo(name,description,getter,setter);
|
||||
info= new MBeanAttributeInfo(name,description,method,setter);
|
||||
}
|
||||
|
||||
return info;
|
||||
|
@ -834,5 +776,25 @@ public class ObjectMBean implements DynamicMBean
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected String toVariableName( String methodName )
|
||||
{
|
||||
String variableName = methodName;
|
||||
|
||||
if ( methodName.startsWith("get") || methodName.startsWith("set") )
|
||||
{
|
||||
variableName = variableName.substring(3);
|
||||
}
|
||||
else if ( methodName.startsWith("is") )
|
||||
{
|
||||
variableName = variableName.substring(2);
|
||||
}
|
||||
|
||||
variableName = variableName.substring(0,1).toLowerCase() + variableName.substring(1);
|
||||
|
||||
return variableName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -17,11 +17,16 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.jmx.ObjectMBean;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.annotation.ManagedOperation;
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*/
|
||||
@ManagedObject("Jetty Logging")
|
||||
public class LogMBean extends ObjectMBean
|
||||
{
|
||||
|
||||
|
@ -30,18 +35,21 @@ public class LogMBean extends ObjectMBean
|
|||
super(managedObject);
|
||||
}
|
||||
|
||||
@ManagedAttribute(value="list of instantiated loggers")
|
||||
public List<String> getLoggers()
|
||||
{
|
||||
List<String> keySet = new ArrayList<String>(Log.getLoggers().keySet());
|
||||
return keySet;
|
||||
}
|
||||
|
||||
public boolean isDebugEnabled(String logger)
|
||||
@ManagedOperation(value="true if debug enabled for the given logger")
|
||||
public boolean isDebugEnabled(@Name("logger") String logger)
|
||||
{
|
||||
return Log.getLogger(logger).isDebugEnabled();
|
||||
}
|
||||
|
||||
public void setDebugEnabled(String logger, Boolean enabled)
|
||||
|
||||
@ManagedOperation(value="Set debug enabled for given logger")
|
||||
public void setDebugEnabled(@Name("logger")String logger, @Name("enabled") Boolean enabled)
|
||||
{
|
||||
Log.getLogger(logger).setDebugEnabled(enabled);
|
||||
}
|
||||
|
|
|
@ -21,12 +21,11 @@ import org.eclipse.jetty.util.annotation.Name;
|
|||
@ManagedObject(value="Test the mbean stuff", wrapper="com.acme.jmx.DerivedMBean")
|
||||
public class Derived extends Base implements Signature
|
||||
{
|
||||
@ManagedAttribute(value="The full name of something", getter="getFullName", setter="setFullName")
|
||||
String fname="Full Name";
|
||||
|
||||
@ManagedAttribute( value="sample managed object")
|
||||
Managed managedInstance = new Managed();
|
||||
|
||||
@ManagedAttribute(value="The full name of something", name="fname", setter="setFullName")
|
||||
public String getFullName()
|
||||
{
|
||||
return fname;
|
||||
|
@ -54,6 +53,7 @@ public class Derived extends Base implements Signature
|
|||
return "bad";
|
||||
}
|
||||
|
||||
@ManagedAttribute( value="sample managed object")
|
||||
public Managed getManagedInstance()
|
||||
{
|
||||
return managedInstance;
|
||||
|
|
|
@ -6,9 +6,9 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
|
|||
@ManagedObject(value="Managed Object", wrapper="com.acme.jmx.ManagedMBean")
|
||||
public class Managed
|
||||
{
|
||||
@ManagedAttribute("Managed Attribute")
|
||||
String managed = "foo";
|
||||
|
||||
@ManagedAttribute("Managed Attribute")
|
||||
public String getManaged()
|
||||
{
|
||||
return managed;
|
||||
|
@ -19,4 +19,10 @@ public class Managed
|
|||
this.managed = managed;
|
||||
}
|
||||
|
||||
|
||||
public String bad()
|
||||
{
|
||||
return "bad";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
|
|||
import org.eclipse.jetty.util.annotation.ManagedOperation;
|
||||
|
||||
import com.acme.Derived;
|
||||
import com.acme.Managed;
|
||||
|
||||
@ManagedObject("Managed MBean Wrapper")
|
||||
public class ManagedMBean extends ObjectMBean
|
||||
|
@ -18,7 +19,7 @@ public class ManagedMBean extends ObjectMBean
|
|||
@ManagedOperation(value="test of proxy operations", managed=true)
|
||||
public String good()
|
||||
{
|
||||
return "not " + ((Derived)_managed).bad();
|
||||
return "not managed " + ((Managed)_managed).bad();
|
||||
}
|
||||
|
||||
@ManagedAttribute(value="test of proxy attributes", getter="goop", proxied=true)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// ========================================================================
|
||||
// =====7===================================================================
|
||||
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
|
@ -25,7 +25,10 @@ import junit.framework.Assert;
|
|||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -39,15 +42,15 @@ public class ObjectMBeanTest
|
|||
|
||||
private static MBeanContainer container;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception
|
||||
@Before
|
||||
public void beforeClass() throws Exception
|
||||
{
|
||||
container = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
|
||||
container.start();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception
|
||||
@After
|
||||
public void afterClass() throws Exception
|
||||
{
|
||||
container.stop();
|
||||
container = null;
|
||||
|
@ -57,7 +60,7 @@ public class ObjectMBeanTest
|
|||
* this test uses the com.acme.Derived test classes
|
||||
*/
|
||||
@Test
|
||||
public void testMbeanInfo() throws Exception
|
||||
public void testDerivedAttributes() throws Exception
|
||||
{
|
||||
|
||||
Derived derived = new Derived();
|
||||
|
@ -67,8 +70,8 @@ public class ObjectMBeanTest
|
|||
mbean.setMBeanContainer(container);
|
||||
managed.setMBeanContainer(container);
|
||||
|
||||
container.addBean(mbean);
|
||||
container.addBean(managed);
|
||||
container.addBean(derived);
|
||||
container.addBean(derived.getManagedInstance());
|
||||
|
||||
MBeanInfo toss = managed.getMBeanInfo();
|
||||
|
||||
|
@ -79,15 +82,15 @@ public class ObjectMBeanTest
|
|||
Assert.assertEquals("name does not match", "com.acme.Derived", info.getClassName());
|
||||
Assert.assertEquals("description does not match", "Test the mbean stuff", info.getDescription());
|
||||
|
||||
for ( MBeanAttributeInfo i : info.getAttributes())
|
||||
{
|
||||
LOG.debug(i.toString());
|
||||
}
|
||||
//for ( MBeanAttributeInfo i : info.getAttributes())
|
||||
//{
|
||||
// LOG.debug(i.toString());
|
||||
//}
|
||||
|
||||
/*
|
||||
* 6 attributes from lifecycle and 2 from Derived and 1 from MBean
|
||||
* 1 attribute from lifecycle and 2 from Derived and 1 from MBean
|
||||
*/
|
||||
Assert.assertEquals("attribute count does not match", 9, info.getAttributes().length);
|
||||
Assert.assertEquals("attribute count does not match", 4, info.getAttributes().length);
|
||||
|
||||
Assert.assertEquals("attribute values does not match", "Full Name", mbean.getAttribute("fname") );
|
||||
|
||||
|
@ -95,10 +98,25 @@ public class ObjectMBeanTest
|
|||
|
||||
Assert.assertEquals("set attribute value does not match", "Fuller Name", mbean.getAttribute("fname") );
|
||||
|
||||
Assert.assertEquals("proxy attribute values do not match", "goop", mbean.getAttribute("goop") );
|
||||
Assert.assertEquals("proxy attribute values do not match", "goop", mbean.getAttribute("goop") );
|
||||
|
||||
//Thread.sleep(100000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDerivedOperations() throws Exception
|
||||
{
|
||||
Derived derived = new Derived();
|
||||
ObjectMBean mbean = (ObjectMBean)ObjectMBean.mbeanFor(derived);
|
||||
|
||||
mbean.setMBeanContainer(container);
|
||||
|
||||
container.addBean(derived);
|
||||
|
||||
MBeanInfo info = mbean.getMBeanInfo();
|
||||
|
||||
Assert.assertEquals("operation count does not match", 5, info.getOperations().length);
|
||||
|
||||
|
||||
MBeanOperationInfo[] opinfos = info.getOperations();
|
||||
boolean publish = false;
|
||||
boolean doodle = false;
|
||||
|
@ -106,9 +124,7 @@ public class ObjectMBeanTest
|
|||
for ( int i = 0 ; i < opinfos.length; ++i )
|
||||
{
|
||||
MBeanOperationInfo opinfo = opinfos[i];
|
||||
|
||||
LOG.debug(opinfo.getName());
|
||||
|
||||
|
||||
if ("publish".equals(opinfo.getName()))
|
||||
{
|
||||
publish = true;
|
||||
|
@ -126,6 +142,7 @@ public class ObjectMBeanTest
|
|||
Assert.assertEquals("parameter name doesn't match", "doodle", pinfos[0].getName());
|
||||
}
|
||||
|
||||
// This is a proxied operation on the JMX wrapper
|
||||
if ("good".equals(opinfo.getName()))
|
||||
{
|
||||
good = true;
|
||||
|
@ -138,11 +155,63 @@ public class ObjectMBeanTest
|
|||
Assert.assertTrue("publish operation was not not found", publish);
|
||||
Assert.assertTrue("doodle operation was not not found", doodle);
|
||||
Assert.assertTrue("good operation was not not found", good);
|
||||
|
||||
// TODO sort out why this is not working...something off in Bean vs MBean ism's
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDerivedObjectAttributes() throws Exception
|
||||
{
|
||||
Derived derived = new Derived();
|
||||
ObjectMBean mbean = (ObjectMBean)ObjectMBean.mbeanFor(derived);
|
||||
|
||||
ObjectMBean managed = (ObjectMBean)ObjectMBean.mbeanFor(derived.getManagedInstance());
|
||||
mbean.setMBeanContainer(container);
|
||||
managed.setMBeanContainer(container);
|
||||
|
||||
Assert.assertNotNull(mbean.getMBeanInfo());
|
||||
|
||||
container.addBean(derived);
|
||||
container.addBean(derived.getManagedInstance());
|
||||
|
||||
Managed managedInstance = (Managed)mbean.getAttribute("managedInstance");
|
||||
Assert.assertNotNull(managedInstance);
|
||||
Assert.assertEquals("managed instance returning nonsense", "foo", managedInstance.getManaged());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThreadPool() throws Exception
|
||||
{
|
||||
QueuedThreadPool qtp = new QueuedThreadPool();
|
||||
|
||||
ObjectMBean bqtp = (ObjectMBean)ObjectMBean.mbeanFor(qtp);
|
||||
|
||||
bqtp.getMBeanInfo();
|
||||
|
||||
|
||||
|
||||
container.addBean(qtp);
|
||||
|
||||
|
||||
Thread.sleep(10000000);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodNameMining() throws Exception
|
||||
{
|
||||
ObjectMBean mbean = new ObjectMBean(new Derived());
|
||||
|
||||
Assert.assertEquals("fullName",mbean.toVariableName("getFullName"));
|
||||
Assert.assertEquals("fullName",mbean.toVariableName("getfullName"));
|
||||
Assert.assertEquals("fullName",mbean.toVariableName("isFullName"));
|
||||
Assert.assertEquals("fullName",mbean.toVariableName("isfullName"));
|
||||
Assert.assertEquals("fullName",mbean.toVariableName("setFullName"));
|
||||
Assert.assertEquals("fullName",mbean.toVariableName("setfullName"));
|
||||
Assert.assertEquals("fullName",mbean.toVariableName("FullName"));
|
||||
Assert.assertEquals("fullName",mbean.toVariableName("fullName"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -20,16 +20,23 @@ import java.lang.annotation.Target;
|
|||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Target( { ElementType.METHOD, ElementType.FIELD } )
|
||||
@Target( { ElementType.METHOD } )
|
||||
public @interface ManagedAttribute
|
||||
{
|
||||
/**
|
||||
* Description of the Managed Object
|
||||
* Description of the Managed Attribute
|
||||
*
|
||||
* @return
|
||||
* @returngit checkout
|
||||
*/
|
||||
String value() default "Not Specified";
|
||||
|
||||
/**
|
||||
* name to use for the attribute
|
||||
*
|
||||
* @return the name of the attribute
|
||||
*/
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* Is the managed field read-only?
|
||||
*
|
||||
|
|
|
@ -30,17 +30,11 @@ public abstract class AbstractLifeCycle implements LifeCycle
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(AbstractLifeCycle.class);
|
||||
|
||||
@ManagedAttribute(value="instance is stopped", readonly=true, getter="isStopped")
|
||||
public static final String STOPPED="STOPPED";
|
||||
@ManagedAttribute(value="instance is failed", readonly=true, getter="isFailed")
|
||||
public static final String FAILED="FAILED";
|
||||
@ManagedAttribute(value="instance is starting", readonly=true, getter="isStarting")
|
||||
public static final String STARTING="STARTING";
|
||||
@ManagedAttribute(value="instance is started", readonly=true, getter="isStarted")
|
||||
public static final String STARTED="STARTED";
|
||||
@ManagedAttribute(value="instance is stopping", readonly=true, getter="isStopping")
|
||||
public static final String STOPPING="STOPPING";
|
||||
@ManagedAttribute(value="instance is running", readonly=true, getter="isRunning")
|
||||
public static final String RUNNING="RUNNING";
|
||||
|
||||
private final CopyOnWriteArrayList<LifeCycle.Listener> _listeners=new CopyOnWriteArrayList<LifeCycle.Listener>();
|
||||
|
@ -139,6 +133,7 @@ public abstract class AbstractLifeCycle implements LifeCycle
|
|||
_listeners.remove(listener);
|
||||
}
|
||||
|
||||
@ManagedAttribute(value="Lifecycle State for this instance", readonly=true)
|
||||
public String getState()
|
||||
{
|
||||
switch(_state)
|
||||
|
|
|
@ -28,6 +28,10 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||
|
||||
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.annotation.ManagedOperation;
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.AggregateLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
|
@ -36,6 +40,7 @@ import org.eclipse.jetty.util.log.Log;
|
|||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.ThreadPool.SizedThreadPool;
|
||||
|
||||
@ManagedObject("A thread pool with no max bound by default")
|
||||
public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPool, Dumpable
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(QueuedThreadPool.class);
|
||||
|
@ -46,14 +51,20 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
|
|||
private final ConcurrentLinkedQueue<Thread> _threads=new ConcurrentLinkedQueue<Thread>();
|
||||
private final Object _joinLock = new Object();
|
||||
private BlockingQueue<Runnable> _jobs;
|
||||
|
||||
private String _name;
|
||||
private int _maxIdleTimeMs=60000;
|
||||
|
||||
private int _maxThreads;
|
||||
|
||||
private int _minThreads;
|
||||
private int _maxQueued=-1;
|
||||
|
||||
private int _priority=Thread.NORM_PRIORITY;
|
||||
|
||||
private boolean _daemon=false;
|
||||
private int _maxStopTime=100;
|
||||
|
||||
private boolean _detailedDump=false;
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
@ -312,6 +323,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
|
|||
* @return minimum number of threads.
|
||||
*/
|
||||
@Override
|
||||
@ManagedAttribute("minimum number of threads in the pool")
|
||||
public int getMinThreads()
|
||||
{
|
||||
return _minThreads;
|
||||
|
@ -321,6 +333,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
|
|||
/**
|
||||
* @return The name of the BoundedThreadPool.
|
||||
*/
|
||||
@ManagedAttribute("name of the thread pool")
|
||||
public String getName()
|
||||
{
|
||||
return _name;
|
||||
|
@ -330,6 +343,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
|
|||
/** Get the priority of the pool threads.
|
||||
* @return the priority of the pool threads.
|
||||
*/
|
||||
@ManagedAttribute("priority of threads in the pool")
|
||||
public int getThreadsPriority()
|
||||
{
|
||||
return _priority;
|
||||
|
@ -339,12 +353,14 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
|
|||
/**
|
||||
* Delegated to the named or anonymous Pool.
|
||||
*/
|
||||
@ManagedAttribute("thead pool using a daemon thread")
|
||||
public boolean isDaemon()
|
||||
{
|
||||
return _daemon;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@ManagedAttribute("full stack detail on dump output")
|
||||
public boolean isDetailedDump()
|
||||
{
|
||||
return _detailedDump;
|
||||
|
@ -471,6 +487,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
@ManagedOperation("dump thread state")
|
||||
public String dump()
|
||||
{
|
||||
return AggregateLifeCycle.dump(this);
|
||||
|
@ -658,7 +675,8 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
|
|||
* @param id The thread ID to interrupt.
|
||||
* @return true if the thread was found and interrupted.
|
||||
*/
|
||||
public boolean interruptThread(long id)
|
||||
@ManagedOperation("interrupt a pool thread")
|
||||
public boolean interruptThread(@Name("id") long id)
|
||||
{
|
||||
for (Thread thread: _threads)
|
||||
{
|
||||
|
@ -676,7 +694,8 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
|
|||
* @param id The thread ID to interrupt.
|
||||
* @return true if the thread was found and interrupted.
|
||||
*/
|
||||
public String dumpThread(long id)
|
||||
@ManagedOperation("dump a pool thread stack")
|
||||
public String dumpThread(@Name("id") long id)
|
||||
{
|
||||
for (Thread thread: _threads)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,8 @@ package org.eclipse.jetty.util.thread;
|
|||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -22,6 +24,7 @@ import org.eclipse.jetty.util.component.LifeCycle;
|
|||
*
|
||||
*
|
||||
*/
|
||||
@ManagedObject("Pool of Threads")
|
||||
public interface ThreadPool extends Executor
|
||||
{
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -41,18 +44,21 @@ public interface ThreadPool extends Executor
|
|||
/**
|
||||
* @return The total number of threads currently in the pool
|
||||
*/
|
||||
@ManagedAttribute("number of threads in pool")
|
||||
public int getThreads();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The number of idle threads in the pool
|
||||
*/
|
||||
@ManagedAttribute("number of idle threads in pool")
|
||||
public int getIdleThreads();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return True if the pool is low on threads
|
||||
*/
|
||||
@ManagedAttribute("indicates the pool is low on available threads")
|
||||
public boolean isLowOnThreads();
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue