
org.jgroups.stack.NonReflectiveProbeHandler Maven / Gradle / Ivy
package org.jgroups.stack;
import org.jgroups.JChannel;
import org.jgroups.JChannelProbeHandler;
import org.jgroups.annotations.ManagedAttribute;
import org.jgroups.annotations.ManagedOperation;
import org.jgroups.annotations.Property;
import org.jgroups.jmx.AdditionalJmxObjects;
import org.jgroups.jmx.ResourceDMBean;
import org.jgroups.util.Util;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
/**
* A {@link org.jgroups.stack.DiagnosticsHandler.ProbeHandler} that does not use reflection. Can be used instead of the
* default ProbeHandler for commands "jmx" and "op"
* @author Bela Ban
* @since 4.1.0
*/
public class NonReflectiveProbeHandler extends JChannelProbeHandler {
// List of fields and field getters. Can be used to get field values, invoke field getters to get field values
// and set fields (via Field.set()).
protected final Map> attrs=new LinkedHashMap<>();
// List of fields and corresponding setters. Can be used to set values of fields
protected final Map> setters=new LinkedHashMap<>();
// List of operations
protected final Map> operations=new LinkedHashMap<>();
protected static final Predicate FILTER=obj -> obj.isAnnotationPresent(ManagedAttribute.class) ||
(obj.isAnnotationPresent(Property.class) && obj.getAnnotation(Property.class).exposeAsManagedAttribute()) ||
obj.isAnnotationPresent(ManagedOperation.class);
public NonReflectiveProbeHandler(JChannel ch) {
super(ch);
}
public NonReflectiveProbeHandler initialize(Protocol[] protocols) {
return initialize(Arrays.asList(protocols));
}
public NonReflectiveProbeHandler initialize(Collection prots) {
for(Protocol prot: prots) {
String prot_name=prot.getName();
Map m=attrs.computeIfAbsent(prot_name, k -> new TreeMap<>());
BiConsumer field_func=(f,o) -> m.put(f.getName(), new ResourceDMBean.FieldAccessor(f, o));
BiConsumer method_func=(method,obj) -> { // getter
if(method.isAnnotationPresent(ManagedOperation.class)) {
Map tmp=operations.computeIfAbsent(prot_name, k -> new TreeMap<>());
tmp.put(method.getName(), new ResourceDMBean.MethodAccessor(method, obj));
}
else if(ResourceDMBean.isGetMethod(method)) {
String method_name=Util.getNameFromAnnotation(method);
String attributeName=Util.methodNameToAttributeName(method_name);
m.put(attributeName, new ResourceDMBean.MethodAccessor(method, obj));
}
else if(ResourceDMBean.isSetMethod(method)) { // setter
Map tmp=setters.computeIfAbsent(prot_name, k -> new TreeMap<>());
String method_name=Util.getNameFromAnnotation(method);
String attributeName=Util.methodNameToAttributeName(method_name);
tmp.put(attributeName, new ResourceDMBean.MethodAccessor(method, obj));
}
};
Util.forAllFieldsAndMethods(prot, FILTER, field_func, method_func);
if(prot instanceof AdditionalJmxObjects) {
Object[] objects=((AdditionalJmxObjects)prot).getJmxObjects();
if(objects != null) {
for(Object obj: objects)
if(obj != null)
Util.forAllFieldsAndMethods(obj, FILTER, field_func, method_func);
}
}
}
return this;
}
public String dump() {
StringBuilder sb=new StringBuilder("attrs\n-----\n");
for(Map.Entry> e: attrs.entrySet()) {
sb.append(e.getKey() + ":\n");
Map val=e.getValue();
val.forEach((key, value) -> sb.append(key + ": " + value).append("\n"));
}
sb.append("\nsetters\n--------\n");
for(Map.Entry> e: setters.entrySet()) {
sb.append(e.getKey() + ":\n");
Map val=e.getValue();
val.forEach((key, value) -> sb.append(key + ": " + value).append("\n"));
}
sb.append("\n");
sb.append("\noperations\n--------\n");
for(Map.Entry> e: operations.entrySet()) {
sb.append(e.getKey() + ":\n");
Map val=e.getValue();
val.forEach((key, value) -> sb.append(key + ": " + value).append("\n"));
}
sb.append("\n");
return sb.toString();
}
@Override
protected Map> dumpAttrsAllProtocols() {
Map> retval=new HashMap<>();
for(Map.Entry> e: attrs.entrySet()) {
String protocol_name=e.getKey();
Map val=e.getValue();
Map map=new TreeMap<>();
for(Map.Entry en: val.entrySet()) {
try {
Object v=en.getValue().invoke(null);
if(v instanceof Double)
v=String.format("%.2f", (double)v);
map.put(en.getKey(), v != null? v.toString() : "null");
}
catch(Exception ex) {
log.error("failed getting value for attribute %s.%s: %s", protocol_name, en.getKey(), ex);
}
}
if(!map.isEmpty())
retval.put(protocol_name, map);
}
return retval;
}
@Override
protected Map> dumpAttrsSelectedProtocol(String protocol_name, List attrs) {
Map map=this.attrs.get(protocol_name);
if(map == null)
return null;
Map> retval=new HashMap<>();
Map tmp;
retval.put(protocol_name, tmp=new TreeMap<>());
for(Map.Entry e: map.entrySet()) {
String attr_name=e.getKey();
if(attrs == null || attrs.stream().anyMatch(attr_name::startsWith)) {
try {
Object v=e.getValue().invoke(null);
tmp.put(attr_name, v);
}
catch(Exception ex) {
log.error("failed getting value for attribute %s.%s: %s", protocol_name, attr_name, ex);
}
}
}
return retval;
}
protected void handleAttrWrite(String protocol_name, String attr_name, String attr_value) {
Object converted_value=null;
// Try to find a suitable setter first:
Map m=setters.get(protocol_name);
if(m != null) {
ResourceDMBean.Accessor setter=m.get(attr_name);
if(setter != null) {
Class> type=((ResourceDMBean.MethodAccessor)setter).getMethod().getParameterTypes()[0];
converted_value=Util.convert(attr_value, type);
invoke(protocol_name, setter, attr_name, converted_value);
return;
}
}
// try to find a field
m=attrs.get(protocol_name);
if(m == null)
throw new RuntimeException(String.format("protocol %s not found", protocol_name));
ResourceDMBean.Accessor setter=m.get(attr_name);
if(setter == null)
throw new RuntimeException(String.format("attribute %s not found in protocol %s", attr_name, protocol_name));
if(setter instanceof ResourceDMBean.FieldAccessor) {
converted_value=Util.convert(attr_value, ((ResourceDMBean.FieldAccessor)setter).getField().getType());
invoke(protocol_name, setter, attr_name, converted_value);
}
}
@Override
protected Method findMethod(Protocol prot, String method_name, String[] args) throws Exception {
Map map=operations.get(prot.getName());
if(map == null) {
log.error("protocol %s not found for method %s", prot.getName(), method_name);
return null;
}
ResourceDMBean.MethodAccessor accessor=map.get(method_name);
if(accessor == null) {
log.error("method %s not found", method_name);
return null;
}
return accessor.getMethod();
}
protected static void invoke(String protocol_name, ResourceDMBean.Accessor setter, String attr, Object value) {
try {
setter.invoke(value);
}
catch(Exception e) {
throw new RuntimeException(String.format("setting %s=%s failed in protocol %s: %s", attr, value, protocol_name, e));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy