Monday, September 17, 2012

Distributed Concurrent HTTP Requests in Java. (in progress)


import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;

import org.apache.commons.beanutils.BeanPredicate;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.functors.EqualPredicate;

public class JavaCallable implements Callable {

private Object caller;
String method;
Object[] args;

public JavaCallable(Object caller, String method, Object[] args) {
super();
this.method = method;
this.args = args;
this.caller = caller;

}

@SuppressWarnings("unchecked")
private Method getReflectedMethod() {
List allMethods = Arrays.asList(caller.getClass().getMethods());
List methods = (List) CollectionUtils.select(allMethods, new BeanPredicate("name", new EqualPredicate(method)));
//todo: make this look at argument class types not just argument length.
Method res = (Method) CollectionUtils.find(methods, new Predicate() {
@Override
public boolean evaluate(Object object) {
Method m = (Method) object;
return m.getGenericParameterTypes().length == args.length;
}
});
return res;
}
@Override
public Object call() throws Exception {
return getReflectedMethod().invoke(caller, args);
}
}

//then somewhere else in your code you can distribute get requests like so.


List calls = new ArrayList();
List methods = new ArrayList();
for (HashMap node : nodes) {
GetMethod getMethod = new GetMethod(someUri);
getMethod.setRequestHeader(HTTPLayer.REQUESTHEADERACCEPT);
getMethod.setRequestHeader(HTTPLayer.REQUESTHEADERCONTENTTYPE);
methods.add(getMethod);
calls.add(new JavaCallable(getClient(), "executeMethod", new Object[]{getMethod }));
}
ExecutorService es = Executors.newFixedThreadPool(calls.size());
List> futures = es.invokeAll(calls);
es.shutdown();
//loop through looking for exceptions
for(Future future: futures){
future.get();
}
return methods;

No comments:

Post a Comment