Fix ehcache: add interceptor for Cache's private constructor and setName method
This commit is contained in:
parent
ff76951d01
commit
e57176d05e
|
|
@ -18,35 +18,29 @@
|
|||
|
||||
package org.apache.skywalking.apm.plugin.ehcache.v2;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.config.CacheConfiguration;
|
||||
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;
|
||||
|
||||
public class EhcacheCloneInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
public class EhcacheCacheNameInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
|
||||
|
||||
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 {
|
||||
if (ret == null) {
|
||||
return null;
|
||||
}
|
||||
CacheConfiguration cacheConfiguration = ((Cache) ret).getCacheConfiguration();
|
||||
if (cacheConfiguration != null) {
|
||||
((EnhancedInstance) ret).setSkyWalkingDynamicField(new EhcacheEnhanceInfo(cacheConfiguration.getName()));
|
||||
}
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
String name = (String) allArguments[0];
|
||||
objInst.setSkyWalkingDynamicField(new EhcacheEnhanceInfo(name));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
|
||||
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.apache.skywalking.apm.plugin.ehcache.v2;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.config.CacheConfiguration;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
|
||||
|
|
@ -25,11 +26,20 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceC
|
|||
public class EhcacheConstructorInterceptor implements InstanceConstructorInterceptor {
|
||||
@Override
|
||||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
|
||||
CacheConfiguration cacheConfiguration = (CacheConfiguration) allArguments[0];
|
||||
try {
|
||||
CacheConfiguration cacheConfiguration = (CacheConfiguration) allArguments[0];
|
||||
|
||||
// get cache name
|
||||
if (cacheConfiguration != null) {
|
||||
objInst.setSkyWalkingDynamicField(new EhcacheEnhanceInfo(cacheConfiguration.getName()));
|
||||
// get cache name
|
||||
if (cacheConfiguration != null) {
|
||||
objInst.setSkyWalkingDynamicField(new EhcacheEnhanceInfo(cacheConfiguration.getName()));
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
Cache cache = (Cache) allArguments[0];
|
||||
|
||||
// get cache name
|
||||
if (cache != null && cache.getCacheConfiguration() != null) {
|
||||
objInst.setSkyWalkingDynamicField(new EhcacheEnhanceInfo(cache.getCacheConfiguration().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPrivate;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
|
||||
|
||||
/**
|
||||
|
|
@ -37,12 +38,10 @@ public class EhcachePluginInstrumentation extends ClassInstanceMethodsEnhancePlu
|
|||
|
||||
public static final String INTERCEPT_CLASS = "net.sf.ehcache.Cache";
|
||||
public static final String CONSTRUCTOR_CLASS_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.ehcache.v2.EhcacheConstructorInterceptor";
|
||||
public static final String CLONE_CLASS_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.ehcache.v2.EhcacheCloneInterceptor";
|
||||
|
||||
// get and put value
|
||||
public static final String PUT_CACHE_ENHANCE_METHOD = "put";
|
||||
public static final String GET_CACHE_ENHANCE_METHOD = "get";
|
||||
public static final String CLONE_CACHE_ENHANCE_METHOD = "clone";
|
||||
public static final String GET_QUIET_CACHE_ENHANCE_METHOD = "getQuiet";
|
||||
public static final String REMOVE_CACHE_ENHANCE_METHOD = "remove";
|
||||
public static final String REMOVE_AND_RETURN_ELEMENT_CACHE_ENHANCE_METHOD = "removeAndReturnElement";
|
||||
|
|
@ -71,13 +70,18 @@ public class EhcachePluginInstrumentation extends ClassInstanceMethodsEnhancePlu
|
|||
public static final String READ_LOCK_RELEASE_ENHANCE_METHOD = "releaseRead" + LOCK_ENHANCE_METHOD_SUFFIX;
|
||||
public static final String READ_WRITE_LOCK_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.ehcache.v2.EhcacheLockInterceptor";
|
||||
|
||||
// cache name
|
||||
public static final String CACHE_NAME_ENHANCE_METHOD = "setName";
|
||||
public static final String CACHE_NAME_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.ehcache.v2.EhcacheCacheNameInterceptor";
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[] {
|
||||
new ConstructorInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return takesArgument(0, named("net.sf.ehcache.config.CacheConfiguration"));
|
||||
return takesArgument(0, named("net.sf.ehcache.config.CacheConfiguration"))
|
||||
.or(isPrivate().and(takesArgument(0, named("net.sf.ehcache.Cache"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -91,24 +95,24 @@ public class EhcachePluginInstrumentation extends ClassInstanceMethodsEnhancePlu
|
|||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[] {
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(CLONE_CACHE_ENHANCE_METHOD);
|
||||
}
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(CACHE_NAME_ENHANCE_METHOD).and(takesArgument(0, String.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return CLONE_CLASS_INTERCEPT_CLASS;
|
||||
}
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return CACHE_NAME_INTERCEPTOR_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
},
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(GET_WITH_LOADER_CACHE_ENHANCE_METHOD).or(named(GET_CACHE_ENHANCE_METHOD).and(takesArgument(0, Object.class)))
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ import org.powermock.modules.junit4.PowerMockRunner;
|
|||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
import org.powermock.reflect.Whitebox;
|
||||
|
||||
import static org.apache.skywalking.apm.plugin.ehcache.v2.define.EhcachePluginInstrumentation.CLONE_CACHE_ENHANCE_METHOD;
|
||||
import static org.apache.skywalking.apm.plugin.ehcache.v2.define.EhcachePluginInstrumentation.GET_ALL_CACHE_ENHANCE_METHOD;
|
||||
import static org.apache.skywalking.apm.plugin.ehcache.v2.define.EhcachePluginInstrumentation.GET_CACHE_ENHANCE_METHOD;
|
||||
import static org.apache.skywalking.apm.plugin.ehcache.v2.define.EhcachePluginInstrumentation.PUT_CACHE_ENHANCE_METHOD;
|
||||
|
|
@ -46,6 +45,8 @@ import static org.apache.skywalking.apm.plugin.ehcache.v2.define.EhcachePluginIn
|
|||
import static org.apache.skywalking.apm.plugin.ehcache.v2.define.EhcachePluginInstrumentation.READ_LOCK_TRY_ENHANCE_METHOD;
|
||||
import static org.apache.skywalking.apm.plugin.ehcache.v2.define.EhcachePluginInstrumentation.WRITE_LOCK_RELEASE_ENHANCE_METHOD;
|
||||
import static org.apache.skywalking.apm.plugin.ehcache.v2.define.EhcachePluginInstrumentation.WRITE_LOCK_TRY_ENHANCE_METHOD;
|
||||
import static org.apache.skywalking.apm.plugin.ehcache.v2.define.EhcachePluginInstrumentation.CACHE_NAME_ENHANCE_METHOD;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
|
|
@ -65,11 +66,12 @@ public class EhcacheInterceptorTest {
|
|||
private EhcacheOperateAllInterceptor operateAllInterceptor;
|
||||
private EhcacheLockInterceptor lockInterceptor;
|
||||
private EhcacheConstructorInterceptor constructorInterceptor;
|
||||
private EhcacheCloneInterceptor cloneInterceptor;
|
||||
private EhcacheCacheNameInterceptor cacheNameInterceptor;
|
||||
private Object[] operateObjectArguments;
|
||||
private Object[] operateElementArguments;
|
||||
private Object[] tryLockArguments;
|
||||
private Object[] releaseLockArguments;
|
||||
private Object[] cacheNameArguments;
|
||||
|
||||
private Exception exception;
|
||||
|
||||
|
|
@ -82,16 +84,19 @@ public class EhcacheInterceptorTest {
|
|||
private Method releaseReadLockMethod;
|
||||
private Method releaseWriteLockMethod;
|
||||
|
||||
private Method cloneMethod;
|
||||
private Method setNameMethod;
|
||||
|
||||
private EnhancedInstance enhancedInstance = new EnhancedInstance() {
|
||||
EhcacheEnhanceInfo ehcacheEnhanceInfo;
|
||||
|
||||
@Override
|
||||
public Object getSkyWalkingDynamicField() {
|
||||
return new EhcacheEnhanceInfo(CACHE_NAME);
|
||||
return ehcacheEnhanceInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyWalkingDynamicField(Object value) {
|
||||
ehcacheEnhanceInfo = (EhcacheEnhanceInfo) value;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -101,7 +106,7 @@ public class EhcacheInterceptorTest {
|
|||
operateElementInterceptor = new EhcacheOperateElementInterceptor();
|
||||
operateAllInterceptor = new EhcacheOperateAllInterceptor();
|
||||
constructorInterceptor = new EhcacheConstructorInterceptor();
|
||||
cloneInterceptor = new EhcacheCloneInterceptor();
|
||||
cacheNameInterceptor = new EhcacheCacheNameInterceptor();
|
||||
lockInterceptor = new EhcacheLockInterceptor();
|
||||
|
||||
exception = new Exception();
|
||||
|
|
@ -113,6 +118,7 @@ public class EhcacheInterceptorTest {
|
|||
3000
|
||||
};
|
||||
releaseLockArguments = new Object[] {"dataKey"};
|
||||
cacheNameArguments = new Object[] {"cacheName"};
|
||||
|
||||
putCacheMethod = Whitebox.getMethods(Cache.class, PUT_CACHE_ENHANCE_METHOD)[0];
|
||||
getCacheMethod = Whitebox.getMethods(Cache.class, GET_CACHE_ENHANCE_METHOD)[0];
|
||||
|
|
@ -123,7 +129,9 @@ public class EhcacheInterceptorTest {
|
|||
releaseReadLockMethod = Whitebox.getMethods(Cache.class, READ_LOCK_RELEASE_ENHANCE_METHOD)[0];
|
||||
releaseWriteLockMethod = Whitebox.getMethods(Cache.class, WRITE_LOCK_RELEASE_ENHANCE_METHOD)[0];
|
||||
|
||||
cloneMethod = Whitebox.getMethods(Cache.class, CLONE_CACHE_ENHANCE_METHOD)[0];
|
||||
setNameMethod = Whitebox.getMethods(Cache.class, CACHE_NAME_ENHANCE_METHOD)[0];
|
||||
|
||||
enhancedInstance.setSkyWalkingDynamicField(new EhcacheEnhanceInfo(CACHE_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -132,10 +140,12 @@ public class EhcacheInterceptorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void assertClone() throws Throwable {
|
||||
cloneInterceptor.beforeMethod(enhancedInstance, cloneMethod, null, null, null);
|
||||
cloneInterceptor.handleMethodException(enhancedInstance, cloneMethod, null, null, exception);
|
||||
cloneInterceptor.afterMethod(enhancedInstance, cloneMethod, null, null, null);
|
||||
public void assertSetNameSuccess() throws Throwable {
|
||||
cacheNameInterceptor.beforeMethod(enhancedInstance, setNameMethod, cacheNameArguments, null, null);
|
||||
cacheNameInterceptor.handleMethodException(enhancedInstance, setNameMethod, null, null, exception);
|
||||
cacheNameInterceptor.afterMethod(enhancedInstance, setNameMethod, cacheNameArguments, null, null);
|
||||
|
||||
Assert.assertThat(((EhcacheEnhanceInfo) enhancedInstance.getSkyWalkingDynamicField()).getCacheName(), equalTo("cacheName"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -100,6 +100,21 @@ segmentItems:
|
|||
peerId: 0
|
||||
tags:
|
||||
- {key: db.statement, value: dataKey}
|
||||
- operationName: Ehcache/put/testCache2
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 6
|
||||
spanLayer: Cache
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 75
|
||||
componentName: ''
|
||||
isError: false
|
||||
spanType: Local
|
||||
peer: ''
|
||||
peerId: 0
|
||||
tags:
|
||||
- {key: db.statement, value: dataKey}
|
||||
- operationName: /ehcache-2.x-scenario/case/ehcache
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
|
|
|
|||
|
|
@ -35,14 +35,7 @@ public class CaseServlet extends HttpServlet {
|
|||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
Cache originCache = cacheManager.getCache("testCache");
|
||||
|
||||
// EhcacheCloneInterceptor
|
||||
Cache cache = null;
|
||||
try {
|
||||
cache = originCache.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
}
|
||||
Cache cache = cacheManager.getCache("testCache");
|
||||
|
||||
String objectKey = "dataKey";
|
||||
|
||||
|
|
@ -65,6 +58,14 @@ public class CaseServlet extends HttpServlet {
|
|||
cache.releaseReadLockOnKey(objectKey);
|
||||
}
|
||||
|
||||
// EhcacheCacheNameInterceptor
|
||||
cacheManager.addCacheIfAbsent("testCache2");
|
||||
|
||||
Cache cloneCache = cacheManager.getCache("testCache2");
|
||||
|
||||
// EhcacheOperateElementInterceptor
|
||||
cloneCache.put(el);
|
||||
|
||||
PrintWriter printWriter = resp.getWriter();
|
||||
printWriter.write("success");
|
||||
printWriter.flush();
|
||||
|
|
|
|||
Loading…
Reference in New Issue