From 539e824d3e58ed1176521a5d707ac8fc8083fe66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B9=9F=E7=84=B6=EF=BC=88Wang=20Yeran=EF=BC=89?= =?UTF-8?q?=28wangyeran=29?= Date: Fri, 29 Oct 2021 12:02:32 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E8=A1=A5=E5=85=85http=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E8=AF=B7=E6=B1=82=E7=B1=BB=E5=9E=8B=E7=9A=84?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repeater/plugin/core/util/HttpUtil.java | 293 ++++++++++++++++++ 1 file changed, 293 insertions(+) diff --git a/repeater-plugin-core/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/core/util/HttpUtil.java b/repeater-plugin-core/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/core/util/HttpUtil.java index d25830c0..362a51e6 100644 --- a/repeater-plugin-core/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/core/util/HttpUtil.java +++ b/repeater-plugin-core/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/core/util/HttpUtil.java @@ -160,11 +160,17 @@ public static Resp invoke(String url, case POST: return invokePost(url, headers, paramsMap, body, 0); case PUT: + return invokePut(url, headers, paramsMap, body, 0); case HEAD: + return invokeHead(url, headers, paramsMap, 0); case PATCH: + return invokePatch(url, headers, paramsMap, body, 0); case DELETE: + return invokeDelete(url, headers, paramsMap, body, 0); case OPTIONS: + return invokeOptions(url, headers, paramsMap, 0); case TRACE: + return invokeTrace(url, headers, paramsMap, 0); default: return Resp.builder().code(500).message("Unsupported http method : " + method).build(); } @@ -326,6 +332,293 @@ public static Resp invokePostBody(String url, return executeRequest(rb.build(), 0); } + /** + * Put方法请求 + * @param url + * @param headers + * @param paramsMap + * @param retryTime + * @return + */ + private static Resp invokePut(String url, + Map headers, + Map paramsMap, + String body, + int retryTime) { + if (StringUtils.isNotEmpty(body)) { + return invokePutBody(url, headers, body); + } + FormBody.Builder fb = new FormBody.Builder(); + if (MapUtils.isNotEmpty(paramsMap)) { + for (Map.Entry entry : paramsMap.entrySet()) { + for (String value : entry.getValue()) { + fb.add(entry.getKey(), value); + } + } + } + Request.Builder rb = new Request.Builder().post(fb.build()).url(url); + if (MapUtils.isNotEmpty(headers)) { + for (Map.Entry entry : headers.entrySet()) { + rb.header(entry.getKey(), entry.getValue()); + } + } + return executeRequest(rb.build(), retryTime); + } + + /** + * Put方法请求 + * + * @param url url地址 + * @param headers 请求头 + * @param body 请求body + * @return resp + */ + public static Resp invokePutBody(String url, + Map headers, + String body) { + String contentType = headers.get("Content-Type"); + if (contentType == null) { + contentType = headers.get("content-type"); + } + if (contentType == null) { + contentType = "application/x-www-form-urlencoded; charset=utf-8"; + } + RequestBody b = RequestBody.create(MediaType.parse(contentType), body); + Request.Builder rb = new Request.Builder().post(b).url(url); + if (MapUtils.isNotEmpty(headers)) { + for (Map.Entry entry : headers.entrySet()) { + rb.header(entry.getKey(), entry.getValue()); + } + } + return executeRequest(rb.build()); + } + + + /** + * Head方法请求 + * + * @param url url地址 + * @param headers 请求头 + * @param paramsMap 请求参数 + * @return resp + */ + private static Resp invokeHead(String url, + Map headers, + Map paramsMap, + int retryTime) { + HttpUrl hu = HttpUrl.parse(url); + if (hu == null) { + return Resp.builder().code(500).message("Parse http url failed,url=" + url).build(); + } + if (MapUtils.isNotEmpty(paramsMap)) { + HttpUrl.Builder builder = hu.newBuilder(); + for (Map.Entry entry : paramsMap.entrySet()) { + for (String value : entry.getValue()) { + builder.addQueryParameter(entry.getKey(), value); + } + } + hu = builder.build(); + } + Request.Builder rb = new Request.Builder().get().url(hu); + if (MapUtils.isNotEmpty(headers)) { + for (Map.Entry entry : headers.entrySet()) { + rb.header(entry.getKey(), entry.getValue()); + } + } + return executeRequest(rb.build(), retryTime); + } + + + /** + * Patch方法请求 + * @param url + * @param headers + * @param paramsMap + * @param retryTime + * @return + */ + private static Resp invokePatch(String url, + Map headers, + Map paramsMap, + String body, + int retryTime) { + if (StringUtils.isNotEmpty(body)) { + return invokePatchBody(url, headers, body); + } + FormBody.Builder fb = new FormBody.Builder(); + if (MapUtils.isNotEmpty(paramsMap)) { + for (Map.Entry entry : paramsMap.entrySet()) { + for (String value : entry.getValue()) { + fb.add(entry.getKey(), value); + } + } + } + Request.Builder rb = new Request.Builder().post(fb.build()).url(url); + if (MapUtils.isNotEmpty(headers)) { + for (Map.Entry entry : headers.entrySet()) { + rb.header(entry.getKey(), entry.getValue()); + } + } + return executeRequest(rb.build(), retryTime); + } + + /** + * Patch方法请求 + * + * @param url url地址 + * @param headers 请求头 + * @param body 请求body + * @return resp + */ + public static Resp invokePatchBody(String url, + Map headers, + String body) { + String contentType = headers.get("Content-Type"); + if (contentType == null) { + contentType = headers.get("content-type"); + } + if (contentType == null) { + contentType = "application/x-www-form-urlencoded; charset=utf-8"; + } + RequestBody b = RequestBody.create(MediaType.parse(contentType), body); + Request.Builder rb = new Request.Builder().post(b).url(url); + if (MapUtils.isNotEmpty(headers)) { + for (Map.Entry entry : headers.entrySet()) { + rb.header(entry.getKey(), entry.getValue()); + } + } + return executeRequest(rb.build()); + } + + /** + * Delete方法请求 + * @param url + * @param headers + * @param paramsMap + * @param retryTime + * @return + */ + private static Resp invokeDelete(String url, + Map headers, + Map paramsMap, + String body, + int retryTime) { + if (StringUtils.isNotEmpty(body)) { + return invokeDeleteBody(url, headers, body); + } + FormBody.Builder fb = new FormBody.Builder(); + if (MapUtils.isNotEmpty(paramsMap)) { + for (Map.Entry entry : paramsMap.entrySet()) { + for (String value : entry.getValue()) { + fb.add(entry.getKey(), value); + } + } + } + Request.Builder rb = new Request.Builder().post(fb.build()).url(url); + if (MapUtils.isNotEmpty(headers)) { + for (Map.Entry entry : headers.entrySet()) { + rb.header(entry.getKey(), entry.getValue()); + } + } + return executeRequest(rb.build(), retryTime); + } + + /** + * Delete方法请求 + * + * @param url url地址 + * @param headers 请求头 + * @param body 请求body + * @return resp + */ + public static Resp invokeDeleteBody(String url, + Map headers, + String body) { + String contentType = headers.get("Content-Type"); + if (contentType == null) { + contentType = headers.get("content-type"); + } + if (contentType == null) { + contentType = "application/x-www-form-urlencoded; charset=utf-8"; + } + RequestBody b = RequestBody.create(MediaType.parse(contentType), body); + Request.Builder rb = new Request.Builder().post(b).url(url); + if (MapUtils.isNotEmpty(headers)) { + for (Map.Entry entry : headers.entrySet()) { + rb.header(entry.getKey(), entry.getValue()); + } + } + return executeRequest(rb.build()); + } + + /** + * Options方法请求 + * @param url + * @param headers + * @param paramsMap + * @param retryTime + * @return resp + */ + private static Resp invokeOptions(String url, + Map headers, + Map paramsMap, + int retryTime) { + HttpUrl hu = HttpUrl.parse(url); + if (hu == null) { + return Resp.builder().code(500).message("Parse http url failed,url=" + url).build(); + } + if (MapUtils.isNotEmpty(paramsMap)) { + HttpUrl.Builder builder = hu.newBuilder(); + for (Map.Entry entry : paramsMap.entrySet()) { + for (String value : entry.getValue()) { + builder.addQueryParameter(entry.getKey(), value); + } + } + hu = builder.build(); + } + Request.Builder rb = new Request.Builder().get().url(hu); + if (MapUtils.isNotEmpty(headers)) { + for (Map.Entry entry : headers.entrySet()) { + rb.header(entry.getKey(), entry.getValue()); + } + } + return executeRequest(rb.build(), retryTime); + } + + /** + * Trace方法请求 + * + * @param url url地址 + * @param headers 请求头 + * @param paramsMap 请求参数 + * @return resp + */ + private static Resp invokeTrace(String url, + Map headers, + Map paramsMap, + int retryTime) { + HttpUrl hu = HttpUrl.parse(url); + if (hu == null) { + return Resp.builder().code(500).message("Parse http url failed,url=" + url).build(); + } + if (MapUtils.isNotEmpty(paramsMap)) { + HttpUrl.Builder builder = hu.newBuilder(); + for (Map.Entry entry : paramsMap.entrySet()) { + for (String value : entry.getValue()) { + builder.addQueryParameter(entry.getKey(), value); + } + } + hu = builder.build(); + } + Request.Builder rb = new Request.Builder().get().url(hu); + if (MapUtils.isNotEmpty(headers)) { + for (Map.Entry entry : headers.entrySet()) { + rb.header(entry.getKey(), entry.getValue()); + } + } + return executeRequest(rb.build(), retryTime); + } + /** * 执行request * From a2eaa8259a424cf6f38be01c79560e26666724f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B9=9F=E7=84=B6=EF=BC=88Wang=20Yeran=EF=BC=89?= =?UTF-8?q?=28wangyeran=29?= Date: Tue, 23 Nov 2021 10:48:06 +0800 Subject: [PATCH 2/8] =?UTF-8?q?rpc=E6=8F=92=E4=BB=B6=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81client?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- repeater-plugins/rpc-plugin/pom.xml | 37 ++++++++ .../repeater/plugin/rpc/RpcListener.java | 45 +++++++++ .../repeater/plugin/rpc/RpcPlugin.java | 70 ++++++++++++++ .../repeater/plugin/rpc/RpcProcessor.java | 91 +++++++++++++++++++ .../rpc/wrapper/RpcWrapperTransModel.java | 84 +++++++++++++++++ 5 files changed, 327 insertions(+) create mode 100644 repeater-plugins/rpc-plugin/pom.xml create mode 100644 repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcListener.java create mode 100644 repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcPlugin.java create mode 100644 repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcProcessor.java create mode 100644 repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/wrapper/RpcWrapperTransModel.java diff --git a/repeater-plugins/rpc-plugin/pom.xml b/repeater-plugins/rpc-plugin/pom.xml new file mode 100644 index 00000000..15f64d7b --- /dev/null +++ b/repeater-plugins/rpc-plugin/pom.xml @@ -0,0 +1,37 @@ + + + + repeater-plugins + com.alibaba.jvm.sandbox + 1.0.0-SNAPSHOT + + 4.0.0 + + rpc-plugin + + ${project.name}-${project.version} + + + org.apache.maven.plugins + maven-assembly-plugin + + + + attached + + package + + + jar-with-dependencies + + + + + + + + + + \ No newline at end of file diff --git a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcListener.java b/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcListener.java new file mode 100644 index 00000000..3dee5144 --- /dev/null +++ b/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcListener.java @@ -0,0 +1,45 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.rpc; + +import com.alibaba.jvm.sandbox.api.event.ReturnEvent; +import com.alibaba.jvm.sandbox.repeater.plugin.api.InvocationListener; +import com.alibaba.jvm.sandbox.repeater.plugin.api.InvocationProcessor; +import com.alibaba.jvm.sandbox.repeater.plugin.core.cache.RecordCache; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.api.DefaultEventListener; +import com.alibaba.jvm.sandbox.repeater.plugin.core.trace.Tracer; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.Invocation; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; +/** + *

+ * + * @author qiyi-wangyeran/fanxiuping + */ +public class RpcListener extends DefaultEventListener { + RpcListener(InvokeType invokeType, + boolean entrance, + InvocationListener listener, + InvocationProcessor processor) { + super(invokeType, entrance, listener, processor); + } + + @Override + protected void doReturn(ReturnEvent event) { + try { + Invocation invocation = RecordCache.getInvocation(event.invokeId); + if (invocation == null) { + log.debug("no valid invocation found in return,type={},traceId={}", invokeType, Tracer.getTraceId()); + return; + } + invocation.setResponse(processor.assembleResponse(event)); + if (invocation.getIdentity().getLocation().startsWith("receiveBase")){ + Object[] requests = invocation.getRequest(); + requests[0] = invocation.getResponse(); + invocation.setRequest(requests); + invocation.getIdentity().setEndpoint(invocation.getResponse().toString()); + } + invocation.setEnd(System.currentTimeMillis()); + listener.onInvocation(invocation); + } catch (Exception e) { + log.error("error occurred when doReturn:{}", e); + } + } +} diff --git a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcPlugin.java b/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcPlugin.java new file mode 100644 index 00000000..c0c4a5ce --- /dev/null +++ b/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcPlugin.java @@ -0,0 +1,70 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.rpc; + +import java.util.List; + +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.api.listener.EventListener; +import com.alibaba.jvm.sandbox.repeater.plugin.api.InvocationListener; +import com.alibaba.jvm.sandbox.repeater.plugin.api.InvocationProcessor; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.AbstractInvokePluginAdapter; +import com.alibaba.jvm.sandbox.repeater.plugin.core.model.EnhanceModel; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; +import com.alibaba.jvm.sandbox.repeater.plugin.spi.InvokePlugin; + +import com.google.common.collect.Lists; +import org.kohsuke.MetaInfServices; + +/** + *

+ * + * @author qiyi-wangyeran/fanxiuping + */ +@MetaInfServices(InvokePlugin.class) +public class RpcPlugin extends AbstractInvokePluginAdapter { + + @Override + protected List getEnhanceModels() { + EnhanceModel.MethodPattern mpsend = EnhanceModel.MethodPattern.builder() + .methodName("sendBase") + .parameterType(new String[]{"java.lang.String","org.apache.thrift.TBase","byte"}) + .build(); + EnhanceModel emsend = EnhanceModel.builder() + .classPattern("org.apache.thrift.TServiceClient") + .methodPatterns(new EnhanceModel.MethodPattern[]{mpsend}) + .watchTypes(Event.Type.BEFORE, Event.Type.RETURN, Event.Type.THROWS) + .build(); + EnhanceModel emreceive = EnhanceModel.builder() + .classPattern("org.apache.thrift.TServiceClient") + .methodPatterns(EnhanceModel.MethodPattern.transform("receiveBase")) + .watchTypes(Event.Type.BEFORE, Event.Type.RETURN, Event.Type.THROWS) + .build(); + + return Lists.newArrayList(emsend, emreceive); + } + + @Override + protected InvocationProcessor getInvocationProcessor() { + return new RpcProcessor(getType()); + } + + @Override + public InvokeType getType() { + return InvokeType.RPC; + } + + @Override + public String identity() { + return "rpc"; + } + + @Override + public boolean isEntrance() { + return false; + } + + @Override + protected EventListener getEventListener(InvocationListener listener) { + return new RpcListener(getType(), isEntrance(), listener, getInvocationProcessor()); + } + +} diff --git a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcProcessor.java b/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcProcessor.java new file mode 100644 index 00000000..447f3cce --- /dev/null +++ b/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcProcessor.java @@ -0,0 +1,91 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.rpc; + +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.Invocation; +import com.alibaba.jvm.sandbox.repeater.plugin.rpc.wrapper.RpcWrapperTransModel; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.api.DefaultInvocationProcessor; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.Identity; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * + * @author qiyi-wangyeran/fanxiuping + */ +class RpcProcessor extends DefaultInvocationProcessor { + private final static Logger log = LoggerFactory.getLogger(RpcProcessor.class); + public static ThreadLocal threadLocalResult = new ThreadLocal<>(); + + RpcProcessor(InvokeType type) { + super(type); + } + + @Override + public Identity assembleIdentity(BeforeEvent event) { + RpcWrapperTransModel wtm = RpcWrapperTransModel.build(event); + try { + if (wtm == null) { + return new Identity(InvokeType.RPC.name(), "Unknown", "Unknown", new HashMap(1)); + } + if (wtm.getRpcCode().startsWith("receiveBase") && StringUtils.isNotBlank(wtm.getThriftProtocol())){ + threadLocalResult.set(event.argumentArray[0]); + } + Map extra = new HashMap(); + extra.put("Trotocol", wtm.getThriftProtocol()); + return new Identity(InvokeType.RPC.name(),wtm.getThriftProtocol(), wtm.getthriftParameterTypes(), extra); + } catch (Exception e) { + log.error("这里是thrift assembleIdentity error:{}",e); + return new Identity(InvokeType.RPC.name(), "Unknown", "Unknown", new HashMap(1)); + } + } + + @Override + public Object[] assembleRequest(BeforeEvent event) { + RpcWrapperTransModel wtm = RpcWrapperTransModel.build(event); + return new Object[]{wtm}; + } + + @Override + public Object assembleResponse(Event event) { + if (event.type == Event.Type.RETURN ) { + try { + Object threadLocalValue = threadLocalResult.get(); + threadLocalResult.remove(); + return threadLocalValue; + } catch (Exception e) { + log.error("这里是thrift assembleResponse error:{}", e); + } + } + return null; + } + + @Override + public Object assembleMockResponse(BeforeEvent event, Invocation invocation) { + Object[] argumentarray=(Object[])event.argumentArray; + if (argumentarray != null && argumentarray.length >= 2){ + try { + if ("receiveBase".equals(event.javaMethodName) && invocation.getResponse() != null){ + if (invocation.getResponse() != null && StringUtils.isNotBlank(invocation.getResponse().toString())){ + event.argumentArray[0] = invocation.getResponse(); + invocation.getRequest()[0] = invocation.getResponse(); + } + } + return null; + } catch (Exception e) { + log.error("error occurred when assemble thrift mock response:{}", e); + return null; + } + }else{ + log.info("rpc thrift assemble mockresponse size:{}", argumentarray.length); + } + return null; + } + +} diff --git a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/wrapper/RpcWrapperTransModel.java b/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/wrapper/RpcWrapperTransModel.java new file mode 100644 index 00000000..7bfbb60b --- /dev/null +++ b/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/wrapper/RpcWrapperTransModel.java @@ -0,0 +1,84 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.rpc.wrapper; + +import com.alibaba.fastjson.JSON; +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import org.apache.commons.lang3.reflect.MethodUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

