update the plugin discovery function. javassist removed.

This commit is contained in:
Zhen Tang 2013-07-05 13:56:40 +08:00
parent d6ee08a983
commit 07aef55430
7 changed files with 110 additions and 85 deletions

View File

@ -37,11 +37,6 @@
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.18.0-GA</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>

View File

@ -0,0 +1,12 @@
package org.bench4q.agent.plugin;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Parameter {
String value();
}

View File

@ -1,22 +1,13 @@
package org.bench4q.agent.plugin;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javassist.ClassPool;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.NotFoundException;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -81,17 +72,15 @@ public class PluginManager {
List<PluginInfo> ret = new ArrayList<PluginInfo>();
for (Class<?> plugin : plugins.values()) {
PluginInfo pluginInfo = new PluginInfo();
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.get(plugin.getCanonicalName());
pluginInfo.setName(((Plugin) ctClass
.getAnnotation(Plugin.class)).value());
pluginInfo.setParameters(this.getParameters(ctClass
pluginInfo
.setName((plugin.getAnnotation(Plugin.class)).value());
pluginInfo.setParameters(this.getParameters(plugin
.getConstructors()[0]));
CtMethod[] behaviors = this.getBehaviors(ctClass);
Method[] behaviors = this.getBehaviors(plugin);
pluginInfo.setBehaviors(new BehaviorInfo[behaviors.length]);
int i = 0;
for (i = 0; i < behaviors.length; i++) {
CtMethod behaviorMethod = behaviors[i];
Method behaviorMethod = behaviors[i];
BehaviorInfo behaviorInfo = buildBehaviorInfo(behaviorMethod);
pluginInfo.getBehaviors()[i] = behaviorInfo;
}
@ -104,28 +93,28 @@ public class PluginManager {
}
}
private BehaviorInfo buildBehaviorInfo(CtMethod behaviorMethod)
private BehaviorInfo buildBehaviorInfo(Method behaviorMethod)
throws ClassNotFoundException {
BehaviorInfo behaviorInfo = new BehaviorInfo();
behaviorInfo.setName(((Behavior) behaviorMethod
.getAnnotation(Behavior.class)).value());
behaviorInfo.setName((behaviorMethod.getAnnotation(Behavior.class))
.value());
behaviorInfo.setParameters(this.getParameters(behaviorMethod));
return behaviorInfo;
}
private ParameterInfo[] getParameters(CtBehavior behavior) {
private ParameterInfo[] getParameters(Method behavior) {
try {
MethodInfo methodInfo = behavior.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute localVariableAttribute = (LocalVariableAttribute) codeAttribute
.getAttribute(LocalVariableAttribute.tag);
int parameterCount = behavior.getParameterTypes().length;
Annotation[][] parameterAnnotations = behavior
.getParameterAnnotations();
ParameterInfo[] parameterNames = new ParameterInfo[parameterCount];
int i;
int pos = Modifier.isStatic(behavior.getModifiers()) ? 0 : 1;
for (i = 0; i < parameterCount; i++) {
ParameterInfo parameterInfo = buildParameterInfo(behavior,
localVariableAttribute, i, pos);
Annotation[] annotations = parameterAnnotations[i];
Parameter parameter = (Parameter) annotations[0];
Class<?> type = behavior.getParameterTypes()[i];
ParameterInfo parameterInfo = buildParameterInfo(
parameter.value(), type.getName());
parameterNames[i] = parameterInfo;
}
return parameterNames;
@ -135,26 +124,46 @@ public class PluginManager {
}
}
private ParameterInfo buildParameterInfo(CtBehavior behavior,
LocalVariableAttribute localVariableAttribute, int i, int pos)
throws NotFoundException {
private ParameterInfo[] getParameters(Constructor<?> behavior) {
try {
int parameterCount = behavior.getParameterTypes().length;
Annotation[][] parameterAnnotations = behavior
.getParameterAnnotations();
ParameterInfo[] parameterNames = new ParameterInfo[parameterCount];
int i;
for (i = 0; i < parameterCount; i++) {
Annotation[] annotations = parameterAnnotations[i];
Parameter parameter = (Parameter) annotations[0];
Class<?> type = behavior.getParameterTypes()[i];
ParameterInfo parameterInfo = buildParameterInfo(
parameter.value(), type.getName());
parameterNames[i] = parameterInfo;
}
return parameterNames;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private ParameterInfo buildParameterInfo(String name, String type) {
ParameterInfo parameterInfo = new ParameterInfo();
parameterInfo.setName(localVariableAttribute.variableName(i + pos));
parameterInfo.setType(behavior.getParameterTypes()[i].getName());
parameterInfo.setName(name);
parameterInfo.setType(type);
return parameterInfo;
}
private CtMethod[] getBehaviors(CtClass plugin) {
private Method[] getBehaviors(Class<?> plugin) {
try {
CtMethod[] ctMethods = plugin.getMethods();
List<CtMethod> ret = new ArrayList<CtMethod>();
Method[] methods = plugin.getMethods();
List<Method> ret = new ArrayList<Method>();
int i = 0;
for (i = 0; i < ctMethods.length; i++) {
if (ctMethods[i].hasAnnotation(Behavior.class)) {
ret.add(ctMethods[i]);
for (i = 0; i < methods.length; i++) {
if (methods[i].isAnnotationPresent(Behavior.class)) {
ret.add(methods[i]);
}
}
return ret.toArray(new CtMethod[0]);
return ret.toArray(new Method[0]);
} catch (Exception e) {
e.printStackTrace();
return null;
@ -164,13 +173,11 @@ public class PluginManager {
public Object initializePlugin(Class<?> plugin,
Map<String, String> parameters) {
try {
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.get(plugin.getCanonicalName());
CtConstructor[] ctConstructors = ctClass.getConstructors();
Constructor<?>[] ctConstructors = plugin.getConstructors();
if (ctConstructors.length != 1) {
return null;
}
CtConstructor constructor = ctConstructors[0];
Constructor<?> constructor = ctConstructors[0];
Object[] params = prepareParameters(constructor, parameters);
return plugin.getConstructors()[0].newInstance(params);
} catch (Exception e) {
@ -179,7 +186,29 @@ public class PluginManager {
}
}
private Object[] prepareParameters(CtBehavior behavior,
private Object[] prepareParameters(Constructor<?> behavior,
Map<String, String> parameters) {
try {
ParameterInfo[] parameterInfo = this.getParameters(behavior);
Object values[] = new Object[parameterInfo.length];
int i = 0;
for (i = 0; i < parameterInfo.length; i++) {
Object value = parameters.get(parameterInfo[i].getName());
if (value == null) {
values[i] = null;
} else {
values[i] = this.getTypeConverter().convert(value,
parameterInfo[i].getType());
}
}
return values;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private Object[] prepareParameters(Method behavior,
Map<String, String> parameters) {
try {
ParameterInfo[] parameterInfo = this.getParameters(behavior);
@ -204,15 +233,11 @@ public class PluginManager {
public Object doBehavior(Object plugin, String behaviorName,
Map<String, String> parameters) {
try {
CtMethod ctMethod = findCtMethod(plugin, behaviorName);
if (ctMethod == null) {
return null;
}
Method method = findMethod(plugin, ctMethod);
Method method = findMethod(plugin, behaviorName);
if (method == null) {
return null;
}
Object[] params = prepareParameters(ctMethod, parameters);
Object[] params = prepareParameters(method, parameters);
return method.invoke(plugin, params);
} catch (Exception e) {
e.printStackTrace();
@ -220,30 +245,15 @@ public class PluginManager {
}
}
private Method findMethod(Object plugin, CtMethod ctMethod) {
int i;
Method[] methods = plugin.getClass().getMethods();
Method method = null;
for (i = 0; i < methods.length; i++) {
if (methods[i].getName().equals(ctMethod.getName())) {
method = methods[i];
}
}
return method;
}
private CtMethod findCtMethod(Object plugin, String behaviorName) {
private Method findMethod(Object plugin, String behaviorName) {
try {
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.get(plugin.getClass()
.getCanonicalName());
CtMethod[] ctMethods = ctClass.getMethods();
Method[] methods = plugin.getClass().getMethods();
int i = 0;
for (i = 0; i < ctMethods.length; i++) {
if (ctMethods[i].hasAnnotation(Behavior.class)) {
if (((Behavior) ctMethods[i].getAnnotation(Behavior.class))
for (i = 0; i < methods.length; i++) {
if (methods[i].isAnnotationPresent(Behavior.class)) {
if (((Behavior) methods[i].getAnnotation(Behavior.class))
.value().equals(behaviorName)) {
return ctMethods[i];
return methods[i];
}
}
}

View File

@ -4,6 +4,7 @@ import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.bench4q.agent.plugin.Behavior;
import org.bench4q.agent.plugin.Parameter;
import org.bench4q.agent.plugin.Plugin;
@Plugin("CommandLine")
@ -32,7 +33,7 @@ public class CommandLinePlugin {
}
@Behavior("Command")
public boolean command(String command) {
public boolean command(@Parameter("command") String command) {
try {
final Process process = Runtime.getRuntime().exec(command);
new Thread() {

View File

@ -1,6 +1,7 @@
package org.bench4q.agent.plugin.basic;
import org.bench4q.agent.plugin.Behavior;
import org.bench4q.agent.plugin.Parameter;
import org.bench4q.agent.plugin.Plugin;
@Plugin("ConstantTimer")
@ -10,7 +11,7 @@ public class ConstantTimerPlugin {
}
@Behavior("Sleep")
public boolean sleep(int time) {
public boolean sleep(@Parameter("time") int time) {
try {
Thread.sleep(time);
return true;

View File

@ -5,7 +5,9 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import org.bench4q.agent.plugin.Behavior;
import org.bench4q.agent.plugin.Parameter;
import org.bench4q.agent.plugin.Plugin;
@Plugin("Http")
@ -16,7 +18,7 @@ public class HttpPlugin {
}
@Behavior("Get")
public boolean get(String url) {
public boolean get(@Parameter("url") String url) {
try {
URL target = new URL(url);
HttpURLConnection httpURLConnection = (HttpURLConnection) target
@ -41,7 +43,8 @@ public class HttpPlugin {
}
@Behavior("Post")
public boolean post(String url, String content) {
public boolean post(@Parameter("url") String url,
@Parameter("content") String content) {
try {
URL target = new URL(url);
HttpURLConnection httpURLConnection = (HttpURLConnection) target
@ -71,7 +74,8 @@ public class HttpPlugin {
}
@Behavior("Put")
public boolean put(String url, String content) {
public boolean put(@Parameter("url") String url,
@Parameter("content") String content) {
try {
URL target = new URL(url);
HttpURLConnection httpURLConnection = (HttpURLConnection) target
@ -101,7 +105,8 @@ public class HttpPlugin {
}
@Behavior("Delete")
public boolean delete(String url, String content) {
public boolean delete(@Parameter("url") String url,
@Parameter("content") String content) {
try {
URL target = new URL(url);
HttpURLConnection httpURLConnection = (HttpURLConnection) target

View File

@ -1,6 +1,7 @@
package org.bench4q.agent.plugin.basic;
import org.bench4q.agent.plugin.Behavior;
import org.bench4q.agent.plugin.Parameter;
import org.bench4q.agent.plugin.Plugin;
@Plugin("Log")
@ -10,7 +11,7 @@ public class LogPlugin {
}
@Behavior("Log")
public boolean log(String message) {
public boolean log(@Parameter("message") String message) {
System.out.println(message);
return true;
}