This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new b431f41  Rewrite Async http client plugin (#1217)
b431f41 is described below

commit b431f4145c8f85516df1142eacbf74c32aef0b09
Author: lican <lican198...@foxmail.com>
AuthorDate: Tue May 15 22:55:05 2018 +0800

    Rewrite Async http client plugin (#1217)
    
    * rewrite http-async-client
    
    * add unit test and document
    
    * fix check style issue
    
    * update test
    
    * update doc fix ci
    
    * fix review
---
 .../httpasyncclient-4.x-plugin/pom.xml             |   6 -
 .../httpasyncclient/v4/ConnectIterceptor.java      |  62 -----
 .../v4/DefaultConnectingIOReactorIterceptor.java   |  61 -----
 .../v4/HttpAsyncClientInterceptor.java             |  60 +++++
 ...va => HttpAsyncRequestExecutorInterceptor.java} | 168 ++++++-------
 .../v4/HttpAsyncResponseConsumerInterceptor.java   |  66 -----
 .../httpasyncclient/v4/HttpHostInterceptor.java    |  66 -----
 .../v4/ProcessResponseInterceptor.java             |  66 -----
 .../v4/SessionRequestCompleteInterceptor.java      |  63 +++++
 .../v4/SessionRequestConstructorInterceptor.java   |  40 +++
 ...tor.java => SessionRequestFailInterceptor.java} | 106 ++++----
 .../httpasyncclient/v4/SetResponseInterceptor.java |  63 -----
 .../httpasyncclient/v4/SuccessInterceptor.java     |  61 -----
 .../define/AbstractNIOConnPoolInstrumentation.java |  76 ------
 .../DefaultConnectingIOReactorInstrumentation.java |  91 -------
 .../v4/define/ExecuteInstrumentation.java          |  92 -------
 .../v4/define/HttpAsyncClientInstrumentation.java  |  76 ++++++
 ...> HttpAsyncRequestExecutorInstrumentation.java} | 144 ++++++-----
 .../define/SessionRequestImplInstrumentation.java  |  75 ------
 .../v4/define/SessionRequestInstrumentation.java   | 104 ++++++++
 .../v4/define/StateInstrumentation.java            |  91 -------
 .../v4/wrapper/FutureCallbackWrapper.java          |  72 ++++++
 .../wrapper/HttpAsyncResponseConsumerWrapper.java  | 111 +++++++++
 .../src/main/resources/skywalking-plugin.def       |   9 +-
 .../v4/HttpAsyncClientInterceptorTest.java         | 275 +++++++++++++++++++++
 .../httpasyncclient/v4/StateInterceptorTest.java   | 179 --------------
 .../plugin/httpasyncclient/v4/TestException.java   | 160 ------------
 27 files changed, 1011 insertions(+), 1432 deletions(-)

diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/pom.xml 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/pom.xml
index f7e90eb..d9f4c50 100644
--- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/pom.xml
@@ -41,12 +41,6 @@
             <version>4.1.1</version>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpasyncclient-cache</artifactId>