+ * + * @author qiyi-wangyeran/fanxiuping + */ +public class RpcWrapperTransModel { + + /** + * rpc code + */ + private String rpcCode; + /** + * thrift_parameter_types + */ + private String thriftParameterTypes; + /** + * thrift_parameter_values + */ + private String thriftProtocol; + public static String RECEIVE = "receiveBase"; + public static String SEND = "sendBase"; + protected static Logger log = LoggerFactory.getLogger(RpcWrapperTransModel.class); + + + + + private RpcWrapperTransModel(String rpcCode,String thriftParameterTypes,String thriftProtocol) { + this.rpcCode=rpcCode; + this.thriftParameterTypes=thriftParameterTypes; + this.thriftProtocol = thriftProtocol; + } + + + public static RpcWrapperTransModel build(BeforeEvent event) { + try { + Object[] argumentArray=(Object[])event.argumentArray; + String rpcCode=""; + String thriftParameterTypes=""; + String thriftProtocol=""; + Object rpcObj = event.target; + if (rpcObj != null){ + Object inprotocol = MethodUtils.invokeMethod(rpcObj, "getInputProtocol"); + thriftProtocol = inprotocol.toString(); + } + if(event.argumentArray!= null && argumentArray.length>=2){ + if (RECEIVE.equals(event.javaMethodName)){ + rpcCode= RECEIVE + "_" + argumentArray[1].toString(); + thriftParameterTypes = argumentArray[0].toString(); + }else{ + rpcCode= SEND + "_" + argumentArray[0].toString(); + thriftParameterTypes = JSON.toJSONString(argumentArray[1]); + } + } + return new RpcWrapperTransModel( + rpcCode, + thriftParameterTypes, + thriftProtocol + ); + }catch(Exception e){ + log.error("rpc thrift Wrapper error {},object:{},event arg:{},func:{}", e,event.target,event.argumentArray,event.javaClassName+event.javaMethodName); + + } + return null; + } + public String getRpcCode() { + return rpcCode; + } + + public String getthriftParameterTypes() { + return thriftParameterTypes; + } + + public String getThriftProtocol(){ + return this.thriftProtocol; + } +} From 433b0aeec0a6ff7c896c702244d2c5c62f42cf08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B9=9F=E7=84=B6=EF=BC=88Wang=20Yeran=EF=BC=89?= =?UTF-8?q?=28wangyeran=29?= Date: Fri, 25 Feb 2022 17:23:06 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E9=87=8D=E6=8F=90thrift=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repeater/plugin/domain/InvokeType.java | 2 + .../{rpc-plugin => couchbase-plugin}/pom.xml | 5 +- repeater-plugins/pom.xml | 1 + .../repeater/plugin/rpc/RpcProcessor.java | 91 ------------------- .../rpc/wrapper/RpcWrapperTransModel.java | 84 ----------------- repeater-plugins/thrift-plugin/pom.xml | 45 +++++++++ .../plugin/thrift/ThriftListener.java} | 17 ++-- .../repeater/plugin/thrift/ThriftPlugin.java} | 24 +++-- .../plugin/thrift/ThriftProcessor.java | 85 +++++++++++++++++ .../wrapper/ThriftWrapperTransModel.java | 85 +++++++++++++++++ 10 files changed, 240 insertions(+), 199 deletions(-) rename repeater-plugins/{rpc-plugin => couchbase-plugin}/pom.xml (96%) delete mode 100644 repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcProcessor.java delete mode 100644 repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/wrapper/RpcWrapperTransModel.java create mode 100644 repeater-plugins/thrift-plugin/pom.xml rename repeater-plugins/{rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcListener.java => thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftListener.java} (84%) rename repeater-plugins/{rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcPlugin.java => thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftPlugin.java} (74%) create mode 100644 repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftProcessor.java create mode 100644 repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/wrapper/ThriftWrapperTransModel.java diff --git a/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java b/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java index 8e021ce6..0b48c354 100644 --- a/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java +++ b/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java @@ -36,6 +36,8 @@ public class InvokeType implements java.io.Serializable { public static InvokeType EH_CACHE = new InvokeType("eh-cache"); public static InvokeType CAFFEINE_CACHE = new InvokeType("caffeine-cache"); + + public static InvokeType THRIFT = new InvokeType("thrift"); private String name; diff --git a/repeater-plugins/rpc-plugin/pom.xml b/repeater-plugins/couchbase-plugin/pom.xml similarity index 96% rename from repeater-plugins/rpc-plugin/pom.xml rename to repeater-plugins/couchbase-plugin/pom.xml index 15f64d7b..5229dac5 100644 --- a/repeater-plugins/rpc-plugin/pom.xml +++ b/repeater-plugins/couchbase-plugin/pom.xml @@ -9,7 +9,8 @@ 4.0.0 - rpc-plugin + couchbase-plugin + ${project.name}-${project.version} @@ -32,6 +33,4 @@ - - \ No newline at end of file diff --git a/repeater-plugins/pom.xml b/repeater-plugins/pom.xml index d87c2bdb..3d5399dd 100644 --- a/repeater-plugins/pom.xml +++ b/repeater-plugins/pom.xml @@ -25,6 +25,7 @@ eh-cache-plugin guava-cache-plugin okhttp-plugin + thrift-plugin diff --git a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcProcessor.java b/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcProcessor.java deleted file mode 100644 index 447f3cce..00000000 --- a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcProcessor.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.alibaba.jvm.sandbox.repeater.plugin.rpc; - -import com.alibaba.jvm.sandbox.api.event.BeforeEvent; -import com.alibaba.jvm.sandbox.api.event.Event; -import com.alibaba.jvm.sandbox.repeater.plugin.domain.Invocation; -import com.alibaba.jvm.sandbox.repeater.plugin.rpc.wrapper.RpcWrapperTransModel; -import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.api.DefaultInvocationProcessor; -import com.alibaba.jvm.sandbox.repeater.plugin.domain.Identity; -import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; -import java.util.Map; - -/** - *

- * - * @author qiyi-wangyeran/fanxiuping - */ -class RpcProcessor extends DefaultInvocationProcessor { - private final static Logger log = LoggerFactory.getLogger(RpcProcessor.class); - public static ThreadLocal threadLocalResult = new ThreadLocal<>(); - - RpcProcessor(InvokeType type) { - super(type); - } - - @Override - public Identity assembleIdentity(BeforeEvent event) { - RpcWrapperTransModel wtm = RpcWrapperTransModel.build(event); - try { - if (wtm == null) { - return new Identity(InvokeType.RPC.name(), "Unknown", "Unknown", new HashMap(1)); - } - if (wtm.getRpcCode().startsWith("receiveBase") && StringUtils.isNotBlank(wtm.getThriftProtocol())){ - threadLocalResult.set(event.argumentArray[0]); - } - Map extra = new HashMap(); - extra.put("Trotocol", wtm.getThriftProtocol()); - return new Identity(InvokeType.RPC.name(),wtm.getThriftProtocol(), wtm.getthriftParameterTypes(), extra); - } catch (Exception e) { - log.error("这里是thrift assembleIdentity error:{}",e); - return new Identity(InvokeType.RPC.name(), "Unknown", "Unknown", new HashMap(1)); - } - } - - @Override - public Object[] assembleRequest(BeforeEvent event) { - RpcWrapperTransModel wtm = RpcWrapperTransModel.build(event); - return new Object[]{wtm}; - } - - @Override - public Object assembleResponse(Event event) { - if (event.type == Event.Type.RETURN ) { - try { - Object threadLocalValue = threadLocalResult.get(); - threadLocalResult.remove(); - return threadLocalValue; - } catch (Exception e) { - log.error("这里是thrift assembleResponse error:{}", e); - } - } - return null; - } - - @Override - public Object assembleMockResponse(BeforeEvent event, Invocation invocation) { - Object[] argumentarray=(Object[])event.argumentArray; - if (argumentarray != null && argumentarray.length >= 2){ - try { - if ("receiveBase".equals(event.javaMethodName) && invocation.getResponse() != null){ - if (invocation.getResponse() != null && StringUtils.isNotBlank(invocation.getResponse().toString())){ - event.argumentArray[0] = invocation.getResponse(); - invocation.getRequest()[0] = invocation.getResponse(); - } - } - return null; - } catch (Exception e) { - log.error("error occurred when assemble thrift mock response:{}", e); - return null; - } - }else{ - log.info("rpc thrift assemble mockresponse size:{}", argumentarray.length); - } - return null; - } - -} diff --git a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/wrapper/RpcWrapperTransModel.java b/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/wrapper/RpcWrapperTransModel.java deleted file mode 100644 index 7bfbb60b..00000000 --- a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/wrapper/RpcWrapperTransModel.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.alibaba.jvm.sandbox.repeater.plugin.rpc.wrapper; - -import com.alibaba.fastjson.JSON; -import com.alibaba.jvm.sandbox.api.event.BeforeEvent; -import org.apache.commons.lang3.reflect.MethodUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - *

- * - * @author qiyi-wangyeran/fanxiuping - */ -public class RpcWrapperTransModel { - - /** - * rpc code - */ - private String rpcCode; - /** - * thrift_parameter_types - */ - private String thriftParameterTypes; - /** - * thrift_parameter_values - */ - private String thriftProtocol; - public static String RECEIVE = "receiveBase"; - public static String SEND = "sendBase"; - protected static Logger log = LoggerFactory.getLogger(RpcWrapperTransModel.class); - - - - - private RpcWrapperTransModel(String rpcCode,String thriftParameterTypes,String thriftProtocol) { - this.rpcCode=rpcCode; - this.thriftParameterTypes=thriftParameterTypes; - this.thriftProtocol = thriftProtocol; - } - - - public static RpcWrapperTransModel build(BeforeEvent event) { - try { - Object[] argumentArray=(Object[])event.argumentArray; - String rpcCode=""; - String thriftParameterTypes=""; - String thriftProtocol=""; - Object rpcObj = event.target; - if (rpcObj != null){ - Object inprotocol = MethodUtils.invokeMethod(rpcObj, "getInputProtocol"); - thriftProtocol = inprotocol.toString(); - } - if(event.argumentArray!= null && argumentArray.length>=2){ - if (RECEIVE.equals(event.javaMethodName)){ - rpcCode= RECEIVE + "_" + argumentArray[1].toString(); - thriftParameterTypes = argumentArray[0].toString(); - }else{ - rpcCode= SEND + "_" + argumentArray[0].toString(); - thriftParameterTypes = JSON.toJSONString(argumentArray[1]); - } - } - return new RpcWrapperTransModel( - rpcCode, - thriftParameterTypes, - thriftProtocol - ); - }catch(Exception e){ - log.error("rpc thrift Wrapper error {},object:{},event arg:{},func:{}", e,event.target,event.argumentArray,event.javaClassName+event.javaMethodName); - - } - return null; - } - public String getRpcCode() { - return rpcCode; - } - - public String getthriftParameterTypes() { - return thriftParameterTypes; - } - - public String getThriftProtocol(){ - return this.thriftProtocol; - } -} diff --git a/repeater-plugins/thrift-plugin/pom.xml b/repeater-plugins/thrift-plugin/pom.xml new file mode 100644 index 00000000..1f7fd784 --- /dev/null +++ b/repeater-plugins/thrift-plugin/pom.xml @@ -0,0 +1,45 @@ + + + + repeater-plugins + com.alibaba.jvm.sandbox + 1.0.0-SNAPSHOT + + 4.0.0 + + thrift-plugin + + ${project.name}-${project.version} + + + org.apache.maven.plugins + maven-assembly-plugin + + + + attached + + package + + + jar-with-dependencies + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 7 + 7 + + + + + + + \ No newline at end of file diff --git a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcListener.java b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftListener.java similarity index 84% rename from repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcListener.java rename to repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftListener.java index 3dee5144..452fdb6c 100644 --- a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcListener.java +++ b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftListener.java @@ -1,4 +1,4 @@ -package com.alibaba.jvm.sandbox.repeater.plugin.rpc; +package com.alibaba.jvm.sandbox.repeater.plugin.thrift; import com.alibaba.jvm.sandbox.api.event.ReturnEvent; import com.alibaba.jvm.sandbox.repeater.plugin.api.InvocationListener; @@ -8,13 +8,14 @@ import com.alibaba.jvm.sandbox.repeater.plugin.core.trace.Tracer; import com.alibaba.jvm.sandbox.repeater.plugin.domain.Invocation; import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; + /** *

* - * @author qiyi-wangyeran/fanxiuping + * @author wangyeran/fanxiuping */ -public class RpcListener extends DefaultEventListener { - RpcListener(InvokeType invokeType, +public class ThriftListener extends DefaultEventListener { + ThriftListener(InvokeType invokeType, boolean entrance, InvocationListener listener, InvocationProcessor processor) { @@ -23,7 +24,7 @@ public class RpcListener extends DefaultEventListener { @Override protected void doReturn(ReturnEvent event) { - try { + Invocation invocation = RecordCache.getInvocation(event.invokeId); if (invocation == null) { log.debug("no valid invocation found in return,type={},traceId={}", invokeType, Tracer.getTraceId()); @@ -38,8 +39,8 @@ protected void doReturn(ReturnEvent event) { } invocation.setEnd(System.currentTimeMillis()); listener.onInvocation(invocation); - } catch (Exception e) { - log.error("error occurred when doReturn:{}", e); - } + + } + } diff --git a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcPlugin.java b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftPlugin.java similarity index 74% rename from repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcPlugin.java rename to repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftPlugin.java index c0c4a5ce..2645a3ca 100644 --- a/repeater-plugins/rpc-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/rpc/RpcPlugin.java +++ b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftPlugin.java @@ -1,4 +1,4 @@ -package com.alibaba.jvm.sandbox.repeater.plugin.rpc; +package com.alibaba.jvm.sandbox.repeater.plugin.thrift; import java.util.List; @@ -10,51 +10,49 @@ import com.alibaba.jvm.sandbox.repeater.plugin.core.model.EnhanceModel; import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; import com.alibaba.jvm.sandbox.repeater.plugin.spi.InvokePlugin; - import com.google.common.collect.Lists; import org.kohsuke.MetaInfServices; /** *

* - * @author qiyi-wangyeran/fanxiuping + * @author wangyeran/fanxiuping */ @MetaInfServices(InvokePlugin.class) -public class RpcPlugin extends AbstractInvokePluginAdapter { +public class ThriftPlugin extends AbstractInvokePluginAdapter { @Override protected List getEnhanceModels() { EnhanceModel.MethodPattern mpsend = EnhanceModel.MethodPattern.builder() .methodName("sendBase") - .parameterType(new String[]{"java.lang.String","org.apache.thrift.TBase","byte"}) + .parameterType(new String[]{"java.lang.String", "org.apache.thrift.TBase", "byte"}) .build(); - EnhanceModel emsend = EnhanceModel.builder() + EnhanceModel emSend = EnhanceModel.builder() .classPattern("org.apache.thrift.TServiceClient") .methodPatterns(new EnhanceModel.MethodPattern[]{mpsend}) .watchTypes(Event.Type.BEFORE, Event.Type.RETURN, Event.Type.THROWS) .build(); - EnhanceModel emreceive = EnhanceModel.builder() + EnhanceModel emReceive = EnhanceModel.builder() .classPattern("org.apache.thrift.TServiceClient") .methodPatterns(EnhanceModel.MethodPattern.transform("receiveBase")) .watchTypes(Event.Type.BEFORE, Event.Type.RETURN, Event.Type.THROWS) .build(); - - return Lists.newArrayList(emsend, emreceive); + return Lists.newArrayList(emSend, emReceive); } @Override protected InvocationProcessor getInvocationProcessor() { - return new RpcProcessor(getType()); + return new ThriftProcessor(getType()); } @Override public InvokeType getType() { - return InvokeType.RPC; + return InvokeType.THRIFT; } @Override public String identity() { - return "rpc"; + return "thrift"; } @Override @@ -64,7 +62,7 @@ public boolean isEntrance() { @Override protected EventListener getEventListener(InvocationListener listener) { - return new RpcListener(getType(), isEntrance(), listener, getInvocationProcessor()); + return new ThriftListener(getType(), isEntrance(), listener, getInvocationProcessor()); } } diff --git a/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftProcessor.java b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftProcessor.java new file mode 100644 index 00000000..71e57a01 --- /dev/null +++ b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftProcessor.java @@ -0,0 +1,85 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.thrift; + +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.Invocation; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.api.DefaultInvocationProcessor; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.Identity; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; +import com.alibaba.jvm.sandbox.repeater.plugin.thrift.wrapper.ThriftWrapperTransModel; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * + * @author wangyeran/fanxiuping + */ +class ThriftProcessor extends DefaultInvocationProcessor { + private final static Logger log = LoggerFactory.getLogger(ThriftProcessor.class); + + public static ThreadLocal threadLocalResult = new ThreadLocal<>(); + + ThriftProcessor(InvokeType type) { + super(type); + } + + @Override + public Identity assembleIdentity(BeforeEvent event) { + + ThriftWrapperTransModel wtm = ThriftWrapperTransModel.build(event); + + if (wtm == null) { + return new Identity(InvokeType.THRIFT.name(), "Unknown", "Unknown", new HashMap(1)); + } + if (wtm.getThriftCode().startsWith("receiveBase") && StringUtils.isNotBlank(wtm.getThriftProtocol())) { + threadLocalResult.set(event.argumentArray[0]); + } + Map extra = new HashMap(); + extra.put("Trotocol", wtm.getThriftProtocol()); + return new Identity(InvokeType.THRIFT.name(), wtm.getThriftCode(), wtm.getThriftParameterTypes(), extra); + + } + + @Override + public Object[] assembleRequest(BeforeEvent event) { + ThriftWrapperTransModel wtm = ThriftWrapperTransModel.build(event); + return new Object[]{wtm}; + } + + @Override + public Object assembleResponse(Event event) { + if (event.type == Event.Type.RETURN) { + //response的时候,再将threadLocal里面的数据弹出 + Object threadLocalValue = threadLocalResult.get(); + //这个其实是receiveBase的参数,但是拿不到returnEvent拿不到参数信息,因此先放到response中 + threadLocalResult.remove(); + return threadLocalValue; + } + return null; + } + + @Override + public Object assembleMockResponse(BeforeEvent event, Invocation invocation) { + Object[] argumentarray = (Object[]) event.argumentArray; + if (argumentarray != null && argumentarray.length >= 2) { + if ("receiveBase".equals(event.javaMethodName) && invocation.getResponse() != null) { + log.info("rpc thrift assemble mock response:{}", invocation.getResponse()); + if (invocation.getResponse() != null && StringUtils.isNotBlank(invocation.getResponse().toString())) { + event.argumentArray[0] = invocation.getResponse(); + invocation.getRequest()[0] = invocation.getResponse(); + } + + } + return null; + } else { + log.info("rpc thrift assemble mockresponse size:{}", argumentarray.length); + } + return null; + } + +} diff --git a/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/wrapper/ThriftWrapperTransModel.java b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/wrapper/ThriftWrapperTransModel.java new file mode 100644 index 00000000..cd7d3bb5 --- /dev/null +++ b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/wrapper/ThriftWrapperTransModel.java @@ -0,0 +1,85 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.thrift.wrapper; + +import com.alibaba.fastjson.JSON; +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import org.apache.commons.lang3.reflect.MethodUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.InvocationTargetException; + +/** + *

+ * + * @author wangyeran/fanxiuping + */ +public class ThriftWrapperTransModel { + /** + * thrift code + */ + private final String thriftCode; + /** + * thrift_parameter_types + */ + private final String thriftParameterTypes; + /** + * thrift_parameter_values + */ + private final String thriftProtocol; + public static String RECEIVE = "receiveBase"; + public static String SEND = "sendBase"; + protected static Logger log = LoggerFactory.getLogger(ThriftWrapperTransModel.class); + + private ThriftWrapperTransModel(String thriftCode, String thriftParameterTypes, String thriftProtocol) { + this.thriftCode = thriftCode; + this.thriftParameterTypes = thriftParameterTypes; + this.thriftProtocol = thriftProtocol; + } + + public static ThriftWrapperTransModel build(BeforeEvent event) { + try { + Object[] argumentArray = (Object[]) event.argumentArray; + String thriftCode = ""; + String thriftParameterTypes = ""; + String thriftProtocol = ""; + + Object thriftObj = event.target; + if (thriftObj != null) { + Object inprotocol = MethodUtils.invokeMethod(thriftObj, "getInputProtocol"); + thriftProtocol = inprotocol.toString(); + } + if (event.argumentArray != null && argumentArray.length >= 2) { + if (RECEIVE.equals(event.javaMethodName)) { + thriftCode = RECEIVE + "_" + argumentArray[1].toString(); + thriftParameterTypes = argumentArray[0].toString(); + } else { + thriftCode = SEND + "_" + argumentArray[0].toString(); + thriftParameterTypes = JSON.toJSONString(argumentArray[1]); + } + } + return new ThriftWrapperTransModel( + thriftCode, + thriftParameterTypes, + thriftProtocol + + ); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + log.error(" thrift Wrapper error {},object:{},event arg:{},func:{}", + e, event.target, event.argumentArray, event.javaClassName + event.javaMethodName); + + } + return null; + } + + public String getThriftCode() { + return thriftCode; + } + + public String getThriftParameterTypes() { + return thriftParameterTypes; + } + + public String getThriftProtocol() { + return this.thriftProtocol; + } +} From ac06e0a33529d5ccd33190219a38300924d58195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B9=9F=E7=84=B6=EF=BC=88Wang=20Yeran=EF=BC=89?= =?UTF-8?q?=28wangyeran=29?= Date: Fri, 25 Feb 2022 17:36:21 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E6=8F=90=E4=BA=A4couchBase=E6=8F=92?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repeater/plugin/domain/InvokeType.java | 6 +- .../plugin/couchbase/CouchBasePlugin.java | 62 +++++++++++++ .../plugin/couchbase/CouchBaseProcessor.java | 92 +++++++++++++++++++ repeater-plugins/pom.xml | 1 + 4 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBasePlugin.java create mode 100644 repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBaseProcessor.java diff --git a/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java b/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java index 0b48c354..cc01fd16 100644 --- a/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java +++ b/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java @@ -36,8 +36,10 @@ public class InvokeType implements java.io.Serializable { public static InvokeType EH_CACHE = new InvokeType("eh-cache"); public static InvokeType CAFFEINE_CACHE = new InvokeType("caffeine-cache"); - - public static InvokeType THRIFT = new InvokeType("thrift"); + + public static InvokeType COUCH_BASE = new InvokeType("couchbase"); + + public static InvokeType THRIFT = new InvokeType("thrift"); private String name; diff --git a/repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBasePlugin.java b/repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBasePlugin.java new file mode 100644 index 00000000..0e44c382 --- /dev/null +++ b/repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBasePlugin.java @@ -0,0 +1,62 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.couchbase; + + +import java.util.List; + +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.AbstractInvokePluginAdapter; +import com.alibaba.jvm.sandbox.repeater.plugin.core.model.EnhanceModel; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; +import com.alibaba.jvm.sandbox.repeater.plugin.spi.InvokePlugin; + +import com.google.common.collect.Lists; +import org.kohsuke.MetaInfServices; + +/** + *

+ * + * @author wangyeran + */ +@MetaInfServices(InvokePlugin.class) +public class CouchBasePlugin extends AbstractInvokePluginAdapter { + + @Override + protected List getEnhanceModels() { + EnhanceModel em1 = EnhanceModel.builder() + .classPattern("net.spy.memcached.MemcachedClient") + .methodPatterns(EnhanceModel.MethodPattern.transform("delete")) + .watchTypes(Event.Type.BEFORE, Event.Type.RETURN, Event.Type.THROWS) + .build(); + EnhanceModel em2 = EnhanceModel.builder() + .classPattern("net.spy.memcached.MemcachedClient") + .methodPatterns(EnhanceModel.MethodPattern.transform("get")) + .watchTypes(Event.Type.BEFORE, Event.Type.RETURN, Event.Type.THROWS) + .build(); + EnhanceModel em3 = EnhanceModel.builder() + .classPattern("net.spy.memcached.MemcachedClient") + .methodPatterns(EnhanceModel.MethodPattern.transform("getBulk")) + .watchTypes(Event.Type.BEFORE, Event.Type.RETURN, Event.Type.THROWS) + .build(); + return Lists.newArrayList(em1, em2, em3); + } + + protected CouchBaseProcessor getInvocationProcessor() { + return new CouchBaseProcessor(getType()); + } + + @Override + public InvokeType getType() { + return InvokeType.COUCH_BASE; + } + + @Override + public String identity() { + return "couchbase"; + } + + @Override + public boolean isEntrance() { + return false; + } + +} diff --git a/repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBaseProcessor.java b/repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBaseProcessor.java new file mode 100644 index 00000000..87258d73 --- /dev/null +++ b/repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBaseProcessor.java @@ -0,0 +1,92 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.couchbase; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.api.DefaultInvocationProcessor; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.Identity; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; +import org.apache.commons.lang3.reflect.MethodUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

+ * + * @author wangyeran + */ +class CouchBaseProcessor extends DefaultInvocationProcessor { + + CouchBaseProcessor(InvokeType type) { + super(type); + } + + protected static Logger log = LoggerFactory.getLogger(CouchBaseProcessor.class); + + @Override + public Identity assembleIdentity(BeforeEvent event) { + if (event.argumentArray[0].getClass().toString().contains("ArrayList$Itr")) { + Class cz = event.argumentArray[0].getClass(); + try { + Method method = cz.getDeclaredMethod("hasNext"); + Method method1 = cz.getDeclaredMethod("next"); + method.setAccessible(true); + method1.setAccessible(true); + List list = new ArrayList(); + while (Boolean.valueOf(method.invoke(event.argumentArray[0]).toString())) { + list.add(method1.invoke(event.argumentArray[0])); + } + Class arrayListClass = event.javaClassLoader.loadClass("java.util.ArrayList"); + Object arrayList = arrayListClass.newInstance(); + for (Object o : list) { + MethodUtils.invokeMethod(arrayList, "add", o); + } + Method methodIterator = arrayListClass.getDeclaredMethod("iterator"); + methodIterator.setAccessible(true); + Object iterator = methodIterator.invoke(arrayList); + event.argumentArray[0] = iterator; + return new Identity(InvokeType.COUCH_BASE.name(), list.toString(), "Unknown", new HashMap(1)); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException | ClassNotFoundException e) { + log.error("couchbase assembleIdentity error {}, object:{}, event arg:{}, func:{}", + e, event.target, event.argumentArray, event.javaClassName + event.javaMethodName); e.printStackTrace(); + } + } + return new Identity(InvokeType.COUCH_BASE.name(), event.argumentArray[0].toString(), "Unknown", new HashMap(1)); + + } + + @Override + public Object[] assembleRequest(BeforeEvent event) { + if (event.argumentArray[0].getClass().toString().contains("ArrayList$Itr")) { + Class cz = event.argumentArray[0].getClass(); + try { + Method method = cz.getDeclaredMethod("hasNext"); + Method method1 = cz.getDeclaredMethod("next"); + method.setAccessible(true); + method1.setAccessible(true); + List list = new ArrayList(); + while (Boolean.valueOf(method.invoke(event.argumentArray[0]).toString())) { + list.add(method1.invoke(event.argumentArray[0])); + } + Class arrayListClass = event.javaClassLoader.loadClass("java.util.ArrayList"); + Object arrayList = arrayListClass.newInstance(); + for (Object o : list) { + MethodUtils.invokeMethod(arrayList, "add", o); + } + Method methodIterator = arrayListClass.getDeclaredMethod("iterator"); + methodIterator.setAccessible(true); + Object iterator = methodIterator.invoke(arrayList); + event.argumentArray[0] = iterator; + return new Object[]{list}; + } catch (Exception e) { + log.error("couchbase assembleRequest error {}, object:{}, event arg:{}, func:{}", + e, event.target, event.argumentArray, event.javaClassName + event.javaMethodName); e.printStackTrace(); + } + } + return new Object[]{event.argumentArray[0]}; + } +} diff --git a/repeater-plugins/pom.xml b/repeater-plugins/pom.xml index 3d5399dd..e7a0ecad 100644 --- a/repeater-plugins/pom.xml +++ b/repeater-plugins/pom.xml @@ -25,6 +25,7 @@ eh-cache-plugin guava-cache-plugin okhttp-plugin + couchbase-plugin thrift-plugin From 06d8dd1ba6a19d55fcdb279afd6b6677b9af3b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B9=9F=E7=84=B6=EF=BC=88Wang=20Yeran=EF=BC=89?= =?UTF-8?q?=28wangyeran=29?= Date: Fri, 25 Feb 2022 17:47:52 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E6=8F=90=E4=BA=A4HIKV=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- repeater-plugins/hikv-plugin/pom.xml | 36 ++++++++++++++ .../repeater/plugin/hikv/HikvPlugin.java | 47 +++++++++++++++++++ .../repeater/plugin/hikv/HikvProcesssor.java | 30 ++++++++++++ repeater-plugins/pom.xml | 1 + 4 files changed, 114 insertions(+) create mode 100644 repeater-plugins/hikv-plugin/pom.xml create mode 100644 repeater-plugins/hikv-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/hikv/HikvPlugin.java create mode 100644 repeater-plugins/hikv-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/hikv/HikvProcesssor.java diff --git a/repeater-plugins/hikv-plugin/pom.xml b/repeater-plugins/hikv-plugin/pom.xml new file mode 100644 index 00000000..82415456 --- /dev/null +++ b/repeater-plugins/hikv-plugin/pom.xml @@ -0,0 +1,36 @@ + + + + repeater-plugins + com.alibaba.jvm.sandbox + 1.0.0-SNAPSHOT + + 4.0.0 + + hikv-plugin + + + ${project.name}-${project.version} + + + org.apache.maven.plugins + maven-assembly-plugin + + + + attached + + package + + + jar-with-dependencies + + + + + + + + \ No newline at end of file diff --git a/repeater-plugins/hikv-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/hikv/HikvPlugin.java b/repeater-plugins/hikv-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/hikv/HikvPlugin.java new file mode 100644 index 00000000..7db74334 --- /dev/null +++ b/repeater-plugins/hikv-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/hikv/HikvPlugin.java @@ -0,0 +1,47 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.hikv; + +import java.util.List; +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.AbstractInvokePluginAdapter; +import com.alibaba.jvm.sandbox.repeater.plugin.core.model.EnhanceModel; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; +import com.alibaba.jvm.sandbox.repeater.plugin.spi.InvokePlugin; +import com.google.common.collect.Lists; +import org.kohsuke.MetaInfServices; + +/** + *

+ * + * @author wangyeran + */ +@MetaInfServices(InvokePlugin.class) +public class HikvPlugin extends AbstractInvokePluginAdapter { + @Override + protected List getEnhanceModels() { + EnhanceModel em = EnhanceModel.builder() + .classPattern("com.iqiyi.hikv.ToBlockingHiKV") + .methodPatterns(EnhanceModel.MethodPattern.transform("get")) + .watchTypes(Event.Type.BEFORE, Event.Type.RETURN, Event.Type.THROWS) + .build(); + return Lists.newArrayList(em); + } + + protected HikvProcesssor getInvocationProcessor() { + return new HikvProcesssor(getType()); + } + + @Override + public InvokeType getType() { + return InvokeType.HIKV; + } + + @Override + public String identity() { + return "hikv"; + } + + @Override + public boolean isEntrance() { + return false; + } +} diff --git a/repeater-plugins/hikv-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/hikv/HikvProcesssor.java b/repeater-plugins/hikv-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/hikv/HikvProcesssor.java new file mode 100644 index 00000000..c196e81c --- /dev/null +++ b/repeater-plugins/hikv-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/hikv/HikvProcesssor.java @@ -0,0 +1,30 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.hikv; + +import java.util.HashMap; + +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.api.DefaultInvocationProcessor; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.Identity; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; + +/** + *

+ * + * @author wangyeran + */ +class HikvProcesssor extends DefaultInvocationProcessor { + + HikvProcesssor(InvokeType type) { + super(type); + } + + @Override + public Identity assembleIdentity(BeforeEvent event) { + return new Identity(InvokeType.HIKV.name(), event.argumentArray[0].toString(), "Unknown", new HashMap(1)); + } + + @Override + public Object[] assembleRequest(BeforeEvent event) { + return new Object[]{event.argumentArray[0]}; + } +} diff --git a/repeater-plugins/pom.xml b/repeater-plugins/pom.xml index e7a0ecad..7d8f5c99 100644 --- a/repeater-plugins/pom.xml +++ b/repeater-plugins/pom.xml @@ -27,6 +27,7 @@ okhttp-plugin couchbase-plugin thrift-plugin + hikv-plugin From 2fc7ddea620f4935dedeea294647f7d03a689e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B9=9F=E7=84=B6=EF=BC=88Wang=20Yeran=EF=BC=89?= =?UTF-8?q?=28wangyeran=29?= Date: Fri, 25 Feb 2022 17:48:53 +0800 Subject: [PATCH 6/8] =?UTF-8?q?review=E6=A0=BC=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repeater/plugin/couchbase/CouchBaseProcessor.java | 2 +- .../sandbox/repeater/plugin/thrift/ThriftProcessor.java | 2 -- .../plugin/thrift/wrapper/ThriftWrapperTransModel.java | 9 +++------ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBaseProcessor.java b/repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBaseProcessor.java index 87258d73..43000b1c 100644 --- a/repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBaseProcessor.java +++ b/repeater-plugins/couchbase-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/couchbase/CouchBaseProcessor.java @@ -50,7 +50,7 @@ public Identity assembleIdentity(BeforeEvent event) { Object iterator = methodIterator.invoke(arrayList); event.argumentArray[0] = iterator; return new Identity(InvokeType.COUCH_BASE.name(), list.toString(), "Unknown", new HashMap(1)); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException | ClassNotFoundException e) { + } catch (Exception e) { log.error("couchbase assembleIdentity error {}, object:{}, event arg:{}, func:{}", e, event.target, event.argumentArray, event.javaClassName + event.javaMethodName); e.printStackTrace(); } diff --git a/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftProcessor.java b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftProcessor.java index 71e57a01..f2539007 100644 --- a/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftProcessor.java +++ b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/ThriftProcessor.java @@ -42,7 +42,6 @@ public Identity assembleIdentity(BeforeEvent event) { Map extra = new HashMap(); extra.put("Trotocol", wtm.getThriftProtocol()); return new Identity(InvokeType.THRIFT.name(), wtm.getThriftCode(), wtm.getThriftParameterTypes(), extra); - } @Override @@ -73,7 +72,6 @@ public Object assembleMockResponse(BeforeEvent event, Invocation invocation) { event.argumentArray[0] = invocation.getResponse(); invocation.getRequest()[0] = invocation.getResponse(); } - } return null; } else { diff --git a/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/wrapper/ThriftWrapperTransModel.java b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/wrapper/ThriftWrapperTransModel.java index cd7d3bb5..02dd7b9b 100644 --- a/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/wrapper/ThriftWrapperTransModel.java +++ b/repeater-plugins/thrift-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/thrift/wrapper/ThriftWrapperTransModel.java @@ -42,11 +42,10 @@ public static ThriftWrapperTransModel build(BeforeEvent event) { String thriftCode = ""; String thriftParameterTypes = ""; String thriftProtocol = ""; - Object thriftObj = event.target; if (thriftObj != null) { - Object inprotocol = MethodUtils.invokeMethod(thriftObj, "getInputProtocol"); - thriftProtocol = inprotocol.toString(); + Object inProtocol = MethodUtils.invokeMethod(thriftObj, "getInputProtocol"); + thriftProtocol = inProtocol.toString(); } if (event.argumentArray != null && argumentArray.length >= 2) { if (RECEIVE.equals(event.javaMethodName)) { @@ -61,12 +60,10 @@ public static ThriftWrapperTransModel build(BeforeEvent event) { thriftCode, thriftParameterTypes, thriftProtocol - ); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - log.error(" thrift Wrapper error {},object:{},event arg:{},func:{}", + log.error("thrift Wrapper error {}, object:{}, event arg:{}, func:{}", e, event.target, event.argumentArray, event.javaClassName + event.javaMethodName); - } return null; } From 808e8864f12ec1728fa00c7f66f363884b5cce3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B9=9F=E7=84=B6=EF=BC=88Wang=20Yeran=EF=BC=89?= =?UTF-8?q?=28wangyeran=29?= Date: Fri, 25 Feb 2022 17:52:10 +0800 Subject: [PATCH 7/8] =?UTF-8?q?review=E8=A1=A5=E5=85=85=E6=8F=90=E4=BA=A4H?= =?UTF-8?q?IKV=20InvokeType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java b/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java index cc01fd16..cc85ba92 100644 --- a/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java +++ b/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java @@ -41,6 +41,8 @@ public class InvokeType implements java.io.Serializable { public static InvokeType THRIFT = new InvokeType("thrift"); + public static InvokeType HIKV = new InvokeType("hikv"); + private String name; public InvokeType(String name) { From 1dbf623c81924f1c0b2e8ab273fdf7f1f9056ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B9=9F=E7=84=B6=EF=BC=88Wang=20Yeran=EF=BC=89?= =?UTF-8?q?=28wangyeran=29?= Date: Thu, 7 Apr 2022 10:32:24 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E6=8F=90=E4=BA=A4mongo=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repeater/plugin/domain/InvokeType.java | 2 + repeater-plugins/mongo-plugin/pom.xml | 44 ++++++ .../repeater/plugin/mongo/MongoListener.java | 94 +++++++++++++ .../repeater/plugin/mongo/MongoPlugin.java | 117 ++++++++++++++++ .../repeater/plugin/mongo/MongoProcessor.java | 67 +++++++++ .../mongo/wrapper/MongoWrapperTransModel.java | 128 ++++++++++++++++++ repeater-plugins/pom.xml | 1 + 7 files changed, 453 insertions(+) create mode 100644 repeater-plugins/mongo-plugin/pom.xml create mode 100644 repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoListener.java create mode 100644 repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoPlugin.java create mode 100644 repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoProcessor.java create mode 100644 repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/wrapper/MongoWrapperTransModel.java diff --git a/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java b/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java index cc85ba92..c3910791 100644 --- a/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java +++ b/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/InvokeType.java @@ -43,6 +43,8 @@ public class InvokeType implements java.io.Serializable { public static InvokeType HIKV = new InvokeType("hikv"); + public static InvokeType MONGO = new InvokeType("mongo"); + private String name; public InvokeType(String name) { diff --git a/repeater-plugins/mongo-plugin/pom.xml b/repeater-plugins/mongo-plugin/pom.xml new file mode 100644 index 00000000..a62f8059 --- /dev/null +++ b/repeater-plugins/mongo-plugin/pom.xml @@ -0,0 +1,44 @@ + + + + repeater-plugins + com.alibaba.jvm.sandbox + 1.0.0-SNAPSHOT + + 4.0.0 + + mongo-plugin + + ${project.name}-${project.version} + + + org.apache.maven.plugins + maven-assembly-plugin + + + + attached + + package + + + jar-with-dependencies + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 7 + 7 + + + + + + \ No newline at end of file diff --git a/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoListener.java b/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoListener.java new file mode 100644 index 00000000..5492f8c1 --- /dev/null +++ b/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoListener.java @@ -0,0 +1,94 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.mongo; + +import com.alibaba.jvm.sandbox.api.ProcessControlException; +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import com.alibaba.jvm.sandbox.api.event.ReturnEvent; +import com.alibaba.jvm.sandbox.api.event.ThrowsEvent; +import com.alibaba.jvm.sandbox.repeater.plugin.core.cache.RepeatCache; +import com.alibaba.jvm.sandbox.repeater.plugin.core.serialize.SerializeException; +import com.alibaba.jvm.sandbox.repeater.plugin.core.trace.SequenceGenerator; +import com.alibaba.jvm.sandbox.repeater.plugin.core.wrapper.SerializerWrapper; +import com.alibaba.jvm.sandbox.repeater.plugin.mongo.wrapper.MongoWrapperTransModel; +import com.alibaba.jvm.sandbox.repeater.plugin.api.InvocationListener; +import com.alibaba.jvm.sandbox.repeater.plugin.api.InvocationProcessor; +import com.alibaba.jvm.sandbox.repeater.plugin.core.bridge.ClassloaderBridge; +import com.alibaba.jvm.sandbox.repeater.plugin.core.cache.RecordCache; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.api.DefaultEventListener; +import com.alibaba.jvm.sandbox.repeater.plugin.core.trace.Tracer; +import com.alibaba.jvm.sandbox.repeater.plugin.core.util.LogUtil; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.*; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * {@link MongoListener} 继承 {@link DefaultEventListener}但是由于http有同步异步两种策略,因此需要重写一些方法 + *

+ * + * @author wangyeran + */ +public class MongoListener extends DefaultEventListener { + MongoListener(InvokeType invokeType, + boolean entrance, + InvocationListener listener, + InvocationProcessor processor) { + super(invokeType, entrance, listener, processor); + } + + @Override + protected void doBefore(BeforeEvent event) { + log.debug("inner the before"); + Invocation invocation = new Invocation(); + invocation.setStart(System.currentTimeMillis()); + invocation.setTraceId(Tracer.getTraceId()); + invocation.setIndex(entrance ? 0 : SequenceGenerator.generate(Tracer.getTraceId())); + invocation.setIdentity(processor.assembleIdentity(event)); + invocation.setEntrance(entrance); + invocation.setType(invokeType); + invocation.setProcessId(event.processId); + invocation.setInvokeId(event.invokeId); + invocation.setRequest(processor.assembleRequest(event)); + invocation.setResponse(processor.assembleResponse(event)); + invocation.setSerializeToken(ClassloaderBridge.instance().encode(event.javaClassLoader)); + try { + SerializerWrapper.inTimeSerialize(invocation); + } catch (SerializeException e) { + Tracer.getContext().setSampled(false); + log.error("Error occurred serialize", e); + } + RecordCache.cacheInvocation(event.invokeId, invocation); + } + + /** + * 处理return事件 + * + * @param event return事件 + */ + protected void doReturn(ReturnEvent event) { + Invocation invocation = RecordCache.getInvocation(event.invokeId); + if (invocation == null) { + log.info("no invocation"); + log.debug("no valid invocation found in return,type={},traceId={}", invokeType, Tracer.getTraceId()); + return; + } + log.info("response here 1"); + invocation.setResponse(processor.assembleResponse(event)); + invocation.setEnd(System.currentTimeMillis()); + listener.onInvocation(invocation); + } + + @Override + protected void doThrow(ThrowsEvent event) { + Invocation invocation = RecordCache.getInvocation(event.invokeId); + if (invocation == null) { + log.debug("no valid invocation found in throw,type={},traceId={}", invokeType, Tracer.getTraceId()); + return; + } + invocation.setThrowable(processor.assembleThrowable(event)); + invocation.setEnd(System.currentTimeMillis()); + listener.onInvocation(invocation); + } +} diff --git a/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoPlugin.java b/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoPlugin.java new file mode 100644 index 00000000..9fd2876d --- /dev/null +++ b/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoPlugin.java @@ -0,0 +1,117 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.mongo; + +import java.util.List; + +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.api.event.Event.Type; +import com.alibaba.jvm.sandbox.api.listener.EventListener; +import com.alibaba.jvm.sandbox.repeater.plugin.api.InvocationListener; +import com.alibaba.jvm.sandbox.repeater.plugin.api.InvocationProcessor; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.AbstractInvokePluginAdapter; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.api.DefaultEventListener; +import com.alibaba.jvm.sandbox.repeater.plugin.core.model.EnhanceModel; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; +import com.alibaba.jvm.sandbox.repeater.plugin.spi.InvokePlugin; + +import com.google.common.collect.Lists; +import org.kohsuke.MetaInfServices; + + + +/** + *

+ * + * @author wangyeran + */ +@MetaInfServices(InvokePlugin.class) +public class MongoPlugin extends AbstractInvokePluginAdapter { + + @Override + protected List getEnhanceModels() { + EnhanceModel.MethodPattern mp1 = EnhanceModel.MethodPattern.builder() + .methodName("find") + .parameterType(new String[]{"org.springframework.data.mongodb.core.query.Query","java.lang.Class","java.lang.String"}) + .build(); + EnhanceModel.MethodPattern mp2 = EnhanceModel.MethodPattern.builder() + .methodName("findOne") + .parameterType(new String[]{"org.springframework.data.mongodb.core.query.Query","java.lang.Class","java.lang.String"}) + .build(); + EnhanceModel.MethodPattern mp3 = EnhanceModel.MethodPattern.builder() + .methodName("findById") + .parameterType(new String[]{"java.lang.Object","java.lang.Class","java.lang.String"}) + .build(); + EnhanceModel.MethodPattern mp4 = EnhanceModel.MethodPattern.builder() + .methodName("findAll") + .parameterType(new String[]{"java.lang.Class","java.lang.String"}) + .build(); + EnhanceModel.MethodPattern mp5 = EnhanceModel.MethodPattern.builder() + .methodName("findAndModify") + .parameterType(new String[]{"org.springframework.data.mongodb.core.query.Query","org.springframework.data.mongodb.core.query.Update","org.springframework.data.mongodb.core.FindAndModifyOptions","java.lang.Class","java.lang.String"}) + .build(); + EnhanceModel.MethodPattern mp6 = EnhanceModel.MethodPattern.builder() + .methodName("count") + .parameterType(new String[]{"org.springframework.data.mongodb.core.query.Query","java.lang.Class","java.lang.String"}) + .build(); + EnhanceModel.MethodPattern mp7 = EnhanceModel.MethodPattern.builder() + .methodName("save") + .parameterType(new String[]{"java.lang.Object","java.lang.Class","java.lang.String"}) + .build(); + EnhanceModel.MethodPattern mp8 = EnhanceModel.MethodPattern.builder() + .methodName("insertAll") + .parameterType(new String[]{"java.util.Collection"}) + .build(); + EnhanceModel.MethodPattern mp9 = EnhanceModel.MethodPattern.builder() + .methodName("insert") + .parameterType(new String[]{"java.lang.Object","java.lang.String"}) + .build(); + EnhanceModel.MethodPattern mp10 = EnhanceModel.MethodPattern.builder() + .methodName("insert") + .parameterType(new String[]{"java.util.Collection","java.lang.String"}) + .build(); + EnhanceModel.MethodPattern mp11 = EnhanceModel.MethodPattern.builder() + .methodName("insert") + .parameterType(new String[]{"java.util.Collection","java.lang.Class"}) + .build(); + EnhanceModel.MethodPattern mp12 = EnhanceModel.MethodPattern.builder() + .methodName("remove") + .parameterType(new String[]{"org.springframework.data.mongodb.core.query.Query","java.lang.Class","java.lang.String"}) + .build(); + EnhanceModel.MethodPattern mp13 = EnhanceModel.MethodPattern.builder() + .methodName("aggregate") + .parameterType(new String[]{"org.springframework.data.mongodb.core.aggregation.Aggregation","java.lang.String","java.lang.Class","org.springframework.data.mongodb.core.aggregation.AggregationOperationContext"}) + .build(); + EnhanceModel.MethodPattern mp14 = EnhanceModel.MethodPattern.builder() + .methodName("doUpdate") + .parameterType(new String[]{"java.lang.String","org.springframework.data.mongodb.core.query.Query","org.springframework.data.mongodb.core.query.Update","org.springframework.data.mongodb.core.FindAndModifyOptions","java.lang.Class","boolean","boolean"}) + .build(); + EnhanceModel em = EnhanceModel.builder() + .classPattern("org.springframework.data.mongodb.core.MongoTemplate") + .methodPatterns(new EnhanceModel.MethodPattern[]{mp1,mp2,mp3,mp4,mp5,mp6,mp7,mp8,mp9,mp10,mp11,mp12,mp13,mp14}) + .watchTypes(Event.Type.BEFORE, Event.Type.RETURN, Event.Type.THROWS) + .build(); + return Lists.newArrayList(em); + } + + @Override + protected InvocationProcessor getInvocationProcessor() { + return new MongoProcessor(getType()); + } + + + + @Override + public InvokeType getType() { + return InvokeType.MONGO; + } + + @Override + public String identity() { + return "mongo"; + } + + @Override + public boolean isEntrance() { + return false; + } + +} diff --git a/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoProcessor.java b/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoProcessor.java new file mode 100644 index 00000000..cbc8c599 --- /dev/null +++ b/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/MongoProcessor.java @@ -0,0 +1,67 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.mongo; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.api.event.ReturnEvent; +import com.alibaba.jvm.sandbox.repeater.plugin.core.impl.api.DefaultInvocationProcessor; +import com.alibaba.jvm.sandbox.repeater.plugin.core.util.LogUtil; +import com.alibaba.jvm.sandbox.repeater.plugin.core.wrapper.SerializerWrapper; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.Identity; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.Invocation; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; +import com.alibaba.jvm.sandbox.repeater.plugin.mongo.wrapper.MongoWrapperTransModel; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.commons.lang3.reflect.MethodUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.lang.reflect.Constructor; +import java.util.HashMap; + +/** + *

+ * + * @author wangyeran + */ +class MongoProcessor extends DefaultInvocationProcessor { + protected static Logger log = LoggerFactory.getLogger(MongoProcessor.class); + + MongoProcessor(InvokeType type) { + super(type); + } + + @Override + public Identity assembleIdentity(BeforeEvent event) { + try { + MongoWrapperTransModel wtm = MongoWrapperTransModel.build(event); + return new Identity(InvokeType.MONGO.name(),wtm.getDbName() + "_" + wtm.gettableName(),wtm.getmethodName() + "_" + wtm.getparamString(), null); + } catch (Exception e) { + return new Identity(InvokeType.MONGO.name(), "Unknown", "Unknown", new HashMap(1)); + } + } + + @Override + public Object[] assembleRequest(BeforeEvent event) { + // args可能存在不可序序列化异常(例如使用tk.mybatis) + MongoWrapperTransModel wtm = MongoWrapperTransModel.build(event); + log.debug("the mongo request:{}, {}", wtm.getDbName() + "_" + wtm.gettableName(), wtm.getmethodName() + "_" + wtm.getparamString()); + return new Object[]{wtm}; + } + + @Override + public Object assembleResponse(Event event) { + if (event.type == Event.Type.RETURN) { + Object response = ((ReturnEvent) event).object; + try { + Object collection = MethodUtils.invokeMethod(response, "getCollection"); + log.debug("here in the record response:{}",collection); + }catch(Exception e){ + e.printStackTrace(); + } + return response; + } + return null; + } +} diff --git a/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/wrapper/MongoWrapperTransModel.java b/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/wrapper/MongoWrapperTransModel.java new file mode 100644 index 00000000..a34df2d1 --- /dev/null +++ b/repeater-plugins/mongo-plugin/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/mongo/wrapper/MongoWrapperTransModel.java @@ -0,0 +1,128 @@ +package com.alibaba.jvm.sandbox.repeater.plugin.mongo.wrapper; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import com.alibaba.jvm.sandbox.repeater.plugin.core.cache.RepeatCache; +import com.alibaba.jvm.sandbox.repeater.plugin.core.trace.Tracer; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.Identity; +import com.alibaba.jvm.sandbox.repeater.plugin.domain.InvokeType; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.commons.lang3.reflect.MethodUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * + * @author wangyeran + */ +public class MongoWrapperTransModel { + /** + * 数据库dbname + */ + private String dbName; + /** + * 表名称 + */ + private String tableName; + /** + * mongomethod + */ + private String methodName; + /** + * ParamString + */ + private String paramString; + + private MongoWrapperTransModel(String dbName,String tableName,String methodName,String paramString) { + this.dbName = dbName; + this.tableName = tableName; + this.methodName = methodName; + this.paramString = paramString; + } + + public static MongoWrapperTransModel build(BeforeEvent event) { + try { + String methodName = ((BeforeEvent) event).javaMethodName; + Object params = event.argumentArray[0]; + String paramString = JSONObject.toJSONString(params); + String tableName = ""; + String dbName = ""; + try { + Object mongotemplate = event.target; + + Field fieldtable = FieldUtils.getDeclaredField(mongotemplate.getClass(), "mongoDbFactory", true); + if (fieldtable != null) { + Object dbfactory = fieldtable.get(mongotemplate); + Object dbs = MethodUtils.invokeMethod(dbfactory, "getDb"); + if (dbs != null) { + dbName = MethodUtils.invokeMethod(dbs, "getName").toString(); + } + } + } catch(Exception e) { + e.printStackTrace(); + } + switch(methodName) { + case "find": tableName = event.argumentArray[2].toString();break; + case "findOne": tableName = event.argumentArray[2].toString();break; + case "findById": tableName = event.argumentArray[2].toString();break; + case "findAll": tableName = event.argumentArray[1].toString();break; + case "findAndModify": tableName = event.argumentArray[4].toString();break; + case "count": tableName = event.argumentArray[2].toString();break; + case "save": tableName = event.argumentArray[2].toString();break; + case "insertAll": tableName = event.argumentArray[0].getClass().getName();break; + case "insert": tableName = event.argumentArray[2].toString();break; + case "remove": tableName = event.argumentArray[2].toString();break; + case "aggregate": tableName = event.argumentArray[1].toString();break; + case "doUpdate": tableName = event.argumentArray[0].toString();break; + default: break; + } + + switch(dbName){ + case "ugc_audit_production": dbName = "audit";break; + case "ugc_audit": dbName = "audit";break; + case "audit_shortvideo": dbName = "audit_shortvideo_test";break; + case "ai_prod": dbName = "ai_test";break; + default:break; + } + + return new MongoWrapperTransModel( + dbName, + tableName, + methodName, + paramString + ); + + + }catch(Exception e){ + e.printStackTrace(); + } + return null; + } + public String getDbName() { + return dbName; + } + + public String gettableName() { + return tableName; + } + + public String getmethodName() { + return methodName; + } + + public String getparamString() { + return paramString; + } + +} diff --git a/repeater-plugins/pom.xml b/repeater-plugins/pom.xml index 7d8f5c99..a1560f41 100644 --- a/repeater-plugins/pom.xml +++ b/repeater-plugins/pom.xml @@ -28,6 +28,7 @@ couchbase-plugin thrift-plugin hikv-plugin + mongo-plugin