Merge pull request #178 from ascrutae/zhangxin/fix/150

Redis plugin cannot work on tomcat
diff --git a/skywalking-collector/skywalking-collector-worker/src/test/java/com/a/eye/skywalking/collector/worker/httpserver/AbstractPostTestCase.java b/skywalking-collector/skywalking-collector-worker/src/test/java/com/a/eye/skywalking/collector/worker/httpserver/AbstractPostTestCase.java
index 3c0bf7a..3e0ac3c 100644
--- a/skywalking-collector/skywalking-collector-worker/src/test/java/com/a/eye/skywalking/collector/worker/httpserver/AbstractPostTestCase.java
+++ b/skywalking-collector/skywalking-collector-worker/src/test/java/com/a/eye/skywalking/collector/worker/httpserver/AbstractPostTestCase.java
@@ -26,8 +26,8 @@
 
     @Before
     public void init() {
-        ClusterWorkerContext clusterWorkerContext = mock(ClusterWorkerContext.class);
-        LocalWorkerContext localWorkerContext = mock(LocalWorkerContext.class);
+        ClusterWorkerContext clusterWorkerContext = PowerMockito.mock(ClusterWorkerContext.class);
+        LocalWorkerContext localWorkerContext = PowerMockito.mock(LocalWorkerContext.class);
         post = spy(new TestAbstractPost(TestAbstractPost.WorkerRole.INSTANCE, clusterWorkerContext, localWorkerContext));
     }
 
diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/NoConcurrencyAccessObject.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/NoConcurrencyAccessObject.java
index 47a3d88..77b6128 100644
--- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/NoConcurrencyAccessObject.java
+++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/NoConcurrencyAccessObject.java
@@ -2,32 +2,35 @@
 
 import com.a.eye.skywalking.api.plugin.interceptor.EnhancedClassInstanceContext;
 import com.a.eye.skywalking.api.plugin.interceptor.InterceptorException;
+import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodInvokeContext;
 
 /**
  * {@link NoConcurrencyAccessObject} is method invocation counter,
- * when {@link #whenEnter(EnhancedClassInstanceContext, Runnable)}, counter + 1;
- * and when {@link #whenExist(EnhancedClassInstanceContext, Runnable)}, counter -1;
+ * when {@link #whenEnter(EnhancedClassInstanceContext, InstanceMethodInvokeContext)} , counter + 1;
+ * and when {@link #whenExist(EnhancedClassInstanceContext)}  , counter -1;
  *
- * When, and only when, the first enter and last exist, also meaning first access, the Runnable is called.
+ * When, and only when, the first enter and last exist, also meaning first access,
+ * the {@link #enter(EnhancedClassInstanceContext, InstanceMethodInvokeContext)}
+ * and {@link #exit()} are called.
  *
  * @author wusheng
  */
