Repository: huaweicloud/sermant
Issue: 【bug】fix the registry plugin bugs

### What happened?

can not work

### How can we reproduce it (as minimally and precisely as possible)?

no

### Anything else we need to know?

_No response_

### Sermant version

<details>
0.6.0
</details>


### OS version

<details>

```console
# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here

# On Windows:
C:\\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here
```
</details>


Changed files:
sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/test/java/com/huawei/discovery/interceptors/OkHttp3ClientInterceptorTest.java
sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/utils/RequestInterceptorUtils.java
sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/declarers/OkHttp3ClientDeclarer.java
sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/test/java/com/huawei/discovery/interceptors/OkHttpClientInterceptorTest.java
sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/httpclient/HttpClient4xInterceptor.java
sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/OkHttpClientInterceptor.java
sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/declarers/OkHttpClientDeclarer.java
sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/OkHttp3ClientInterceptor.java

diff --git a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/declarers/OkHttp3ClientDeclarer.java b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/declarers/OkHttp3ClientDeclarer.java
index 2c06e3a6..d4444be9 100644
--- a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/declarers/OkHttp3ClientDeclarer.java
+++ b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/declarers/OkHttp3ClientDeclarer.java
@@ -50,7 +50,8 @@ public class OkHttp3ClientDeclarer extends AbstractPluginDeclarer {
     @Override
     public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
         return new InterceptDeclarer[] {
-                InterceptDeclarer.build(MethodMatcher.nameEquals("getResponseWithInterceptorChain"), INTERCEPT_CLASS)
+                InterceptDeclarer.build(MethodMatcher.nameContains("execute", "getResponseWithInterceptorChain"),
+                        INTERCEPT_CLASS)
         };
     }
 }
diff --git a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/declarers/OkHttpClientDeclarer.java b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/declarers/OkHttpClientDeclarer.java
index c3d96662..f80a04e4 100644
--- a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/declarers/OkHttpClientDeclarer.java
+++ b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/declarers/OkHttpClientDeclarer.java
@@ -50,7 +50,8 @@ public class OkHttpClientDeclarer extends AbstractPluginDeclarer {
     @Override
     public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
         return new InterceptDeclarer[] {
-                InterceptDeclarer.build(MethodMatcher.nameEquals("getResponseWithInterceptorChain"), INTERCEPT_CLASS)
+                InterceptDeclarer.build(MethodMatcher.nameContains("execute", "getResponseWithInterceptorChain"),
+                        INTERCEPT_CLASS)
         };
     }
 }
diff --git a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/OkHttp3ClientInterceptor.java b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/OkHttp3ClientInterceptor.java
index 8fb1c39c..ffc674be 100644
--- a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/OkHttp3ClientInterceptor.java
+++ b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/OkHttp3ClientInterceptor.java
@@ -28,7 +28,7 @@ import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
 import com.huaweicloud.sermant.core.plugin.service.PluginServiceManager;
 import com.huaweicloud.sermant.core.utils.ReflectUtils;
 
-import okhttp3.HttpUrl;
+import okhttp3.OkHttpClient;
 import okhttp3.Protocol;
 import okhttp3.Request;
 import okhttp3.Response;
@@ -36,11 +36,14 @@ import okhttp3.Response.Builder;
 
 import org.apache.http.HttpStatus;
 
+import java.io.IOException;
+import java.lang.reflect.Method;
 import java.net.URI;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Function;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
@@ -71,14 +74,30 @@ public class OkHttp3ClientInterceptor extends MarkInterceptor {
         RequestInterceptorUtils.printRequestLog("OkHttp3", hostAndPath);
         AtomicReference<Request> rebuildRequest = new AtomicReference<>();
         rebuildRequest.set(request);
-        invokerService.invoke(
+        final Optional<Object> invoke = invokerService.invoke(
                 buildInvokerFunc(uri, hostAndPath, request, rebuildRequest, context),
                 buildExFunc(rebuildRequest),
-                hostAndPath.get(HttpConstants.HTTP_URI_HOST))
-                .ifPresent(context::skip);
+                hostAndPath.get(HttpConstants.HTTP_URI_HOST));
+        if (!invoke.isPresent() && isNoneReturnMethod(context.getMethod())) {
+            context.skip(null);
+        }
+        invoke.ifPresent(o -> setResultOrThrow(context, o, uri.getPath()));
         return context;
     }
 
