Skip to content

Commit

Permalink
- ResourceDMBean now accepts filters (JGRP-2796)
Browse files Browse the repository at this point in the history
  • Loading branch information
belaban committed Apr 27, 2024
1 parent e51b65c commit 2ad1563
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 16 deletions.
28 changes: 21 additions & 7 deletions src/org/jgroups/jmx/ResourceDMBean.java
Expand Up @@ -7,6 +7,7 @@
import org.jgroups.conf.AttributeType;
import org.jgroups.logging.Log;
import org.jgroups.logging.LogFactory;
import org.jgroups.util.Average;
import org.jgroups.util.Util;

import javax.management.*;
Expand Down Expand Up @@ -54,16 +55,19 @@ public class ResourceDMBean implements DynamicMBean {
protected static final Predicate<AccessibleObject> FILTER=obj -> obj.isAnnotationPresent(ManagedAttribute.class) ||
(obj.isAnnotationPresent(Property.class) && obj.getAnnotation(Property.class).exposeAsManagedAttribute());


public ResourceDMBean(Object instance) {
this(instance, null);
}

public ResourceDMBean(Object instance, Predicate<AccessibleObject> filter) {
if(instance == null)
throw new NullPointerException("Cannot make an MBean wrapper for null instance");
this.obj=instance;
Class<? extends Object> c=obj.getClass();
expose_all=c.isAnnotationPresent(MBean.class) && c.getAnnotation(MBean.class).exposeAll();

findFields(instance);
findMethods(instance);
findFields(instance, filter);
findMethods(instance, filter);
fixFields(instance);

List<Object> objects=Util.getComponents(instance);
Expand All @@ -73,8 +77,8 @@ public ResourceDMBean(Object instance) {
if(objs == null)
objs=new ArrayList<>();
objs.add(inst);
findFields(inst);
findMethods(inst);
findFields(inst, filter);
findMethods(inst, filter);
fixFields(inst);
}
}
Expand Down Expand Up @@ -273,6 +277,10 @@ public static boolean isFractional(Class<?> cl) {
return cl.equals(float.class) || cl.equals(Float.class) || cl.equals(double.class) || cl.equals(Double.class);
}

public static boolean isNumber(Class<?> cl) {
return isNumeric(cl) || isFractional(cl) || Number.class.isAssignableFrom(cl) || Average.class.isAssignableFrom(cl);
}


protected static AttributeType getType(AccessibleObject ao) {
Property prop=ao.getAnnotation(Property.class);
Expand Down Expand Up @@ -306,14 +314,17 @@ protected static Class<?> getClassForName(String name) throws ClassNotFoundExcep
throw new ClassNotFoundException("Class " + name + " cannot be found");
}

protected void findMethods(Object instance) {
protected void findMethods(Object instance, Predicate<AccessibleObject> filter) {
// find all methods but don't include methods from Object class
List<Method> methods = new ArrayList<>(Arrays.asList(instance.getClass().getMethods()));
methods.removeAll(OBJECT_METHODS);

for(Method method: methods) {

// does method have @ManagedAttribute annotation?
if(method.isAnnotationPresent(ManagedAttribute.class) || method.isAnnotationPresent(Property.class)) {
if(filter != null && !filter.test(method))
continue;
exposeManagedAttribute(method, instance);
}
//or @ManagedOperation
Expand Down Expand Up @@ -461,12 +472,15 @@ protected static String toLowerCase(String input) {
}


protected void findFields(Object instance) {
protected void findFields(Object instance, Predicate<AccessibleObject> filter) {
// traverse class hierarchy and find all annotated fields
for(Class<?> clazz=instance.getClass(); clazz != null && clazz != Object.class; clazz=clazz.getSuperclass()) {

Field[] fields=clazz.getDeclaredFields();
for(Field field: fields) {
if(filter != null && !filter.test(field))
continue;

ManagedAttribute attr=field.getAnnotation(ManagedAttribute.class);
Property prop=field.getAnnotation(Property.class);
boolean expose_prop=prop != null && prop.exposeAsManagedAttribute();
Expand Down
42 changes: 33 additions & 9 deletions src/org/jgroups/util/ExtractMetrics.java
Expand Up @@ -5,8 +5,12 @@
import org.jgroups.stack.Protocol;

import javax.management.MBeanAttributeInfo;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
Expand All @@ -18,9 +22,19 @@
*/
public class ExtractMetrics {
protected JChannel ch;
protected static final Predicate<AccessibleObject> IS_NUMBER=obj -> {
if(obj instanceof Field)
return ResourceDMBean.isNumber(((Field)obj).getType());
if(obj instanceof Method) {
Method m=(Method)obj;
return ResourceDMBean.isNumber(m.getReturnType());
}
return false;
};


public static class Entry {
protected final String description;
protected final String description;
protected final Supplier<Object> method;

protected Entry(String description, Supplier<Object> method) {
Expand All @@ -43,18 +57,24 @@ public String toString() {
}

public static Map<String,Map<String,Entry>> extract(JChannel ch) {
return extract(ch, null);
}

public static Map<String,Map<String,Entry>> extract(JChannel ch, Predicate<AccessibleObject> filter) {
Map<String,Map<String,Entry>> map=new HashMap<>();
for(Protocol p: ch.stack().getProtocols()) {
map.put(p.getName(), extract(p));
map.put(p.getName(), extract(p, filter));
}
return map;
}


public static Map<String,Entry> extract(Protocol p) {
Map<String,Entry> map=new HashMap<>();
return extract(p, null);
}

ResourceDMBean dm=new ResourceDMBean(p);
public static Map<String,Entry> extract(Protocol p, Predicate<AccessibleObject> filter) {
Map<String,Entry> map=new HashMap<>();
ResourceDMBean dm=new ResourceDMBean(p, filter);
dm.forAllAttributes((k,v) -> {
MBeanAttributeInfo info=v.info();
String descr=info != null? info.getDescription() : "n/a";
Expand All @@ -73,20 +93,24 @@ public static Map<String,Entry> extract(Protocol p) {
return map;
}

protected void start() throws Exception {
protected void start(boolean numeric) throws Exception {
ch=new JChannel().connect("bla").name("X");
Map<String,Map<String,Entry>> map=extract(ch);
Map<String,Map<String,Entry>> map=extract(ch, IS_NUMBER);
for(Map.Entry<String,Map<String,Entry>> e: map.entrySet()) {
System.out.printf("\n%s:\n---------------\n", e.getKey());
for(Map.Entry<String,Entry> e2: e.getValue().entrySet()) {
System.out.printf(" %s: %s\n", e2.getKey(), e2.getValue());
Entry entry=e2.getValue();
Supplier<Object> s=entry.getMethod();
if(s != null)
System.out.printf(" %s: %s\n", e2.getKey(), s.get());
}
}
Util.close(ch);
}

public static void main(String[] args) throws Throwable {
new ExtractMetrics().start();
boolean numeric=args.length > 0 && Boolean.parseBoolean(args[0]);
new ExtractMetrics().start(numeric);

}
}
Expand Down

0 comments on commit 2ad1563

Please sign in to comment.