-            <version>4.1.1</version>
-            <scope>provided</scope>
-        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ConnectIterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ConnectIterceptor.java
deleted file mode 100644
index 09725eb..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ConnectIterceptor.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.lang.reflect.Method;
-import java.net.InetSocketAddress;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
-
-/**
- * Pass ref accross thread by SessionRequest.
- *
- * @author liyuntao
- */
-
-public class ConnectIterceptor implements InstanceMethodsAroundInterceptor {
-
-    @Override public void beforeMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
-
-    }
-
-    @Override public Object afterMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Object ret) throws Throwable {
-        
((EnhancedInstance)ret).setSkyWalkingDynamicField(ContextManager.capture());
-
-        InetSocketAddress remoteAddress = (InetSocketAddress)allArguments[0];
-        String peer = remoteAddress.toString().substring(1);
-
-        Object[] cacheValue = new Object[3];
-        cacheValue[0] = ContextManager.capture();
-        cacheValue[1] = peer;
-        objInst.setSkyWalkingDynamicField(cacheValue);
-        return ret;
-    }
-
-    @Override public void handleMethodException(EnhancedInstance objInst, 
Method method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Throwable t) {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        activeSpan.errorOccurred();
-        activeSpan.log(t);
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/DefaultConnectingIOReactorIterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/DefaultConnectingIOReactorIterceptor.java
deleted file mode 100644
index bb7c44f..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/DefaultConnectingIOReactorIterceptor.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.lang.reflect.Method;
-import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
-import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
-
-/**
- * Create local span :httpasyncclient/SocketChannel, to showcase the ability 
to connect to the remote host.
- *
- * @author liyuntao
- */
-
-public class DefaultConnectingIOReactorIterceptor implements 
InstanceMethodsAroundInterceptor {
-
-    @Override public void beforeMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
-        Object[] cacheValue = (Object[])objInst.getSkyWalkingDynamicField();
-        final ContextCarrier contextCarrier = new ContextCarrier();
-        AbstractSpan span = ContextManager.createExitSpan("httpasyncclient/" + 
method.getName(), contextCarrier, cacheValue[1].toString());
-        ContextManager.continued((ContextSnapshot)cacheValue[0]);
-        
span.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT).setLayer(SpanLayer.HTTP);
-    }
-
-    @Override public Object afterMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Object ret) throws Throwable {
-        ContextManager.stopSpan();
-        return ret;
-    }
-
-    @Override public void handleMethodException(EnhancedInstance objInst, 
Method method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Throwable t) {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        activeSpan.errorOccurred();
-        activeSpan.log(t);
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptor.java
new file mode 100644
index 0000000..d35d9bb
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptor.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
+
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
+import org.apache.http.protocol.HttpContext;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.wrapper.FutureCallbackWrapper;
+import 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.wrapper.HttpAsyncResponseConsumerWrapper;
+
+import java.lang.reflect.Method;
+
+import static 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL;
+
+/**
+ * in main thread,hold the context in thread local so we can read in the same 
thread.
+ *
+ * @author lican
+ */
+public class HttpAsyncClientInterceptor implements 
InstanceMethodsAroundInterceptor {
+
+
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] 
allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
+        HttpAsyncResponseConsumer consumer = (HttpAsyncResponseConsumer) 
allArguments[1];
+        HttpContext context = (HttpContext) allArguments[2];
+        FutureCallback callback = (FutureCallback) allArguments[3];
+        allArguments[1] = new HttpAsyncResponseConsumerWrapper(consumer);
+        allArguments[3] = new FutureCallbackWrapper(callback);
+        CONTEXT_LOCAL.set(context);
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable {
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
+
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncRequestExecutorInterceptor.java
similarity index 52%
rename from 
apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptor.java
rename to 
apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncRequestExecutorInterceptor.java
index 156b1ca..47b9761 100644
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptor.java
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncRequestExecutorInterceptor.java
@@ -1,84 +1,84 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import org.apache.http.client.methods.HttpRequestWrapper;
-import org.apache.skywalking.apm.agent.core.context.CarrierItem;
-import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.tag.Tags;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
-import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
-
-/**
- * Create exit span of httpasyncclient.
- *
- * @author liyuntao
- */
-
-public class StateInterceptor implements InstanceMethodsAroundInterceptor {
-
-    @Override public void beforeMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
-        if (null == allArguments[0]) {
-            return;
-        }
-        HttpRequestWrapper httpRequest = (HttpRequestWrapper)allArguments[0];
-        String uri = httpRequest.getOriginal().getRequestLine().getUri();
-        AbstractSpan span = null;
-        final ContextCarrier contextCarrier = new ContextCarrier();
-        try {
-            URL url = new 
URL(httpRequest.getOriginal().getRequestLine().getUri());
-            String remotePeer = url.getHost() + ":" + url.getPort();
-            span = ContextManager.createExitSpan(url.getPath(), 
contextCarrier, remotePeer);
-        } catch (MalformedURLException e) {
-            throw e;
-        }
-        span.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT);
-        Tags.URL.set(span, uri);
-        Tags.HTTP.METHOD.set(span, 
httpRequest.getOriginal().getRequestLine().getMethod());
-        SpanLayer.asHttp(span);
-
-        CarrierItem next = contextCarrier.items();
-        while (next.hasNext()) {
-            next = next.next();
-            httpRequest.setHeader(next.getHeadKey(), next.getHeadValue());
-        }
-
-    }
-
-    @Override public Object afterMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Object ret) throws Throwable {
-        return ret;
-    }
-
-    @Override public void handleMethodException(EnhancedInstance objInst, 
Method method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Throwable t) {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        activeSpan.errorOccurred();
-        activeSpan.log(t);
-    }
-}
\ No newline at end of file
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
+
+import org.apache.http.HttpHost;
+import org.apache.http.RequestLine;
+import org.apache.http.client.methods.HttpRequestWrapper;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.skywalking.apm.agent.core.context.CarrierItem;
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+
+import java.lang.reflect.Method;
+import java.net.URL;
+
+import static 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL;
+
+/**
+ * the actual point request begin fetch the request from thread local .
+ * @author lican
+ */
+public class HttpAsyncRequestExecutorInterceptor implements 
InstanceMethodsAroundInterceptor {
+
+
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] 
allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
+        HttpContext context = CONTEXT_LOCAL.get();
+        CONTEXT_LOCAL.remove();
+        if (context == null) {
+            return;
+        }
+        final ContextCarrier contextCarrier = new ContextCarrier();
+        HttpRequestWrapper requestWrapper = (HttpRequestWrapper) 
context.getAttribute(HttpClientContext.HTTP_REQUEST);
+        HttpHost httpHost = (HttpHost) 
context.getAttribute(HttpClientContext.HTTP_TARGET_HOST);
+
+        RequestLine requestLine = requestWrapper.getRequestLine();
+        String uri = requestLine.getUri();
+        String operationName = uri.startsWith("http") ? new URL(uri).getPath() 
: uri;
+        int port = httpHost.getPort();
+        AbstractSpan span = ContextManager.createExitSpan(operationName, 
contextCarrier, httpHost.getHostName() + ":" + (port == -1 ? 80 : port));
+        span.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT);
+        Tags.URL.set(span, 
requestWrapper.getOriginal().getRequestLine().getUri());
+        Tags.HTTP.METHOD.set(span, requestLine.getMethod());
+        SpanLayer.asHttp(span);
+        CarrierItem next = contextCarrier.items();
+        while (next.hasNext()) {
+            next = next.next();
+            requestWrapper.setHeader(next.getHeadKey(), next.getHeadValue());
+        }
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable {
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
+
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncResponseConsumerInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncResponseConsumerInterceptor.java
deleted file mode 100644
index 2446652..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncResponseConsumerInterceptor.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.lang.reflect.Method;
-import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.tag.Tags;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
-import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
-
-/**
- * End a local span for  {@link 
org.apache.http.impl.nio.client.CloseableHttpAsyncClient#execute} called by
- * application.
- *
- * @author liyuntao
- */
-
-public class HttpAsyncResponseConsumerInterceptor implements 
InstanceMethodsAroundInterceptor {
-
-    @Override public void beforeMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
-
-        HttpAsyncRequestProducer producer = 
(HttpAsyncRequestProducer)allArguments[0];
-        String uri = producer.generateRequest().getRequestLine().getUri();
-        String requestMethod = 
producer.generateRequest().getRequestLine().getMethod();
-        AbstractSpan span = ContextManager.createLocalSpan("httpasyncclient/" 
+ method.getName());
-        Tags.HTTP.METHOD.set(span, requestMethod);
-        
span.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT).setLayer(SpanLayer.HTTP);
-        Tags.URL.set(span, uri);
-
-    }
-
-    @Override public Object afterMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Object ret) throws Throwable {
-        ContextManager.stopSpan();
-        return ret;
-    }
-
-    @Override public void handleMethodException(EnhancedInstance objInst, 
Method method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Throwable t) {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        activeSpan.errorOccurred();
-        activeSpan.log(t);
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpHostInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpHostInterceptor.java
deleted file mode 100644
index 02c096e..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpHostInterceptor.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.lang.reflect.Method;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.tag.Tags;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
-import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
-
-/**
- * End a local span for  {@link 
org.apache.http.impl.nio.client.CloseableHttpAsyncClient#execute} called by
- * application.
- *
- * @author liyuntao
- */
-
-public class HttpHostInterceptor implements InstanceMethodsAroundInterceptor {
-
-    @Override public void beforeMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
-
-        HttpHost producer = (HttpHost)allArguments[0];
-        String uri = producer.toURI();
-        AbstractSpan span = ContextManager.createLocalSpan("httpasyncclient/" 
+ method.getName());
-        
span.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT).setLayer(SpanLayer.HTTP);
-        Tags.HTTP.METHOD.set(span, 
((HttpRequest)allArguments[1]).getRequestLine().getMethod());
-        Tags.URL.set(span, uri);
-
-    }
-
-    @Override public Object afterMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Object ret) throws Throwable {
-        ContextManager.stopSpan();
-        return ret;
-    }
-
-    @Override public void handleMethodException(EnhancedInstance objInst, 
Method method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Throwable t) {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        activeSpan.errorOccurred();
-        activeSpan.log(t);
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ProcessResponseInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ProcessResponseInterceptor.java
deleted file mode 100644
index 1cfc1db..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ProcessResponseInterceptor.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.lang.reflect.Method;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
-import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
-
-/**
- * 1.End exit span.
- * 2.Create a local span of  callback.
- * 3.End local span:AsyncThread/execute.
- *
- * @author liyuntao
- */
-
-public class ProcessResponseInterceptor implements 
InstanceMethodsAroundInterceptor {
-
-    @Override public void beforeMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        String uri = activeSpan.getOperationName();
-        //stop exitSpan
-        ContextManager.stopSpan();
-        AbstractSpan localSpan = ContextManager.createLocalSpan("callback:" + 
uri);
-        
localSpan.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT).setLayer(SpanLayer.HTTP);
-    }
-
-    @Override public Object afterMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Object ret) throws Throwable {
-        //stop local span:callback
-        ContextManager.stopSpan();
-        //stop local span:AsyncThread/execute
-        ContextManager.stopSpan();
-
-        return ret;
-    }
-
-    @Override public void handleMethodException(EnhancedInstance objInst, 
Method method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Throwable t) {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        activeSpan.errorOccurred();
-        activeSpan.log(t);
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestCompleteInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestCompleteInterceptor.java
new file mode 100644
index 0000000..4862f54
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestCompleteInterceptor.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
+
+import org.apache.http.protocol.HttpContext;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import java.lang.reflect.Method;
+
+/**
+ * request ready(completed) so we can start our local thread span;
+ *
+ * @author lican
+ */
+public class SessionRequestCompleteInterceptor implements 
InstanceMethodsAroundInterceptor {
+
+    public static ThreadLocal<HttpContext> CONTEXT_LOCAL = new 
ThreadLocal<HttpContext>();
+
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] 
allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
+        Object[] array = (Object[]) objInst.getSkyWalkingDynamicField();
+        if (array == null || array.length == 0) {
+            return;
+        }
+        ContextSnapshot snapshot = (ContextSnapshot) array[0];
+        ContextManager.createLocalSpan("httpasyncclient/local");
+        if (snapshot != null) {
+            ContextManager.continued(snapshot);
+        }
+        CONTEXT_LOCAL.set((HttpContext) array[1]);
+
+
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable {
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
+
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestConstructorInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestConstructorInterceptor.java
new file mode 100644
index 0000000..63ce0e4
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestConstructorInterceptor.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
+
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+
+import static 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL;
+
+/**
+ * hold the snapshot in SkyWalkingDynamicField
+ * @author lican
+ */
+public class SessionRequestConstructorInterceptor implements 
InstanceConstructorInterceptor {
+    @Override
+    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
+        if (ContextManager.isActive()) {
+            ContextSnapshot snapshot = ContextManager.capture();
+            objInst.setSkyWalkingDynamicField(new Object[]{snapshot, 
CONTEXT_LOCAL.get()});
+        }
+        CONTEXT_LOCAL.remove();
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestImplIterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestFailInterceptor.java
similarity index 52%
rename from 
apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestImplIterceptor.java
rename to 
apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestFailInterceptor.java
index e5e3395..3954113 100644
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestImplIterceptor.java
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestFailInterceptor.java
@@ -1,54 +1,52 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.lang.reflect.Method;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
-
-/**
- * Set local span false When  connect to the remote host  failed .
- *
- * @author liyuntao
- */
-
-public class SessionRequestImplIterceptor implements 
InstanceMethodsAroundInterceptor {
-
-    @Override public void beforeMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        activeSpan.errorOccurred();
-
-    }
-
-    @Override public Object afterMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Object ret) throws Throwable {
-        return ret;
-    }
-
-    @Override public void handleMethodException(EnhancedInstance objInst, 
Method method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Throwable t) {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        activeSpan.errorOccurred();
-        activeSpan.log(t);
-    }
-}
\ No newline at end of file
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
+
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import java.lang.reflect.Method;
+
+import static 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL;
+
+/**
+ * when request fail to ready we should remove thread local in case of memory 
leak;
+ *
+ * @author lican
+ */
+public class SessionRequestFailInterceptor implements 
InstanceMethodsAroundInterceptor {
+
+
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] 
allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
+        //this means actual request will not started. so the span has not been 
created,we cannot log the status.
+        CONTEXT_LOCAL.remove();
+        objInst.setSkyWalkingDynamicField(null);
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable {
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
+
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SetResponseInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SetResponseInterceptor.java
deleted file mode 100644
index 65fd2b7..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SetResponseInterceptor.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.lang.reflect.Method;
-import org.apache.http.HttpResponse;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.tag.Tags;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
-
-/**
- * End exit span and create  a local span of  future/Callback.
- *
- * @author liyuntao
- */
-
-public class SetResponseInterceptor implements 
InstanceMethodsAroundInterceptor {
-
-    @Override public void beforeMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
-        if (null == allArguments[0]) {
-            return;
-        }
-        AbstractSpan span = ContextManager.activeSpan();
-        int statusCode = 
((HttpResponse)allArguments[0]).getStatusLine().getStatusCode();
-        if (statusCode >= 400) {
-            span.errorOccurred();
-            Tags.STATUS_CODE.set(span, Integer.toString(statusCode));
-        }
-
-    }
-
-    @Override public Object afterMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Object ret) throws Throwable {
-        return ret;
-    }
-
-    @Override public void handleMethodException(EnhancedInstance objInst, 
Method method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Throwable t) {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        activeSpan.errorOccurred();
-        activeSpan.log(t);
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SuccessInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SuccessInterceptor.java
deleted file mode 100644
index c9f0551..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SuccessInterceptor.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.lang.reflect.Method;
-import org.apache.http.nio.reactor.SessionRequest;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
-import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
-
-/**
- * Create a local sapn and passing ref accross thread by SessionRequest.
- *
- * @author liyuntao
- */
-
-public class SuccessInterceptor implements InstanceMethodsAroundInterceptor {
-
-    @Override public void beforeMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, MethodInterceptResult result) throws 
Throwable {
-        SessionRequest request = (SessionRequest)allArguments[0];
-        AbstractSpan localSpan = 
ContextManager.createLocalSpan("AsyncThread/execute");
-        
localSpan.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT).setLayer(SpanLayer.HTTP);
-        Object cacheValue = 
((EnhancedInstance)request).getSkyWalkingDynamicField();
-        ContextManager.continued((ContextSnapshot)cacheValue);
-
-    }
-
-    @Override public Object afterMethod(EnhancedInstance objInst, Method 
method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Object ret) throws Throwable {
-        return ret;
-    }
-
-    @Override public void handleMethodException(EnhancedInstance objInst, 
Method method, Object[] allArguments,
-        Class<?>[] argumentsTypes, Throwable t) {
-        AbstractSpan activeSpan = ContextManager.activeSpan();
-        activeSpan.errorOccurred();
-        activeSpan.log(t);
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/AbstractNIOConnPoolInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/AbstractNIOConnPoolInstrumentation.java
deleted file mode 100644
index 8a1ff20..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/AbstractNIOConnPoolInstrumentation.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.define;
-
-import net.bytebuddy.description.method.MethodDescription;
-import net.bytebuddy.matcher.ElementMatcher;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
-import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
-
-/**
- * {@link AbstractNIOConnPoolInstrumentation} presents that skywalking 
intercept
- * org.apache.http.nio.protocol.AbstractNIOConnPool#requestCompleted
- *
- * @author liyuntao
- */
-
-public class AbstractNIOConnPoolInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
-
-    private static final String ENHANCE_CLASS = 
"org.apache.http.nio.pool.AbstractNIOConnPool";
-    private static final String START_LOCAL_SUCCESS_INTERCEPT_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.SuccessInterceptor";
-
-    @Override
-    public ClassMatch enhanceClass() {
-        return byName(ENHANCE_CLASS);
-    }
-
-    @Override
-    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
-        return null;
-    }
-
-    @Override
-    protected InstanceMethodsInterceptPoint[] 
getInstanceMethodsInterceptPoints() {
-        return new InstanceMethodsInterceptPoint[] {
-
-            new InstanceMethodsInterceptPoint() {
-                @Override
-                public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                    return named("requestCompleted");
-                }
-
-                @Override
-                public String getMethodsInterceptor() {
-                    return START_LOCAL_SUCCESS_INTERCEPT_CLASS;
-                }
-
-                @Override
-                public boolean isOverrideArgs() {
-                    return false;
-                }
-            }
-
-        };
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/DefaultConnectingIOReactorInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/DefaultConnectingIOReactorInstrumentation.java
deleted file mode 100644
index 92cf49d..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/DefaultConnectingIOReactorInstrumentation.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.define;
-
-import net.bytebuddy.description.method.MethodDescription;
-import net.bytebuddy.matcher.ElementMatcher;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
-import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
-
-/**
- * {@link DefaultConnectingIOReactorInstrumentation} presents that skywalking 
intercepts
- * org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor#processEvent
- *
- * @author liyuntao
- */
-
-public class DefaultConnectingIOReactorInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
-
-    private static final String ENHANCE_CLASS = 
"org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor";
-    private static final String INTERCEPT_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.DefaultConnectingIOReactorIterceptor";
-    private static final String LOCAL_INTERCEPT_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.ConnectIterceptor";
-
-    @Override
-    public ClassMatch enhanceClass() {
-        return byName(ENHANCE_CLASS);
-    }
-
-    @Override
-    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
-        return null;
-    }
-
-    @Override
-    protected InstanceMethodsInterceptPoint[] 
getInstanceMethodsInterceptPoints() {
-        return new InstanceMethodsInterceptPoint[] {
-            new InstanceMethodsInterceptPoint() {
-                @Override
-                public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                    return named("processEvent");
-                }
-
-                @Override
-                public String getMethodsInterceptor() {
-                    return INTERCEPT_CLASS;
-                }
-
-                @Override
-                public boolean isOverrideArgs() {
-                    return false;
-                }
-            },
-            new InstanceMethodsInterceptPoint() {
-                @Override
-                public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                    return named("connect");
-                }
-
-                @Override
-                public String getMethodsInterceptor() {
-                    return LOCAL_INTERCEPT_CLASS;
-                }
-
-                @Override
-                public boolean isOverrideArgs() {
-                    return false;
-                }
-            }
-        };
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ExecuteInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ExecuteInstrumentation.java
deleted file mode 100644
index 51bcd9a..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ExecuteInstrumentation.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.define;
-
-import net.bytebuddy.description.method.MethodDescription;
-import net.bytebuddy.matcher.ElementMatcher;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
-import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
-import static 
org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
-import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
-
-/**
- * {@link ExecuteInstrumentation} presents that skywalking intercepts 
org.apache.http.impl.nio.client.CloseableHttpAsyncClient#execute
- *
- * @author liyuntao
- */
-
-public class ExecuteInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
-
-    private static final String ENHANCE_CLASS = 
"org.apache.http.impl.nio.client.CloseableHttpAsyncClient";
-    private static final String CONSUMER_INTERCEPT_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.HttpAsyncResponseConsumerInterceptor";
-    private static final String HOST_INTERCEPT_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.HttpHostInterceptor";
-
-    @Override
-    public ClassMatch enhanceClass() {
-        return byName(ENHANCE_CLASS);
-    }
-
-    @Override
-    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
-        return null;
-    }
-
-    @Override
-    protected InstanceMethodsInterceptPoint[] 
getInstanceMethodsInterceptPoints() {
-        return new InstanceMethodsInterceptPoint[] {
-            new InstanceMethodsInterceptPoint() {
-                @Override
-                public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                    return named("execute").and(takesArgumentWithType(0, 
"org.apache.http.nio.protocol.HttpAsyncRequestProducer")).and(takesArguments(3));
-                }
-
-                @Override
-                public String getMethodsInterceptor() {
-                    return CONSUMER_INTERCEPT_CLASS;
-                }
-
-                @Override
-                public boolean isOverrideArgs() {
-                    return false;
-                }
-            },
-            new InstanceMethodsInterceptPoint() {
-                @Override
-                public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                    return 
named("execute").and(takesArguments(4)).and(takesArgumentWithType(0, 
"org.apache.http.HttpHost"));
-                }
-
-                @Override
-                public String getMethodsInterceptor() {
-                    return HOST_INTERCEPT_CLASS;
-                }
-
-                @Override
-                public boolean isOverrideArgs() {
-                    return false;
-                }
-            }
-        };
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncClientInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncClientInstrumentation.java
new file mode 100644
index 0000000..72aaf04
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncClientInstrumentation.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+import org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.*;
+
+/**
+ * {@link HttpAsyncClientInstrumentation} indicates that the execute method in 
both 
org.apache.http.impl.nio.client.MinimalHttpAsyncClient#execute(HttpAsyncRequestProducer,
 HttpAsyncResponseConsumer, HttpContext, FutureCallback)
+ * and InternalHttpAsyncClient#execute(HttpAsyncRequestProducer, 
HttpAsyncResponseConsumer, HttpContext, FutureCallback) can be instrumented for 
single request.pipeline is not support now for some
+ * complex situation.this is run in main thread.
+ *
+ * @author lican
+ */
+public class HttpAsyncClientInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
+
+    private static final String ENHANCE_CLASS_MINIMAL = 
"org.apache.http.impl.nio.client.MinimalHttpAsyncClient";
+    private static final String ENHANCE_CLASS_INTERNAL = 
"org.apache.http.impl.nio.client.InternalHttpAsyncClient";
+    private static final String METHOD = "execute";
+    private static final String INTERCEPTOR_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.HttpAsyncClientInterceptor";
+    private static final String FIRST_ARG_TYPE = 
"org.apache.http.nio.protocol.HttpAsyncRequestProducer";
+
+    @Override
+    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return null;
+    }
+
+    @Override
+    protected InstanceMethodsInterceptPoint[] 
getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[]{new 
InstanceMethodsInterceptPoint() {
+            @Override
+            public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                return named(METHOD).and(takesArguments(4)
+                        .and(takesArgument(0, named(FIRST_ARG_TYPE))));
+            }
+
+            @Override
+            public String getMethodsInterceptor() {
+                return INTERCEPTOR_CLASS;
+            }
+
+            @Override
+            public boolean isOverrideArgs() {
+                return true;
+            }
+        }
+        };
+    }
+
+    @Override
+    protected ClassMatch enhanceClass() {
+        return MultiClassNameMatch.byMultiClassMatch(ENHANCE_CLASS_MINIMAL, 
ENHANCE_CLASS_INTERNAL);
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ProcessResponseInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncRequestExecutorInstrumentation.java
similarity index 63%
rename from 
apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ProcessResponseInstrumentation.java
rename to 
apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncRequestExecutorInstrumentation.java
index 9bd8708..ae14bd3 100644
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ProcessResponseInstrumentation.java
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncRequestExecutorInstrumentation.java
@@ -1,73 +1,71 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.define;
-
-import net.bytebuddy.description.method.MethodDescription;
-import net.bytebuddy.matcher.ElementMatcher;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
-import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
-
-/**
- * {@link ProcessResponseInstrumentation} presents that skywalking intercept
- * org.apache.http.nio.protocol.HttpAsyncRequestExecutor#processResponse and 
#connected
- *
- * @author liyuntao
- */
-public class ProcessResponseInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
-
-    private static final String ENHANCE_CLASS = 
"org.apache.http.nio.protocol.HttpAsyncRequestExecutor";
-    private static final String END_EXIT_INTERCEPT_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.ProcessResponseInterceptor";
-
-    @Override
-    public ClassMatch enhanceClass() {
-        return byName(ENHANCE_CLASS);
-    }
-
-    @Override
-    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
-        return null;
-    }
-
-    @Override
-    protected InstanceMethodsInterceptPoint[] 
getInstanceMethodsInterceptPoints() {
-        return new InstanceMethodsInterceptPoint[] {
-            new InstanceMethodsInterceptPoint() {
-                @Override
-                public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                    return named("processResponse");
-                }
-
-                @Override
-                public String getMethodsInterceptor() {
-                    return END_EXIT_INTERCEPT_CLASS;
-                }
-
-                @Override
-                public boolean isOverrideArgs() {
-                    return false;
-                }
-            }
-
-        };
-    }
-}
\ No newline at end of file
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+/**
+ * {@link HttpAsyncRequestExecutorInstrumentation} indicates the real request 
start location in method requestReady
+ *
+ * @author lican
+ */
+public class HttpAsyncRequestExecutorInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
+
+    private static final String ENHANCE_CLASS = 
"org.apache.http.nio.protocol.HttpAsyncRequestExecutor";
+    private static final String METHOD = "requestReady";
+    private static final String INTERCEPTOR_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.HttpAsyncRequestExecutorInterceptor";
+
+    @Override
+    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return null;
+    }
+
+    @Override
+    protected InstanceMethodsInterceptPoint[] 
getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[]{new 
InstanceMethodsInterceptPoint() {
+            @Override
+            public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                return named(METHOD);
+            }
+
+            @Override
+            public String getMethodsInterceptor() {
+                return INTERCEPTOR_CLASS;
+            }
+
+            @Override
+            public boolean isOverrideArgs() {
+                return false;
+            }
+        }
+        };
+    }
+
+    @Override
+    protected ClassMatch enhanceClass() {
+        return byName(ENHANCE_CLASS);
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestImplInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestImplInstrumentation.java
deleted file mode 100644
index a36f3bd..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestImplInstrumentation.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.define;
-
-import java.io.IOException;
-import net.bytebuddy.description.method.MethodDescription;
-import net.bytebuddy.matcher.ElementMatcher;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
-import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
-
-/**
- * {@link SessionRequestImplInstrumentation} presents that skywalking 
intercepts
- * {@link 
org.apache.http.impl.nio.reactor.SessionRequestImpl#failed(IOException)} }
- *
- * @author liyuntao
- */
-
-public class SessionRequestImplInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
-
-    private static final String ENHANCE_CLASS = 
"org.apache.http.impl.nio.reactor.SessionRequestImpl";
-    private static final String INTERCEPT_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestImplIterceptor";
-
-    @Override
-    public ClassMatch enhanceClass() {
-        return byName(ENHANCE_CLASS);
-    }
-
-    @Override
-    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
-        return null;
-    }
-
-    @Override
-    protected InstanceMethodsInterceptPoint[] 
getInstanceMethodsInterceptPoints() {
-        return new InstanceMethodsInterceptPoint[] {
-            new InstanceMethodsInterceptPoint() {
-                @Override
-                public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                    return named("failed");
-                }
-
-                @Override
-                public String getMethodsInterceptor() {
-                    return INTERCEPT_CLASS;
-                }
-
-                @Override
-                public boolean isOverrideArgs() {
-                    return false;
-                }
-            }
-        };
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestInstrumentation.java
new file mode 100644
index 0000000..2e53747
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestInstrumentation.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.any;
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+/**
+ * this is a bridge for main thread and real request thread which mean hold 
the {@link org.apache.skywalking.apm.agent.core.context.ContextSnapshot} object 
to be continued
+ * in "completed" method.that is mean the request is ready to submit
+ *
+ * @author lican
+ */
+public class SessionRequestInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
+
+    private static final String CONSTRUCTOR_INTERCEPTOR_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestConstructorInterceptor";
+    private static final String COMPLETED_METHOD = "completed";
+    private static final String TIMEOUT_METHOD = "timeout";
+    private static final String FAILED_METHOD = "failed";
+    private static final String CANCEL_METHOD = "cancel";
+    private static final String SUCCESS_INTERCEPTOR_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor";
+    private static final String FAIL_INTERCEPTOR_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestFailInterceptor";
+    private static final String ENHANCE_CLASS = 
"org.apache.http.impl.nio.reactor.SessionRequestImpl";
+
+    @Override
+    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[]{new ConstructorInterceptPoint() 
{
+            @Override
+            public ElementMatcher<MethodDescription> getConstructorMatcher() {
+                return any();
+            }
+
+            @Override
+            public String getConstructorInterceptor() {
+                return CONSTRUCTOR_INTERCEPTOR_CLASS;
+            }
+        }
+        };
+    }
+
+    @Override
+    protected InstanceMethodsInterceptPoint[] 
getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[]{new 
InstanceMethodsInterceptPoint() {
+            @Override
+            public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                return named(COMPLETED_METHOD);
+            }
+
+            @Override
+            public String getMethodsInterceptor() {
+                return SUCCESS_INTERCEPTOR_CLASS;
+            }
+
+            @Override
+            public boolean isOverrideArgs() {
+                return false;
+            }
+        },new InstanceMethodsInterceptPoint() {
+            @Override
+            public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                return 
named(TIMEOUT_METHOD).or(named(FAILED_METHOD).or(named(CANCEL_METHOD)));
+            }
+
+            @Override
+            public String getMethodsInterceptor() {
+                return FAIL_INTERCEPTOR_CLASS;
+            }
+
+            @Override
+            public boolean isOverrideArgs() {
+                return false;
+            }
+        }
+        };
+    }
+
+    @Override
+    protected ClassMatch enhanceClass() {
+        return byName(ENHANCE_CLASS);
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/StateInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/StateInstrumentation.java
deleted file mode 100644
index 8da43e5..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/StateInstrumentation.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.define;
-
-import net.bytebuddy.description.method.MethodDescription;
-import net.bytebuddy.matcher.ElementMatcher;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
-import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
-
-/**
- * {@link StateInstrumentation} presents that skywalking intercept  
org.apache.http.nio.protocol.HttpAsyncRequestExecutor$State#setRequest
- *
- * @author liyuntao
- */
-
-public class StateInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
-
-    private static final String ENHANCE_CLASS = 
"org.apache.http.nio.protocol.HttpAsyncRequestExecutor$State";
-    private static final String START_EXIT_INTERCEPT_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.StateInterceptor";
-    private static final String END_EXIT_INTERCEPT_CLASS = 
"org.apache.skywalking.apm.plugin.httpasyncclient.v4.SetResponseInterceptor";
-
-    @Override
-    public ClassMatch enhanceClass() {
-        return byName(ENHANCE_CLASS);
-    }
-
-    @Override
-    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
-        return null;
-    }
-
-    @Override
-    protected InstanceMethodsInterceptPoint[] 
getInstanceMethodsInterceptPoints() {
-        return new InstanceMethodsInterceptPoint[] {
-            new InstanceMethodsInterceptPoint() {
-                @Override
-                public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                    return named("setRequest");
-                }
-
-                @Override
-                public String getMethodsInterceptor() {
-                    return START_EXIT_INTERCEPT_CLASS;
-                }
-
-                @Override
-                public boolean isOverrideArgs() {
-                    return false;
-                }
-            },
-            new InstanceMethodsInterceptPoint() {
-                @Override
-                public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                    return named("setResponse");
-                }
-
-                @Override
-                public String getMethodsInterceptor() {
-                    return END_EXIT_INTERCEPT_CLASS;
-                }
-
-                @Override
-                public boolean isOverrideArgs() {
-                    return false;
-                }
-            }
-
-        };
-    }
-}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/FutureCallbackWrapper.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/FutureCallbackWrapper.java
new file mode 100644
index 0000000..316009f
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/FutureCallbackWrapper.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.wrapper;
+
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+
+import static 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL;
+
+/**
+ * a wrapper for {@link FutureCallback} so we can be notified when the hold 
response
+ * (when one or more request fails the pipeline mode may not callback though 
we haven't support pipeline)
+ * received whether it fails or completed or canceled.
+ * @author lican
+ */
+public class FutureCallbackWrapper<T> implements FutureCallback<T> {
+
+    private FutureCallback<T> callback;
+
+    public FutureCallbackWrapper(FutureCallback<T> callback) {
+        this.callback = callback;
+    }
+
+    @Override
+    public void completed(T o) {
+        if (ContextManager.isActive()) {
+            ContextManager.stopSpan();
+        }
+        if (callback != null) {
+            callback.completed(o);
+        }
+    }
+
+    @Override
+    public void failed(Exception e) {
+        CONTEXT_LOCAL.remove();
+        if (ContextManager.isActive()) {
+            ContextManager.activeSpan().errorOccurred().log(e);
+            ContextManager.stopSpan();
+        }
+        if (callback != null) {
+            callback.failed(e);
+        }
+    }
+
+    @Override
+    public void cancelled() {
+        CONTEXT_LOCAL.remove();
+        if (ContextManager.isActive()) {
+            ContextManager.activeSpan().errorOccurred();
+            ContextManager.stopSpan();
+        }
+        if (callback != null) {
+            callback.cancelled();
+        }
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/HttpAsyncResponseConsumerWrapper.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/HttpAsyncResponseConsumerWrapper.java
new file mode 100644
index 0000000..b9363e8
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/HttpAsyncResponseConsumerWrapper.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4.wrapper;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpResponse;
+import org.apache.http.nio.ContentDecoder;
+import org.apache.http.nio.IOControl;
+import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
+import org.apache.http.protocol.HttpContext;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+
+import java.io.IOException;
+
+import static 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL;
+
+/**
+ * a wrapper for {@link HttpAsyncResponseConsumer} so we can be notified when 
the
+ * current response(every response will callback the wrapper) received maybe 
completed or canceled,or failed.
+ *
+ * @author lican
+ */
+public class HttpAsyncResponseConsumerWrapper<T> implements 
HttpAsyncResponseConsumer<T> {
+
+    private HttpAsyncResponseConsumer<T> consumer;
+
+    public HttpAsyncResponseConsumerWrapper(HttpAsyncResponseConsumer<T> 
consumer) {
+        this.consumer = consumer;
+    }
+
+    @Override
+    public void responseReceived(HttpResponse response) throws IOException, 
HttpException {
+        if (ContextManager.isActive()) {
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode > 400) {
+                AbstractSpan span = ContextManager.activeSpan();
+                Tags.STATUS_CODE.set(span, String.valueOf(statusCode));
+            }
+            ContextManager.stopSpan();
+        }
+        consumer.responseReceived(response);
+    }
+
+    @Override
+    public void consumeContent(ContentDecoder decoder, IOControl ioctrl) 
throws IOException {
+        consumer.consumeContent(decoder, ioctrl);
+    }
+
+    @Override
+    public void responseCompleted(HttpContext context) {
+        consumer.responseCompleted(context);
+    }
+
+    @Override
+    public void failed(Exception ex) {
+        CONTEXT_LOCAL.remove();
+        if (ContextManager.isActive()) {
+            ContextManager.activeSpan().errorOccurred().log(ex);
+            ContextManager.stopSpan();
+        }
+        consumer.failed(ex);
+
+    }
+
+    @Override
+    public Exception getException() {
+        return consumer.getException();
+    }
+
+    @Override
+    public T getResult() {
+        return consumer.getResult();
+    }
+
+    @Override
+    public boolean isDone() {
+        return consumer.isDone();
+    }
+
+    @Override
+    public void close() throws IOException {
+        consumer.close();
+    }
+
+    @Override
+    public boolean cancel() {
+        CONTEXT_LOCAL.remove();
+        if (ContextManager.isActive()) {
+            ContextManager.activeSpan().errorOccurred();
+            ContextManager.stopSpan();
+        }
+        return consumer.cancel();
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/resources/skywalking-plugin.def
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/resources/skywalking-plugin.def
index 98e3da4..d3153bc 100644
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/resources/skywalking-plugin.def
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/resources/skywalking-plugin.def
@@ -14,11 +14,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.ExecuteInstrumentation
-httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.DefaultConnectingIOReactorInstrumentation
-httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.SessionRequestImplInstrumentation
-httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.AbstractNIOConnPoolInstrumentation
-httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.StateInstrumentation
-httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.ProcessResponseInstrumentation
+httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.HttpAsyncClientInstrumentation
+httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.SessionRequestInstrumentation
+httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.HttpAsyncRequestExecutorInstrumentation
 
 
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptorTest.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptorTest.java
new file mode 100644
index 0000000..03f7f16
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptorTest.java
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
+
+import org.apache.http.*;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpRequestWrapper;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
+import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
+import org.apache.skywalking.apm.agent.core.context.util.KeyValuePair;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
+import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
+import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
+import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
+import 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.wrapper.FutureCallbackWrapper;
+import 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.wrapper.HttpAsyncResponseConsumerWrapper;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+
+import java.util.List;
+
+import static 
org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.*;
+
+/**
+ * @author lican
+ */
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(TracingSegmentRunner.class)
+@PrepareForTest(HttpHost.class)
+public class HttpAsyncClientInterceptorTest {
+
+    @SegmentStoragePoint
+    private SegmentStorage segmentStorage;
+
+    @Rule
+    public AgentServiceRule agentServiceRule = new AgentServiceRule();
+
+    private EnhancedInstance enhancedInstance;
+
+    private HttpAsyncClientInterceptor httpAsyncClientInterceptor;
+
+    private HttpAsyncRequestExecutorInterceptor requestExecutorInterceptor;
+
+    private SessionRequestConstructorInterceptor 
sessionRequestConstructorInterceptor;
+
+    private SessionRequestCompleteInterceptor completeInterceptor;
+
+    @Mock
+    private HttpAsyncRequestProducer producer;
+
+    @Mock
+    private HttpAsyncResponseConsumer consumer;
+
+    @Mock
+    private HttpContext httpContext;
+
+    @Mock
+    private FutureCallback callback;
+
+    @Mock
+    private HttpRequestWrapper requestWrapper;
+
+    @Mock
+    private HttpHost httpHost;
+
+    @Mock
+    private HttpResponse response;
+
+    @Before
+    public void setUp() throws Exception {
+        ServiceManager.INSTANCE.boot();
+        httpAsyncClientInterceptor = new HttpAsyncClientInterceptor();
+        requestExecutorInterceptor = new HttpAsyncRequestExecutorInterceptor();
+        sessionRequestConstructorInterceptor = new 
SessionRequestConstructorInterceptor();
+        completeInterceptor = new SessionRequestCompleteInterceptor();
+
+        httpContext = new BasicHttpContext();
+        httpContext.setAttribute(HttpClientContext.HTTP_REQUEST, 
requestWrapper);
+        httpContext.setAttribute(HttpClientContext.HTTP_TARGET_HOST, httpHost);
+        CONTEXT_LOCAL.set(httpContext);
+        when(httpHost.getHostName()).thenReturn("127.0.0.1");
+        when(httpHost.getSchemeName()).thenReturn("http");
+
+
+        final RequestLine requestLine = new RequestLine() {
+            @Override
+            public String getMethod() {
+                return "GET";
+            }
+
+            @Override
+            public ProtocolVersion getProtocolVersion() {
+                return new ProtocolVersion("http", 1, 1);
+            }
+
+            @Override
+            public String getUri() {
+                return "http://127.0.0.1:8080/test-web/test";;
+            }
+        };
+
+        when(response.getStatusLine()).thenReturn(new StatusLine() {
+            @Override
+            public ProtocolVersion getProtocolVersion() {
+                return new ProtocolVersion("http", 1, 1);
+            }
+
+            @Override
+            public int getStatusCode() {
+                return 200;
+            }
+
+            @Override
+            public String getReasonPhrase() {
+                return null;
+            }
+        });
+
+        when(requestWrapper.getRequestLine()).thenReturn(requestLine);
+        when(requestWrapper.getOriginal()).thenReturn(new 
HttpGet("http://localhost:8081/original/test";));
+        when(httpHost.getPort()).thenReturn(8080);
+
+        enhancedInstance = new EnhancedInstance() {
+
+            private Object object;
+
+            @Override
+            public Object getSkyWalkingDynamicField() {
+                return object;
+            }
+
+            @Override
+            public void setSkyWalkingDynamicField(Object value) {
+                this.object = value;
+            }
+        };
+    }
+
+    @Test
+    public void testSuccess() throws Throwable {
+
+        //mock active span;
+        ContextManager.createEntrySpan("mock-test", new ContextCarrier());
+
+        Thread thread = baseTest();
+
+        ContextManager.stopSpan();
+
+        thread.join();
+        Assert.assertThat(segmentStorage.getTraceSegments().size(), is(2));
+
+        List<AbstractTracingSpan> spans = 
SegmentHelper.getSpans(findNeedSegemnt());
+        assertHttpSpan(spans.get(0));
+        verify(requestWrapper, times(1)).setHeader(anyString(), anyString());
+
+
+    }
+
+    @Test
+    public void testNoContext() throws Throwable {
+
+        Thread thread = baseTest();
+        thread.join();
+
+        Assert.assertThat(segmentStorage.getTraceSegments().size(), is(0));
+
+        verify(requestWrapper, times(0)).setHeader(anyString(), anyString());
+
+
+    }
+
+    private Thread baseTest() throws Throwable {
+        Object[] allArguments = new Object[]{producer, consumer, httpContext, 
callback};
+        Class[] types = new Class[]{HttpAsyncRequestProducer.class, 
HttpAsyncResponseConsumer.class, HttpContext.class, FutureCallback.class};
+        httpAsyncClientInterceptor.beforeMethod(enhancedInstance, null, 
allArguments, types, null);
+        Assert.assertEquals(CONTEXT_LOCAL.get(), httpContext);
+        Assert.assertTrue(allArguments[1] instanceof 
HttpAsyncResponseConsumerWrapper);
+        Assert.assertTrue(allArguments[3] instanceof FutureCallbackWrapper);
+
+        sessionRequestConstructorInterceptor.onConstruct(enhancedInstance, 
null);
+
+        Thread thread = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    //start local
+                    completeInterceptor.beforeMethod(enhancedInstance, null, 
null, null, null);
+                    //start request
+                    requestExecutorInterceptor.beforeMethod(enhancedInstance, 
null, null, null, null);
+
+                    HttpAsyncResponseConsumerWrapper consumerWrapper = new 
HttpAsyncResponseConsumerWrapper(consumer);
+
+                    consumerWrapper.responseReceived(response);
+
+                    new FutureCallbackWrapper(callback).completed(null);
+
+                } catch (Throwable throwable) {
+                    throwable.printStackTrace();
+                }
+            }
+        });
+        thread.start();
+        return thread;
+    }
+
+    private TraceSegment findNeedSegemnt() {
+        for (TraceSegment traceSegment : segmentStorage.getTraceSegments()) {
+            if (SegmentHelper.getSpans(traceSegment).size() > 1) {
+                return traceSegment;
+            }
+        }
+        return null;
+    }
+
+    private void assertHttpSpan(AbstractTracingSpan span) {
+        assertThat(span.getOperationName(), is("/test-web/test"));
+        assertThat(SpanHelper.getComponentId(span), is(26));
+        List<KeyValuePair> tags = SpanHelper.getTags(span);
+        assertThat(tags.get(0).getValue(), 
is("http://localhost:8081/original/test";));
+        assertThat(tags.get(1).getValue(), is("GET"));
+        assertThat(span.isExit(), is(true));
+    }
+
+    @Test
+    public void afterMethod() throws Throwable {
+        baseCompleteTest(completeInterceptor);
+        baseCompleteTest(httpAsyncClientInterceptor);
+        baseCompleteTest(requestExecutorInterceptor);
+    }
+
+    private void baseCompleteTest(InstanceMethodsAroundInterceptor 
instanceMethodsAroundInterceptor) throws Throwable {
+        Object ret = new Object();
+        Object result = 
instanceMethodsAroundInterceptor.afterMethod(enhancedInstance, null, null, 
null, ret);
+        Assert.assertEquals(ret, result);
+    }
+}
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptorTest.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptorTest.java
deleted file mode 100644
index 05a33f2..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptorTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.util.List;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.RequestLine;
-import org.apache.http.StatusLine;
-import org.apache.http.client.methods.HttpRequestWrapper;
-import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
-import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
-import org.apache.skywalking.apm.agent.core.context.util.KeyValuePair;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
-import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
-import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
-import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
-import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
-import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.modules.junit4.PowerMockRunnerDelegate;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@RunWith(PowerMockRunner.class)
-@PowerMockRunnerDelegate(TracingSegmentRunner.class)
-@PrepareForTest(HttpHost.class)
-public class StateInterceptorTest {
-
-    @SegmentStoragePoint
-    private SegmentStorage segmentStorage;
-
-    @Rule
-    public AgentServiceRule agentServiceRule = new AgentServiceRule();
-
-    private StateInterceptor stateInterceptor;
-
-    private SetResponseInterceptor setResponseInterceptor;
-
-    private ProcessResponseInterceptor processResponseInterceptor;
-    @Mock
-    private HttpHost httpHost;
-    @Mock
-    private HttpRequestWrapper request;
-    @Mock
-    private HttpRequest httpRequest;
-    @Mock
-    private HttpResponse httpResponse;
-    @Mock
-    private StatusLine statusLine;
-
-    private Object[] allArguments;
-    private Class[] argumentsType;
-
-    @Mock
-    private EnhancedInstance enhancedInstance;
-
-    @Before
-    public void setUp() throws Exception {
-        ServiceManager.INSTANCE.boot();
-        stateInterceptor = new StateInterceptor();
-        setResponseInterceptor = new SetResponseInterceptor();
-        processResponseInterceptor = new ProcessResponseInterceptor();
-
-        PowerMockito.mock(HttpHost.class);
-        when(statusLine.getStatusCode()).thenReturn(200);
-        when(httpResponse.getStatusLine()).thenReturn(statusLine);
-        when(httpHost.getHostName()).thenReturn("127.0.0.1");
-        when(httpHost.getSchemeName()).thenReturn("http");
-        when(request.getOriginal()).thenReturn(httpRequest);
-        when(httpRequest.getRequestLine()).thenReturn(new RequestLine() {
-            @Override
-            public String getMethod() {
-                return "GET";
-            }
-
-            @Override
-            public ProtocolVersion getProtocolVersion() {
-                return new ProtocolVersion("http", 1, 1);
-            }
-
-            @Override
-            public String getUri() {
-                return "http://127.0.0.1:8080/test-web/httpasync";;
-            }
-        });
-        when(httpHost.getPort()).thenReturn(8080);
-
-        allArguments = new Object[] {request};
-        argumentsType = new Class[] {request.getClass()};
-    }
-
-    @Test
-    public void testHttpClient() throws Throwable {
-        AbstractSpan span = 
ContextManager.createLocalSpan("httpasyncclient/HttpAsyncRequestExecutor:");
-        stateInterceptor.beforeMethod(enhancedInstance, null, allArguments, 
argumentsType, null);
-        stateInterceptor.afterMethod(enhancedInstance, null, allArguments, 
argumentsType, httpResponse);
-        processResponseInterceptor.beforeMethod(enhancedInstance, null, 
allArguments, argumentsType, null);
-        processResponseInterceptor.afterMethod(enhancedInstance, null, 
allArguments, argumentsType, httpResponse);
-        Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1));
-        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
-
-        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
-        assertHttpSpan(spans.get(0));
-        verify(request, times(1)).setHeader(anyString(), anyString());
-    }
-
-    @Test
-    public void testStatusCodeNotEquals200() throws Throwable {
-        when(statusLine.getStatusCode()).thenReturn(500);
-        AbstractSpan span = 
ContextManager.createLocalSpan("httpasyncclient/HttpAsyncRequestExecutor:");
-        stateInterceptor.beforeMethod(enhancedInstance, null, allArguments, 
argumentsType, null);
-        stateInterceptor.afterMethod(enhancedInstance, null, allArguments, 
argumentsType, httpResponse);
-        allArguments = new Object[] {httpResponse};
-        setResponseInterceptor.beforeMethod(enhancedInstance, null, 
allArguments, argumentsType, null);
-        setResponseInterceptor.afterMethod(enhancedInstance, null, 
allArguments, argumentsType, httpResponse);
-        processResponseInterceptor.beforeMethod(enhancedInstance, null, 
allArguments, argumentsType, null);
-        processResponseInterceptor.afterMethod(enhancedInstance, null, 
allArguments, argumentsType, httpResponse);
-
-        Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1));
-        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
-        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
-
-        assertThat(spans.size(), is(3));
-
-        List<KeyValuePair> tags = SpanHelper.getTags(spans.get(0));
-        assertThat(tags.size(), is(3));
-        assertThat(tags.get(2).getValue(), is("500"));
-
-        assertHttpSpan(spans.get(0));
-        assertThat(SpanHelper.getErrorOccurred(spans.get(0)), is(true));
-        verify(request, times(1)).setHeader(anyString(), anyString());
-    }
-
-    private void assertHttpSpan(AbstractTracingSpan span) {
-        assertThat(span.getOperationName(), is("/test-web/httpasync"));
-        assertThat(SpanHelper.getComponentId(span), is(26));
-        List<KeyValuePair> tags = SpanHelper.getTags(span);
-        assertThat(tags.get(0).getValue(), 
is("http://127.0.0.1:8080/test-web/httpasync";));
-        assertThat(tags.get(1).getValue(), is("GET"));
-        assertThat(span.isExit(), is(true));
-    }
-
-}
diff --git 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/TestException.java
 