+    private void setResultOrThrow(ExecuteContext context, Object result, String url) {
+        if (result instanceof IOException) {
+            LOGGER.log(Level.SEVERE, "Ok http client request error, uri is " + url, (Exception) result);
+            context.setThrowableOut((Exception) result);
+            return;
+        }
+        context.skip(result);
+    }
+
+    private boolean isNoneReturnMethod(Method method) {
+        return method.getReturnType() == void.class || method.getReturnType() == Void.class;
+    }
+
     private Optional<Request> getRequest(ExecuteContext context) {
         final Optional<Object> originalRequest = ReflectUtils.getFieldValue(context.getObject(), FIELD_NAME);
         if (originalRequest.isPresent() && originalRequest.get() instanceof Request) {
@@ -97,37 +116,43 @@ public class OkHttp3ClientInterceptor extends MarkInterceptor {
             final String method = request.method();
             Request newRequest = covertRequest(uri, hostAndPath, request, method, invokerContext.getServiceInstance());
             rebuildRequest.set(newRequest);
-            try {
-                context.setRawMemberFieldValue(FIELD_NAME, newRequest);
-            } catch (NoSuchFieldException e) {
-                LOGGER.warning("setRawMemberFieldValue originalRequest failed");
-                return context;
-            } catch (IllegalAccessException e) {
-                LOGGER.warning("setRawMemberFieldValue originalRequest failed");
-                return context;
-            }
-            return RequestInterceptorUtils.buildFunc(context, invokerContext).get();
+            final Object target = copyNewCall(context, newRequest);
+            return RequestInterceptorUtils.buildFunc(target, context.getMethod(), context.getArguments(),
+                    invokerContext).get();
         };
     }
 
+    private Object copyNewCall(ExecuteContext executeContext, Request newRequest) {
+        final Optional<Object> client = ReflectUtils.getFieldValue(executeContext.getObject(), "client");
+        if (!client.isPresent()) {
+            return executeContext.getObject();
+        }
+        final OkHttpClient okHttpClient = (OkHttpClient) client.get();
+        return okHttpClient.newCall(newRequest);
+    }
+
     private Request covertRequest(URI uri, Map<String, String> hostAndPath, Request request, String method,
             ServiceInstance serviceInstance) {
         String url = RequestInterceptorUtils.buildUrlWithIp(uri, serviceInstance,
                 hostAndPath.get(HttpConstants.HTTP_URI_PATH), method);
-        HttpUrl newUrl = HttpUrl.parse(url);
-        return request
-                .newBuilder()
-                .url(newUrl)
+        return new Request.Builder()
+                .headers(request.headers())
+                .method(request.method(), request.body())
+                .url(url)
+                .tag(request.tag())
                 .build();
     }
 
     /**
      * 构建okHttp3响应
      *
-     * @param ex
+     * @param ex 指定异常
      * @return 响应
      */
-    private Response buildErrorResponse(Exception ex, Request request) {
+    private Object buildErrorResponse(Exception ex, Request request) {
+        if (ex instanceof IOException) {
+            return ex;
+        }
         Builder builder = new Builder();
         builder.code(HttpStatus.SC_INTERNAL_SERVER_ERROR);
         builder.message(ex.getMessage());
diff --git a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/OkHttpClientInterceptor.java b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/OkHttpClientInterceptor.java
index 8266bcf5..1485a5fd 100644
--- a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/OkHttpClientInterceptor.java
+++ b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/OkHttpClientInterceptor.java
@@ -29,6 +29,7 @@ import com.huaweicloud.sermant.core.plugin.service.PluginServiceManager;
 import com.huaweicloud.sermant.core.utils.ReflectUtils;
 
 import com.squareup.okhttp.HttpUrl;
+import com.squareup.okhttp.OkHttpClient;
 import com.squareup.okhttp.Protocol;
 import com.squareup.okhttp.Request;
 import com.squareup.okhttp.Response;
@@ -36,11 +37,14 @@ import com.squareup.okhttp.Response.Builder;
 
 import org.apache.http.HttpStatus;
 
+import java.io.IOException;
+import java.lang.reflect.Method;
 import java.net.URI;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Function;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
@@ -50,7 +54,6 @@ import java.util.logging.Logger;
  * @since 2022-09-14
  */
 public class OkHttpClientInterceptor extends MarkInterceptor {
-
     private static final Logger LOGGER = LoggerFactory.getLogger();
 
     private static final String FIELD_NAME = "originalRequest";
@@ -72,14 +75,30 @@ public class OkHttpClientInterceptor extends MarkInterceptor {
         RequestInterceptorUtils.printRequestLog("OkHttp", hostAndPath);
         AtomicReference<Request> rebuildRequest = new AtomicReference<>();
         rebuildRequest.set(request);
-        invokerService.invoke(
+        final Optional<Object> invoke = invokerService.invoke(
                 buildInvokerFunc(uri, hostAndPath, request, rebuildRequest, context),
                 buildExFunc(rebuildRequest),
-                hostAndPath.get(HttpConstants.HTTP_URI_HOST))
-                .ifPresent(context::skip);
+                hostAndPath.get(HttpConstants.HTTP_URI_HOST));
+        if (!invoke.isPresent() && isNoneReturnMethod(context.getMethod())) {
+            context.skip(null);
+        }
+        invoke.ifPresent(o -> setResultOrThrow(context, o, uri.getPath()));
         return context;
     }
 
+    private void setResultOrThrow(ExecuteContext context, Object result, String url) {
+        if (result instanceof IOException) {
+            LOGGER.log(Level.SEVERE, "Ok http client request error, uri is " + url, (Exception) result);
+            context.setThrowableOut((Exception) result);
+            return;
+        }
+        context.skip(result);
+    }
+
+    private boolean isNoneReturnMethod(Method method) {
+        return method.getReturnType() == void.class || method.getReturnType() == Void.class;
+    }
+
     private Optional<Request> getRequest(ExecuteContext context) {
         final Optional<Object> originalRequest = ReflectUtils.getFieldValue(context.getObject(), FIELD_NAME);
         if (originalRequest.isPresent() && originalRequest.get() instanceof Request) {
@@ -98,19 +117,21 @@ public class OkHttpClientInterceptor extends MarkInterceptor {
             final String method = request.method();
             Request newRequest = covertRequest(uri, hostAndPath, request, method, invokerContext.getServiceInstance());
             rebuildRequest.set(newRequest);
-            try {
-                context.setRawMemberFieldValue(FIELD_NAME, newRequest);
-            } catch (NoSuchFieldException e) {
-                LOGGER.warning("setRawMemberFieldValue originalRequest failed");
-                return context;
-            } catch (IllegalAccessException e) {
-                LOGGER.warning("setRawMemberFieldValue originalRequest failed");
-                return context;
-            }
-            return RequestInterceptorUtils.buildFunc(context, invokerContext).get();
+            final Object newCall = copyNewCall(context, newRequest);
+            return RequestInterceptorUtils.buildFunc(newCall, context.getMethod(), context.getArguments(),
+                    invokerContext).get();
         };
     }
 
+    private Object copyNewCall(ExecuteContext executeContext, Request newRequest) {
+        final Optional<Object> client = ReflectUtils.getFieldValue(executeContext.getObject(), "client");
+        if (!client.isPresent()) {
+            return executeContext.getObject();
+        }
+        final OkHttpClient okHttpClient = (OkHttpClient) client.get();
+        return okHttpClient.newCall(newRequest);
+    }
+
     private Request covertRequest(URI uri, Map<String, String> hostAndPath, Request request, String method,
             ServiceInstance serviceInstance) {
         String url = RequestInterceptorUtils.buildUrlWithIp(uri, serviceInstance,
@@ -125,10 +146,13 @@ public class OkHttpClientInterceptor extends MarkInterceptor {
     /**
      * 构建okHttp响应
      *
-     * @param ex
+     * @param ex 指定异常
      * @return 响应
      */
-    private Response buildErrorResponse(Exception ex, Request request) {
+    private Object buildErrorResponse(Exception ex, Request request) {
+        if (ex instanceof IOException) {
+            return ex;
+        }
         Builder builder = new Builder();
         builder.code(HttpStatus.SC_INTERNAL_SERVER_ERROR);
         builder.message(ex.getMessage());
diff --git a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/httpclient/HttpClient4xInterceptor.java b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/httpclient/HttpClient4xInterceptor.java
index ed6ef173..b9fe9751 100644
--- a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/httpclient/HttpClient4xInterceptor.java
+++ b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/interceptors/httpclient/HttpClient4xInterceptor.java
@@ -36,12 +36,14 @@ import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.utils.URIUtils;
 
+import java.io.IOException;
 import java.net.URI;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Function;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
@@ -78,10 +80,19 @@ public class HttpClient4xInterceptor extends MarkInterceptor {
                 buildInvokerFunc(hostAndPath, uri, httpRequest, context),
                 buildExFunc(httpRequest),
                 hostAndPath.get(HttpConstants.HTTP_URI_HOST))
-                .ifPresent(context::skip);
+                .ifPresent(result -> this.setResultOrThrow(context, result, uri.getPath()));
         return context;
     }
 
+    private void setResultOrThrow(ExecuteContext context, Object result, String url) {
+        if (result instanceof IOException) {
+            LOGGER.log(Level.SEVERE, "Http client request failed, uri is " + url, (Exception) result);
+            context.setThrowableOut((Exception) result);
+            return;
+        }
+        context.skip(result);
+    }
+
     private Function<InvokerContext, Object> buildInvokerFunc(Map<String, String> hostAndPath, URI uri,
             HttpRequest httpRequest, ExecuteContext context) {
         final String method = httpRequest.getRequestLine().getMethod();
@@ -110,6 +121,9 @@ public class HttpClient4xInterceptor extends MarkInterceptor {
     private Function<Exception, Object> buildExFunc(HttpRequest httpRequest) {
         final ClassLoader appClassloader = Thread.currentThread().getContextClassLoader();
         return ex -> {
+            if (ex instanceof IOException) {
+                return ex;
+            }
             final ClassLoader pluginClassloader = Thread.currentThread().getContextClassLoader();
             Thread.currentThread().setContextClassLoader(appClassloader);
             try {
diff --git a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/utils/RequestInterceptorUtils.java b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/utils/RequestInterceptorUtils.java
index 63471709..36e11129 100644
--- a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/utils/RequestInterceptorUtils.java
+++ b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/main/java/com/huawei/discovery/utils/RequestInterceptorUtils.java
@@ -133,21 +133,34 @@ public class RequestInterceptorUtils {
      * @return 调用器
      */
     public static Supplier<Object> buildFunc(ExecuteContext context, InvokerContext invokerContext) {
+        return buildFunc(context.getObject(), context.getMethod(), context.getArguments(), invokerContext);
+    }
+
+    /**
+     * 构建invoke回调方法函数
+     *
+     * @param target 目标
+     * @param arguments 参数
+     * @param method 方法
+     * @param invokerContext 调用上下文
+     * @return 调用器
+     */
+    public static Supplier<Object> buildFunc(Object target, Method method, Object[] arguments,
+            InvokerContext invokerContext) {
         return () -> {
             try {
-                final Method method = context.getMethod();
                 AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                     method.setAccessible(true);
                     return method;
                 });
-                return method.invoke(context.getObject(), context.getArguments());
+                return method.invoke(target, arguments);
             } catch (IllegalAccessException e) {
                 LOGGER.log(Level.SEVERE, String.format(Locale.ENGLISH, "Can not invoke method [%s]",
-                    context.getMethod().getName()), e);
+                        method.getName()), e);
             } catch (InvocationTargetException e) {
                 invokerContext.setEx(e.getTargetException());
                 LOGGER.log(Level.FINE, String.format(Locale.ENGLISH, "invoke method [%s] failed",
-                    context.getMethod().getName()), e);
+                        method.getName()), e.getTargetException());
             }
             return Optional.empty();
         };
diff --git a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/test/java/com/huawei/discovery/interceptors/OkHttp3ClientInterceptorTest.java b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/test/java/com/huawei/discovery/interceptors/OkHttp3ClientInterceptorTest.java
index d436dde0..2e4edea0 100644
--- a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/test/java/com/huawei/discovery/interceptors/OkHttp3ClientInterceptorTest.java
+++ b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/test/java/com/huawei/discovery/interceptors/OkHttp3ClientInterceptorTest.java
@@ -104,7 +104,9 @@ public class OkHttp3ClientInterceptorTest extends BaseTest {
     public void testRestTemplateInterceptor() throws Exception {
         OkHttpClient client = new OkHttpClient();
         Request request = createRequest(url);
-        ExecuteContext context = ExecuteContext.forMemberMethod(client.newCall(request), null, arguments, null, null);
+        ExecuteContext context = ExecuteContext.forMemberMethod(client.newCall(request),
+                String.class.getDeclaredMethod("trim"), arguments, null,
+                null);
         discoveryPluginConfig.setRealmName(realmName);
         initStrategy(PlugEffectWhiteBlackConstants.STRATEGY_ALL, "zookeeper-provider-demo");
         interceptor.doBefore(context);
diff --git a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/test/java/com/huawei/discovery/interceptors/OkHttpClientInterceptorTest.java b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/test/java/com/huawei/discovery/interceptors/OkHttpClientInterceptorTest.java
index a14b928b..6c1bf20c 100644
--- a/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/test/java/com/huawei/discovery/interceptors/OkHttpClientInterceptorTest.java
+++ b/sermant-plugins/sermant-springboot-registry/springboot-registry-plugin/src/test/java/com/huawei/discovery/interceptors/OkHttpClientInterceptorTest.java
@@ -99,7 +99,9 @@ public class OkHttpClientInterceptorTest extends BaseTest {
     public void testRestTemplateInterceptor() throws Exception {
         OkHttpClient client = new OkHttpClient();
         Request request = createRequest(url);
-        ExecuteContext context = ExecuteContext.forMemberMethod(client.newCall(request), null, arguments, null, null);
+        ExecuteContext context = ExecuteContext.forMemberMethod(client.newCall(request),
+                String.class.getDeclaredMethod("trim"), arguments, null,
+                null);
         discoveryPluginConfig.setRealmName(realmName);
         initStrategy(PlugEffectWhiteBlackConstants.STRATEGY_ALL, "zookeeper-provider-demo");
         interceptor.doBefore(context);