From 507acd567f3c663b7652ea384f09d53eb7105496 Mon Sep 17 00:00:00 2001 From: Jongho Moon Date: Tue, 11 Aug 2015 17:58:59 +0900 Subject: [PATCH] httpclient3 plugin now uses new plugin api --- .../plugin/httpclient3/HostNameGetter.java | 23 +++ .../plugin/httpclient3/HttpClient3Plugin.java | 136 +++++++++++------- .../plugin/httpclient3/PortNumberGetter.java | 23 +++ .../httpclient3/ProxyHostNameGetter.java | 23 +++ .../httpclient3/ProxyPortNumberGetter.java | 23 +++ .../HttpConnectionOpenMethodInterceptor.java | 30 ++-- ...ttpMethodBaseExecuteMethodInterceptor.java | 1 - 7 files changed, 191 insertions(+), 68 deletions(-) create mode 100644 plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/HostNameGetter.java create mode 100644 plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/PortNumberGetter.java create mode 100644 plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/ProxyHostNameGetter.java create mode 100644 plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/ProxyPortNumberGetter.java diff --git a/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/HostNameGetter.java b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/HostNameGetter.java new file mode 100644 index 000000000..1c0abf0ce --- /dev/null +++ b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/HostNameGetter.java @@ -0,0 +1,23 @@ +/** + * Copyright 2014 NAVER Corp. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.plugin.httpclient3; + +/** + * @author Jongho Moon + * + */ +public interface HostNameGetter { + public String _$PINPOINT$_getHostName(); +} diff --git a/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/HttpClient3Plugin.java b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/HttpClient3Plugin.java index 565e19b57..848c31a5f 100644 --- a/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/HttpClient3Plugin.java +++ b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/HttpClient3Plugin.java @@ -15,14 +15,15 @@ */ package com.navercorp.pinpoint.plugin.httpclient3; -import com.navercorp.pinpoint.bootstrap.logging.PLogger; -import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; +import java.security.ProtectionDomain; + +import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass; +import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException; +import com.navercorp.pinpoint.bootstrap.instrument.InstrumentMethod; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin; +import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginInstrumentContext; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; -import com.navercorp.pinpoint.bootstrap.plugin.transformer.BaseClassFileTransformerBuilder; -import com.navercorp.pinpoint.bootstrap.plugin.transformer.ClassFileTransformerBuilder; -import com.navercorp.pinpoint.bootstrap.plugin.transformer.MethodTransformerBuilder; -import com.navercorp.pinpoint.bootstrap.plugin.transformer.MethodTransformerProperty; +import com.navercorp.pinpoint.bootstrap.plugin.transformer.PinpointClassFileTransformer; /** * @author netspider @@ -50,61 +51,100 @@ public class HttpClient3Plugin implements ProfilerPlugin, HttpClient3Constants { } private void addHttpClient3Class(ProfilerPluginSetupContext context, HttpClient3PluginConfig config) { - final ClassFileTransformerBuilder classEditorBuilder = context.getClassFileTransformerBuilder("org.apache.commons.httpclient.HttpClient"); + context.addClassFileTransformer("org.apache.commons.httpclient.HttpClient", new PinpointClassFileTransformer() { + + @Override + public byte[] transform(ProfilerPluginInstrumentContext instrumentContext, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { + InstrumentClass target = instrumentContext.getInstrumentClass(loader, className, classfileBuffer); + + injectHttpClientExecuteMethod(target, "org.apache.commons.httpclient.HttpMethod"); + injectHttpClientExecuteMethod(target, "org.apache.commons.httpclient.HostConfiguration", "org.apache.commons.httpclient.HttpMethod"); + injectHttpClientExecuteMethod(target, "org.apache.commons.httpclient.HostConfiguration", "org.apache.commons.httpclient.HttpMethod", "org.apache.commons.httpclient.HttpState"); + + return target.toBytecode(); + } - injectHttpClientExecuteMethod(classEditorBuilder, "org.apache.commons.httpclient.HttpMethod"); - injectHttpClientExecuteMethod(classEditorBuilder, "org.apache.commons.httpclient.HostConfiguration", "org.apache.commons.httpclient.HttpMethod"); - injectHttpClientExecuteMethod(classEditorBuilder, "org.apache.commons.httpclient.HostConfiguration", "org.apache.commons.httpclient.HttpMethod", "org.apache.commons.httpclient.HttpState"); - - context.addClassFileTransformer(classEditorBuilder.build()); + private void injectHttpClientExecuteMethod(InstrumentClass target, String... parameterTypeNames) throws InstrumentException { + InstrumentMethod method = target.getDeclaredMethod("executeMethod", parameterTypeNames); + + if (method != null) { + method.addInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.ExecuteInterceptor"); + } + } + }); } - private void injectHttpClientExecuteMethod(final BaseClassFileTransformerBuilder classEditorBuilder, String... parameterTypeNames) { - MethodTransformerBuilder methodEditorBuilder = classEditorBuilder.editMethod("executeMethod", parameterTypeNames); - methodEditorBuilder.property(MethodTransformerProperty.IGNORE_IF_NOT_EXIST); - methodEditorBuilder.injectInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.ExecuteInterceptor"); - } private void addDefaultHttpMethodRetryHandlerClass(ProfilerPluginSetupContext context, HttpClient3PluginConfig config) { - final ClassFileTransformerBuilder classEditorBuilder = context.getClassFileTransformerBuilder("org.apache.commons.httpclient.DefaultHttpMethodRetryHandler"); - MethodTransformerBuilder methodEditorBuilder = classEditorBuilder.editMethod("retryMethod", "org.apache.commons.httpclient.HttpMethod", "java.io.IOException", "int"); - methodEditorBuilder.property(MethodTransformerProperty.IGNORE_IF_NOT_EXIST); - methodEditorBuilder.injectInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.RetryMethodInterceptor"); - - context.addClassFileTransformer(classEditorBuilder.build()); + context.addClassFileTransformer("org.apache.commons.httpclient.DefaultHttpMethodRetryHandler", new PinpointClassFileTransformer() { + + @Override + public byte[] transform(ProfilerPluginInstrumentContext instrumentContext, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { + InstrumentClass target = instrumentContext.getInstrumentClass(loader, className, classfileBuffer); + + InstrumentMethod retryMethod = target.getDeclaredMethod("retryMethod", "org.apache.commons.httpclient.HttpMethod", "java.io.IOException", "int"); + + if (retryMethod != null) { + retryMethod.addInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.RetryMethodInterceptor"); + } + + return target.toBytecode(); + } + }); } private void addHttpConnectionClass(ProfilerPluginSetupContext context, HttpClient3PluginConfig config) { - final ClassFileTransformerBuilder classEditorBuilder = context.getClassFileTransformerBuilder("org.apache.commons.httpclient.HttpConnection"); - classEditorBuilder.injectFieldAccessor(FIELD_HOST_NAME); - classEditorBuilder.injectFieldAccessor(FIELD_PORT_NUMBER); - classEditorBuilder.injectFieldAccessor(FIELD_PROXY_HOST_NAME); - classEditorBuilder.injectFieldAccessor(FIELD_PROXY_PORT_NUMBER); - - MethodTransformerBuilder methodEditorBuilder = classEditorBuilder.editMethod("open"); - methodEditorBuilder.property(MethodTransformerProperty.IGNORE_IF_NOT_EXIST); - methodEditorBuilder.injectInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.HttpConnectionOpenMethodInterceptor"); + context.addClassFileTransformer("org.apache.commons.httpclient.HttpConnection", new PinpointClassFileTransformer() { + + @Override + public byte[] transform(ProfilerPluginInstrumentContext instrumentContext, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { + InstrumentClass target = instrumentContext.getInstrumentClass(loader, className, classfileBuffer); + + target.addGetter(HostNameGetter.class.getName(), HttpClient3Constants.FIELD_HOST_NAME); + target.addGetter(PortNumberGetter.class.getName(), HttpClient3Constants.FIELD_PORT_NUMBER); + target.addGetter(ProxyHostNameGetter.class.getName(), HttpClient3Constants.FIELD_PROXY_HOST_NAME); + target.addGetter(ProxyPortNumberGetter.class.getName(), HttpClient3Constants.FIELD_PROXY_PORT_NUMBER); - context.addClassFileTransformer(classEditorBuilder.build()); + InstrumentMethod open = target.getDeclaredMethod("open"); + + if (open != null) { + open.addInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.HttpConnectionOpenMethodInterceptor"); + } + + return target.toBytecode(); + } + }); } - private void addHttpMethodBaseClass(ProfilerPluginSetupContext context, HttpClient3PluginConfig config) { - final ClassFileTransformerBuilder classEditorBuilder = context.getClassFileTransformerBuilder("org.apache.commons.httpclient.HttpMethodBase"); - MethodTransformerBuilder executeMethodEditorBuilder = classEditorBuilder.editMethod("execute", "org.apache.commons.httpclient.HttpState", "org.apache.commons.httpclient.HttpConnection"); - executeMethodEditorBuilder.property(MethodTransformerProperty.IGNORE_IF_NOT_EXIST); - executeMethodEditorBuilder.injectInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.HttpMethodBaseExecuteMethodInterceptor"); - - if(config.isApacheHttpClient3ProfileIo()) { - MethodTransformerBuilder writeRequestMethodEditorBuilder = classEditorBuilder.editMethod("writeRequest", "org.apache.commons.httpclient.HttpState", "org.apache.commons.httpclient.HttpConnection"); - writeRequestMethodEditorBuilder.property(MethodTransformerProperty.IGNORE_IF_NOT_EXIST); - writeRequestMethodEditorBuilder.injectInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.HttpMethodBaseRequestAndResponseMethodInterceptor"); + private void addHttpMethodBaseClass(ProfilerPluginSetupContext context, final HttpClient3PluginConfig config) { + context.addClassFileTransformer("org.apache.commons.httpclient.HttpMethodBase", new PinpointClassFileTransformer() { - MethodTransformerBuilder readResponseMethodEditorBuilder = classEditorBuilder.editMethod("readResponse", "org.apache.commons.httpclient.HttpState", "org.apache.commons.httpclient.HttpConnection"); - readResponseMethodEditorBuilder.property(MethodTransformerProperty.IGNORE_IF_NOT_EXIST); - readResponseMethodEditorBuilder.injectInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.HttpMethodBaseRequestAndResponseMethodInterceptor"); - } + @Override + public byte[] transform(ProfilerPluginInstrumentContext instrumentContext, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { + InstrumentClass target = instrumentContext.getInstrumentClass(loader, className, classfileBuffer); + + InstrumentMethod execute = target.getDeclaredMethod("execute", "org.apache.commons.httpclient.HttpState", "org.apache.commons.httpclient.HttpConnection"); + if (execute != null) { + execute.addInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.HttpMethodBaseExecuteMethodInterceptor"); + } + + if (config.isApacheHttpClient3ProfileIo()) { + InstrumentMethod writeRequest = target.getDeclaredMethod("writeRequest", "org.apache.commons.httpclient.HttpState", "org.apache.commons.httpclient.HttpConnection"); + + if (writeRequest != null) { + writeRequest.addInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.HttpMethodBaseRequestAndResponseMethodInterceptor"); + } + + InstrumentMethod readResponse = target.getDeclaredMethod("readResponse", "org.apache.commons.httpclient.HttpState", "org.apache.commons.httpclient.HttpConnection"); + + if (readResponse != null) { + readResponse.addInterceptor("com.navercorp.pinpoint.plugin.httpclient3.interceptor.HttpMethodBaseRequestAndResponseMethodInterceptor"); + } + } - context.addClassFileTransformer(classEditorBuilder.build()); + return target.toBytecode(); + } + }); } } \ No newline at end of file diff --git a/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/PortNumberGetter.java b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/PortNumberGetter.java new file mode 100644 index 000000000..e9e74e0c0 --- /dev/null +++ b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/PortNumberGetter.java @@ -0,0 +1,23 @@ +/** + * Copyright 2014 NAVER Corp. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.plugin.httpclient3; + +/** + * @author Jongho Moon + * + */ +public interface PortNumberGetter { + public int _$PINPOINT$_getPortNumber(); +} diff --git a/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/ProxyHostNameGetter.java b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/ProxyHostNameGetter.java new file mode 100644 index 000000000..598506c59 --- /dev/null +++ b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/ProxyHostNameGetter.java @@ -0,0 +1,23 @@ +/** + * Copyright 2014 NAVER Corp. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.plugin.httpclient3; + +/** + * @author Jongho Moon + * + */ +public interface ProxyHostNameGetter { + public String _$PINPOINT$_getProxyHostName(); +} diff --git a/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/ProxyPortNumberGetter.java b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/ProxyPortNumberGetter.java new file mode 100644 index 000000000..567d5aadc --- /dev/null +++ b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/ProxyPortNumberGetter.java @@ -0,0 +1,23 @@ +/** + * Copyright 2014 NAVER Corp. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.plugin.httpclient3; + +/** + * @author Jongho Moon + * + */ +public interface ProxyPortNumberGetter { + public int _$PINPOINT$_getProxyPortNumber(); +} diff --git a/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/interceptor/HttpConnectionOpenMethodInterceptor.java b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/interceptor/HttpConnectionOpenMethodInterceptor.java index 58017007a..f10ee8395 100644 --- a/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/interceptor/HttpConnectionOpenMethodInterceptor.java +++ b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/interceptor/HttpConnectionOpenMethodInterceptor.java @@ -16,33 +16,25 @@ package com.navercorp.pinpoint.plugin.httpclient3.interceptor; -import com.navercorp.pinpoint.bootstrap.FieldAccessor; import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder; import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.interceptor.MethodDescriptor; import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptorForPlugin; -import com.navercorp.pinpoint.bootstrap.plugin.annotation.Name; import com.navercorp.pinpoint.common.trace.AnnotationKey; import com.navercorp.pinpoint.common.trace.ServiceType; +import com.navercorp.pinpoint.plugin.httpclient3.HostNameGetter; import com.navercorp.pinpoint.plugin.httpclient3.HttpClient3Constants; +import com.navercorp.pinpoint.plugin.httpclient3.PortNumberGetter; +import com.navercorp.pinpoint.plugin.httpclient3.ProxyHostNameGetter; +import com.navercorp.pinpoint.plugin.httpclient3.ProxyPortNumberGetter; /** * @author jaehong.kim */ public class HttpConnectionOpenMethodInterceptor extends SpanEventSimpleAroundInterceptorForPlugin implements HttpClient3Constants { - private FieldAccessor hostNameAccessor; - private FieldAccessor portNumberAccessor; - private FieldAccessor proxyHostNameAccessor; - private FieldAccessor proxyPortNumberAccessor; - - public HttpConnectionOpenMethodInterceptor(TraceContext traceContext, MethodDescriptor methodDescriptor, @Name(FIELD_HOST_NAME) FieldAccessor hostNameAccessor, @Name(FIELD_PORT_NUMBER) FieldAccessor portNumberAccessor, - @Name(FIELD_PROXY_HOST_NAME) FieldAccessor proxyHostNameAccessor, @Name(FIELD_PROXY_PORT_NUMBER) FieldAccessor proxyPortNumberAccessor) { + public HttpConnectionOpenMethodInterceptor(TraceContext traceContext, MethodDescriptor methodDescriptor) { super(traceContext, methodDescriptor); - this.hostNameAccessor = hostNameAccessor; - this.portNumberAccessor = portNumberAccessor; - this.proxyHostNameAccessor = proxyHostNameAccessor; - this.proxyPortNumberAccessor = proxyPortNumberAccessor; } @Override @@ -50,14 +42,14 @@ public class HttpConnectionOpenMethodInterceptor extends SpanEventSimpleAroundIn recorder.recordApi(methodDescriptor); recorder.recordServiceType(ServiceType.HTTP_CLIENT_INTERNAL); - if (hostNameAccessor.isApplicable(target) && portNumberAccessor.isApplicable(target) && proxyHostNameAccessor.isApplicable(target) && proxyPortNumberAccessor.isApplicable(target)) { + if (target instanceof HostNameGetter && target instanceof PortNumberGetter && target instanceof ProxyHostNameGetter && target instanceof ProxyPortNumberGetter) { final StringBuilder sb = new StringBuilder(); - if (proxyHostNameAccessor.get(target) != null) { - sb.append(proxyHostNameAccessor.get(target)); - sb.append(":").append(proxyPortNumberAccessor.get(target)); + if (((ProxyHostNameGetter)target)._$PINPOINT$_getProxyHostName() != null) { + sb.append(((ProxyHostNameGetter)target)._$PINPOINT$_getProxyHostName()); + sb.append(":").append(((ProxyPortNumberGetter)target)._$PINPOINT$_getProxyPortNumber()); } else { - sb.append(hostNameAccessor.get(target)); - sb.append(":").append(proxyPortNumberAccessor.get(target)); + sb.append(((HostNameGetter)target)._$PINPOINT$_getHostName()); + sb.append(":").append(((PortNumberGetter)target)._$PINPOINT$_getPortNumber()); } recorder.recordAttribute(AnnotationKey.HTTP_INTERNAL_DISPLAY, sb.toString()); } diff --git a/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/interceptor/HttpMethodBaseExecuteMethodInterceptor.java b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/interceptor/HttpMethodBaseExecuteMethodInterceptor.java index dc0890084..769742441 100644 --- a/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/interceptor/HttpMethodBaseExecuteMethodInterceptor.java +++ b/plugins/httpclient3/src/main/java/com/navercorp/pinpoint/plugin/httpclient3/interceptor/HttpMethodBaseExecuteMethodInterceptor.java @@ -54,7 +54,6 @@ import com.navercorp.pinpoint.common.trace.AnnotationKey; import com.navercorp.pinpoint.common.trace.ServiceType; import com.navercorp.pinpoint.plugin.httpclient3.HttpClient3CallContext; import com.navercorp.pinpoint.plugin.httpclient3.HttpClient3Constants; -import com.navercorp.pinpoint.plugin.httpclient3.HttpClient3PluginConfig; /** * @author Minwoo Jung