b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/TestException.java
deleted file mode 100644
index 9923001..0000000
--- 
a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/TestException.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.httpasyncclient.v4;
-
-import java.util.List;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.RequestLine;
-import org.apache.http.StatusLine;
-import org.apache.http.client.methods.HttpRequestWrapper;
-import org.apache.skywalking.apm.agent.core.context.ContextManager;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
-import org.hamcrest.CoreMatchers;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.modules.junit4.PowerMockRunnerDelegate;
-import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
-import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
-import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
-import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
-import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
-import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
-import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
-import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
-
-import static junit.framework.TestCase.assertNotNull;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-/**
- * @auther lytscu
- */
-@RunWith(PowerMockRunner.class)
-@PowerMockRunnerDelegate(TracingSegmentRunner.class)
-@PrepareForTest(HttpHost.class)
-public class TestException {
-    @SegmentStoragePoint
-    private SegmentStorage segmentStorage;
-
-    @Rule
-    public AgentServiceRule agentServiceRule = new AgentServiceRule();
-
-    private StateInterceptor stateInterceptor;
-
-    private SetResponseInterceptor setResponseInterceptor;
-
-    private ProcessResponseInterceptor processResponseInterceptor;
-    @Mock
-    private HttpHost httpHost;
-    @Mock
-    private HttpRequestWrapper request;
-    @Mock
-    private HttpRequest httpRequest;
-    @Mock
-    private HttpResponse httpResponse;
-    @Mock
-    private StatusLine statusLine;
-
-    private Object[] allArguments, setResponseInterceptorArguments;
-    private Class[] argumentsType;
-
-    @Mock
-    private EnhancedInstance enhancedInstance;
-
-    @Before
-    public void setUp() throws Exception {
-        ServiceManager.INSTANCE.boot();
-        stateInterceptor = new StateInterceptor();
-        setResponseInterceptor = new SetResponseInterceptor();
-        processResponseInterceptor = new ProcessResponseInterceptor();
-        PowerMockito.mock(HttpHost.class);
-        when(statusLine.getStatusCode()).thenReturn(200);
-        when(httpResponse.getStatusLine()).thenReturn(statusLine);
-        when(httpHost.getHostName()).thenReturn("127.0.0.1");
-        when(httpHost.getSchemeName()).thenReturn("http");
-        when(request.getOriginal()).thenReturn(httpRequest);
-        when(httpRequest.getRequestLine()).thenReturn(new RequestLine() {
-            @Override
-            public String getMethod() {
-                return "GET";
-            }
-
-            @Override
-            public ProtocolVersion getProtocolVersion() {
-                return new ProtocolVersion("http", 1, 1);
-            }
-
-            @Override
-            public String getUri() {
-                return "http://127.0.0.1:8080/test-web/httpasync";;
-            }
-        });
-        when(httpHost.getPort()).thenReturn(8080);
-
-        allArguments = new Object[] {request};
-        setResponseInterceptorArguments = new Object[] {httpResponse};
-        argumentsType = new Class[] {request.getClass()};
-    }
-
-    @Test
-    public void testHttpClientWithException() throws Throwable {
-        AbstractSpan localSpan = 
ContextManager.createLocalSpan("httpasyncclient/HttpAsyncRequestExecutor:");
-        stateInterceptor.beforeMethod(enhancedInstance, null, allArguments, 
argumentsType, null);
-        stateInterceptor.handleMethodException(enhancedInstance, null, 
allArguments, argumentsType, new RuntimeException("testException"));
-        processResponseInterceptor.beforeMethod(enhancedInstance, null, 
allArguments, argumentsType, null);
-        processResponseInterceptor.afterMethod(enhancedInstance, null, 
allArguments, argumentsType, httpResponse);
-        Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1));
-        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
-        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
-
-        assertThat(spans.size(), is(3));
-        AbstractTracingSpan span = spans.get(0);
-        assertThat(SpanHelper.getErrorOccurred(span), is(true));
-        assertHttpSpanErrorLog(SpanHelper.getLogs(span));
-        verify(request, times(1)).setHeader(anyString(), anyString());
-
-    }
-
-    private void assertHttpSpanErrorLog(List<LogDataEntity> logs) {
-        assertThat(logs.size(), is(1));
-        LogDataEntity logData = logs.get(0);
-        Assert.assertThat(logData.getLogs().size(), is(4));
-        Assert.assertThat(logData.getLogs().get(0).getValue(), 
CoreMatchers.<Object>is("error"));
-        Assert.assertThat(logData.getLogs().get(1).getValue(), 
CoreMatchers.<Object>is(RuntimeException.class.getName()));
-        Assert.assertThat(logData.getLogs().get(2).getValue(), 
is("testException"));
-        assertNotNull(logData.getLogs().get(3).getValue());
-    }
-}

-- 
To stop receiving notification emails like this one, please contact
wush...@apache.org.

Reply via email to