-public class NoConcurrencyAccessObject {
+public abstract class NoConcurrencyAccessObject {
     private static final String INVOKE_COUNTER_KEY = "__$invokeCounterKey";
 
-    public void whenEnter(EnhancedClassInstanceContext context, Runnable runnable) {
+    public void whenEnter(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
         if (!context.isContain(INVOKE_COUNTER_KEY)) {
             context.set(INVOKE_COUNTER_KEY, 0);
         }
         int counter = context.get(INVOKE_COUNTER_KEY,
             Integer.class);
         if (++counter == 1) {
-            runnable.run();
+            enter(context, interceptorContext);
         }
         context.set(INVOKE_COUNTER_KEY, counter);
     }
 
-    public void whenExist(EnhancedClassInstanceContext context, Runnable runnable) {
+    public void whenExist(EnhancedClassInstanceContext context) {
         if (!context.isContain(INVOKE_COUNTER_KEY)) {
             throw new InterceptorException(
                 "key=INVOKE_COUNTER_KEY not found is context. unexpected situation.");
@@ -35,8 +38,12 @@
         int counter = context.get(INVOKE_COUNTER_KEY,
             Integer.class);
         if (--counter == 0) {
-            runnable.run();
+            exit();
         }
         context.set(INVOKE_COUNTER_KEY, counter);
     }
+
+    protected abstract void enter(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext);
+
+    protected abstract void exit();
 }
diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/NoConcurrencyAccessObjectTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/NoConcurrencyAccessObjectTest.java
index fcd83db..91f2bc3 100644
--- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/NoConcurrencyAccessObjectTest.java
+++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/NoConcurrencyAccessObjectTest.java
@@ -2,41 +2,53 @@
 
 import com.a.eye.skywalking.api.plugin.interceptor.EnhancedClassInstanceContext;
 import com.a.eye.skywalking.api.plugin.interceptor.assist.NoConcurrencyAccessObject;
+import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodInvokeContext;
 import org.junit.Assert;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
 
 /**
  * @author wusheng
  */
+@RunWith(MockitoJUnitRunner.class)
 public class NoConcurrencyAccessObjectTest {
+
+    @Mock
+    private InstanceMethodInvokeContext invokeContext;
+
     @Test
     public void testEntraExitCounter() {
-        NoConcurrencyAccessObject object = new NoConcurrencyAccessObject();
         final EnhancedClassInstanceContext context = new EnhancedClassInstanceContext();
-        object.whenEnter(context, new Runnable() {
+        NoConcurrencyAccessObject first = new NoConcurrencyAccessObject(){
+
             @Override
-            public void run() {
+            protected void enter(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
                 context.set("firstEntrance", true);
             }
-        });
-        object.whenEnter(context, new Runnable() {
-            @Override
-            public void run() {
-                context.set("secondEntrance", true);
-            }
-        });
-        object.whenExist(context, new Runnable() {
-            @Override
-            public void run() {
+
+            @Override protected void exit() {
                 context.set("firstExit", true);
             }
-        });
-        object.whenExist(context, new Runnable() {
+        };
+
+        NoConcurrencyAccessObject second = new NoConcurrencyAccessObject(){
+
             @Override
-            public void run() {
+            protected void enter(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
+                context.set("secondEntrance", true);
+            }
+
+            @Override protected void exit() {
                 context.set("lastEntrance", true);
             }
-        });
+        };
+
+        first.whenEnter(context, invokeContext);
+        second.whenEnter(context, invokeContext);
+        first.whenExist(context);
+        second.whenExist(context);
 
         Assert.assertTrue(!context.isContain("secondEntrance"));
         Assert.assertTrue(!context.isContain("firstExit"));
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java b/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java
index b7f4012..9eca1fc 100644
--- a/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java
@@ -44,28 +44,7 @@
     @Override
     public void beforeMethod(final EnhancedClassInstanceContext context,
         final InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result) {
-        this.whenEnter(context, new Runnable() {
-            @Override
-            public void run() {
-                Span span = ContextManager.createSpan("Jedis/" + interceptorContext.methodName());
-                Tags.COMPONENT.set(span, REDIS_COMPONENT);
-                Tags.DB_TYPE.set(span, REDIS_COMPONENT);
-                Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT);
-                tagPeer(span, context);
-                Tags.SPAN_LAYER.asDB(span);
-                if (StringUtil.isEmpty(context.get(KEY_OF_REDIS_HOST, String.class))) {
-                    Tags.PEERS.set(span, String.valueOf(context.get(KEY_OF_REDIS_HOSTS)));
-                } else {
-                    Tags.PEER_HOST.set(span, context.get(KEY_OF_REDIS_HOST, String.class));
-                    Tags.PEER_PORT.set(span, (Integer)context.get(KEY_OF_REDIS_PORT));
-                }
-
-                if (interceptorContext.allArguments().length > 0
-                    && interceptorContext.allArguments()[0] instanceof String) {
-                    Tags.DB_STATEMENT.set(span, interceptorContext.methodName() + " " + interceptorContext.allArguments()[0]);
-                }
-            }
-        });
+        this.whenEnter(context, interceptorContext);
     }
 
     /**
@@ -84,12 +63,7 @@
     @Override
     public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
         Object ret) {
-        this.whenExist(context, new Runnable() {
-            @Override
-            public void run() {
-                ContextManager.stopSpan();
-            }
-        });
+        this.whenExist(context);
         return ret;
     }
 
@@ -98,4 +72,30 @@
         InstanceMethodInvokeContext interceptorContext) {
         ContextManager.activeSpan().log(t);
     }
+
+    @Override
+    protected void enter(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
+        Span span = ContextManager.createSpan("Jedis/" + interceptorContext.methodName());
+        Tags.COMPONENT.set(span, REDIS_COMPONENT);
+        Tags.DB_TYPE.set(span, REDIS_COMPONENT);
+        Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT);
+        tagPeer(span, context);
+        Tags.SPAN_LAYER.asDB(span);
+        if (StringUtil.isEmpty(context.get(KEY_OF_REDIS_HOST, String.class))) {
+            Tags.PEERS.set(span, String.valueOf(context.get(KEY_OF_REDIS_HOSTS)));
+        } else {
+            Tags.PEER_HOST.set(span, context.get(KEY_OF_REDIS_HOST, String.class));
+            Tags.PEER_PORT.set(span, (Integer)context.get(KEY_OF_REDIS_PORT));
+        }
+
+        if (interceptorContext.allArguments().length > 0
+            && interceptorContext.allArguments()[0] instanceof String) {
+            Tags.DB_STATEMENT.set(span, interceptorContext.methodName() + " " + interceptorContext.allArguments()[0]);
+        }
+    }
+
+    @Override
+    protected void exit() {
+        ContextManager.stopSpan();
+    }
 }