package com.yammer.telemetry.agent.handlers;
import com.google.common.io.Resources;
import javassist.*;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.nio.charset.Charset;
public class ApacheHttpClientClassHandler extends SubTypeInstrumentationHandler {
public ApacheHttpClientClassHandler() {
super("org.apache.http.client.HttpClient");
}
protected boolean transform(CtClass cc, ClassPool pool) throws NotFoundException, CannotCompileException, IOException {
boolean transformedOneMethod = false;
for (CtMethod method : cc.getDeclaredMethods()) {
if ("execute".equals(method.getName()) && !Modifier.isAbstract(method.getModifiers())) {
String hostParameter = "null";
String requestParameter = "null";
String requestUriParameter = "null";
String handlerParameter = "null";
CtClass[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i].subtypeOf(pool.get("org.apache.http.HttpHost"))) {
hostParameter = "$" + (i + 1);
} else if (parameterTypes[i].subtypeOf(pool.get("org.apache.http.client.methods.HttpUriRequest"))) {
requestParameter = "$" + (i + 1);
requestUriParameter = "$" + (i + 1);
} else if (parameterTypes[i].subtypeOf(pool.get("org.apache.http.HttpRequest"))) {
requestParameter = "$" + (i + 1);
}
}
// Copy the method to a uniquely named location that won't conflict with anything.
CtMethod copiedMethod = CtNewMethod.copy(method, cc.makeUniqueName("execute"), cc, null);
copiedMethod.setModifiers(javassist.Modifier.PRIVATE);
cc.addMethod(copiedMethod);
final String source = Resources.toString(Resources.getResource(getClass(), "HttpClient_execute.javassist"), Charset.forName("utf-8"));
pool.importPackage("java.net");
pool.importPackage("org.apache.http");
pool.importPackage("org.apache.http.client.methods");
pool.importPackage("com.yammer.telemetry.tracing");
pool.importPackage("com.yammer.telemetry.agent.handlers");
String body = source.replace("%HTTP_HOST_PARAM%", hostParameter)
.replace("%HTTP_REQUEST_PARAM%", requestParameter)
.replace("%HTTP_REQUEST_URI_PARAM%", requestUriParameter)
.replace("%RESPONSE_HANDLER_PARAM%", handlerParameter);
method.setBody(body, "this", copiedMethod.getName());
transformedOneMethod = true;
}
}
return transformedOneMethod;
}
}